<commit_before>/*                          _       _
 *__      _____  __ ___   ___  __ _| |_ ___
 *\ \ /\ / / _ \/ _` \ \ / / |/ _` | __/ _ \
 * \ V  V /  __/ (_| |\ V /| | (_| | ||  __/
 *  \_/\_/ \___|\__,_| \_/ |_|\__,_|\__\___|
 *
 * Copyright © 2016 Weaviate. All rights reserved.
 * LICENSE: https://github.com/weaviate/weaviate/blob/master/LICENSE
 * AUTHOR: Bob van Luijt (bob@weaviate.com)
 * See www.weaviate.com for details
 * Contact: @weaviate_iot / yourfriends@weaviate.com
 */
package main

import (
	"bytes"
	"encoding/json"
	"flag"
	"io"
	"io/ioutil"
	"net/http"
	"testing"
	"time"

	// "github.com/weaviate/weaviate/connectors"
	// "github.com/weaviate/weaviate/connectors/datastore"
	"github.com/weaviate/weaviate/models"
)

/*
 * Request function
 */
func doRequest(endpoint string, method string, accept string, body io.Reader, apiKey string) *http.Response {
	tr := &http.Transport{
		MaxIdleConns:       10,
		IdleConnTimeout:    30 * time.Second,
		DisableCompression: true,
	}
	client := &http.Client{Transport: tr}

	req, _ := http.NewRequest(method, "http://localhost:8080/weaviate/v1-alpha"+endpoint, body)
	req.Header.Set("Content-Type", "application/json")
	req.Header.Set("Accept", accept)

	if apiKey != "" {
		req.Header.Set("X-API-KEY", apiKey)
	}

	response, err := client.Do(req)

	if err != nil {
		panic(err)
	}

	return response

}

func getResponseBody(response *http.Response) []byte {
	defer response.Body.Close()
	body, _ := ioutil.ReadAll(response.Body)

	return body
}

var apiKeyCmdLine string
var locationId string

func init() {
	flag.StringVar(&apiKeyCmdLine, "api-key", "", "API-KEY as used as haeder in the tests.")
	flag.Parse()

	// testUserObject := &dbconnector.DatabaseUsersObjectsObject{
	// 	Delete:   true,
	// 	Email:    "test@ing.nl",
	// 	IpOrigin: "*",
	// 	Read:     true,
	// 	Write:    true,
	// }

	// jsonValue, _ := json.Marshal(testUserObject)

	// testUser := &dbconnector.DatabaseUsersObject{
	// 	Uuid:         "sdf",
	// 	KeyToken:     "TESTTEST",
	// 	KeyExpiresMs: 0,
	// 	Object:       string(jsonValue),
	// 	Parent:       "",
	// }

	// databaseConnector := &datastore.Datastore{}
	// databaseConnector.Connect()

	// UUID, _ := databaseConnector.AddUser(*testUser)

	// print(UUID)
}

/******************
 * START TESTS
 ******************/

// weaviate.location.insert
func Test__weaviate_location_insert_JSON(t *testing.T) {
	jsonStr := bytes.NewBuffer([]byte(`{"address_components":[{"long_name":"TEST","short_name":"string","types":["UNDEFINED"]}],"formatted_address":"string","geometry":{"location":{},"location_type":"string","viewport":{"northeast":{},"southwest":{}}},"place_id":"string","types":["UNDEFINED"]} `))
	response := doRequest("/locations", "POST", "application/json", jsonStr, apiKeyCmdLine)

	if response.StatusCode != http.StatusAccepted {
		t.Errorf("Expected response code %d. Got %d\n", http.StatusAccepted, response.StatusCode)
	}

	body := getResponseBody(response)

	respObject := &models.Location{}
	json.Unmarshal(body, respObject)

	locationId = respObject.ID

	expLength := 36
	if len(locationId) != expLength {
		t.Errorf("Expected length of ID %d. Got %d\n", expLength, len(locationId))
	}
}

// weaviate.location.list
func Test__weaviate_location_list_JSON(t *testing.T) {
	response := doRequest("/locations", "GET", "application/json", nil, apiKeyCmdLine)
	if response.StatusCode != http.StatusOK {
		t.Errorf("Expected response code %d. Got %d\n", http.StatusOK, response.StatusCode)
	}

	body := getResponseBody(response)

	respObject := &models.LocationsListResponse{}
	json.Unmarshal(body, respObject)

	if respObject.Locations[0].ID != locationId {
		t.Errorf("Expected ID %s. Got %s\n", locationId, respObject.Locations[0].ID)
	}
}

// weaviate.location.get
func Test__weaviate_location_get_JSON(t *testing.T) {
	response := doRequest("/locations/"+locationId, "GET", "application/json", nil, apiKeyCmdLine)
	if response.StatusCode != http.StatusOK {
		t.Errorf("Expected response code %d. Got %d\n", http.StatusOK, response.StatusCode)
	}

	body := getResponseBody(response)

	respObject := &models.Location{}
	json.Unmarshal(body, respObject)

	if respObject.ID != locationId {
		t.Errorf("Expected ID %s. Got %s\n", locationId, respObject.ID)
	}

	responseNotFound := doRequest("/locations/11111111-1111-1111-1111-111111111111", "GET", "application/json", nil, apiKeyCmdLine)
	if responseNotFound.StatusCode != http.StatusNotFound {
		t.Errorf("Expected response code %d. Got %d\n", http.StatusNotFound, responseNotFound.StatusCode)
	}
}

// weaviate.location.update
// weaviate.location.patch
// weaviate.location.delete

// weaviate.adapters.list
func Test__weaviate_adapters_list_JSON(t *testing.T) {
	result := doRequest("/adapters", "GET", "application/json", nil, apiKeyCmdLine)
	if result.StatusCode != http.StatusNotImplemented {
		t.Errorf("Expected response code %d. Got %d\n", http.StatusNotImplemented, result.StatusCode)
	}
}

func Test__weaviate_adapters_list_XML(t *testing.T) {
	result := doRequest("/adapters", "GET", "application/xml", nil, apiKeyCmdLine)
	if result.StatusCode != http.StatusNotImplemented {
		t.Errorf("Expected response code %d. Got %d\n", http.StatusNotImplemented, result.StatusCode)
	}
}

// weaviate.adapters.insert
func Test__weaviate_adapters_insert_JSON(t *testing.T) {
	jsonStr := bytes.NewBuffer([]byte(`{}`))
	result := doRequest("/adapters", "POST", "application/json", jsonStr, apiKeyCmdLine)
	if result.StatusCode != http.StatusNotImplemented {
		t.Errorf("Expected response code %d. Got %d\n", http.StatusNotImplemented, result.StatusCode)
	}
}

func Test__weaviate_adapters_insert_XML(t *testing.T) {
	jsonStr := bytes.NewBuffer([]byte(`{}`))
	result := doRequest("/adapters", "POST", "application/xml", jsonStr, apiKeyCmdLine)
	if result.StatusCode != http.StatusNotImplemented {
		t.Errorf("Expected response code %d. Got %d\n", http.StatusNotImplemented, result.StatusCode)
	}
}

// weaviate.adapters.delete
func Test__weaviate_adapters_delete_JSON(t *testing.T) {
	result := doRequest("/adapters/1", "DELETE", "application/json", nil, apiKeyCmdLine)
	if result.StatusCode != http.StatusNotImplemented {
		t.Errorf("Expected response code %d. Got %d\n", http.StatusNotImplemented, result.StatusCode)
	}
}

func Test__weaviate_adapters_delete_XML(t *testing.T) {
	result := doRequest("/adapters/1", "DELETE", "application/xml", nil, apiKeyCmdLine)
	if result.StatusCode != http.StatusNotImplemented {
		t.Errorf("Expected response code %d. Got %d\n", http.StatusNotImplemented, result.StatusCode)
	}
}

// weaviate.adapters.get
func Test__weaviate_adapters_get_JSON(t *testing.T) {
	result := doRequest("/adapters/1", "GET", "application/json", nil, apiKeyCmdLine)
	if result.StatusCode != http.StatusNotImplemented {
		t.Errorf("Expected response code %d. Got %d\n", http.StatusNotImplemented, result.StatusCode)
	}
}

func Test__weaviate_adapters_get_XML(t *testing.T) {
	result := doRequest("/adapters/1", "GET", "application/xml", nil, apiKeyCmdLine)
	if result.StatusCode != http.StatusNotImplemented {
		t.Errorf("Expected response code %d. Got %d\n", http.StatusNotImplemented, result.StatusCode)
	}
}

// weaviate.adapters.update
func Test__weaviate_adapters_update_JSON(t *testing.T) {
	jsonStr := bytes.NewBuffer([]byte(`{ "activateUrl": "string", "activated": true, "deactivateUrl": "string", "displayName": "string", "iconUrl": "string", "id": "string", "manageUrl": "string" }`))
	result := doRequest("/adapters/1", "PUT", "application/json", jsonStr, apiKeyCmdLine)
	if result.StatusCode != http.StatusNotImplemented {
		t.Errorf("Expected response code %d. Got %d\n", http.StatusNotImplemented, result.StatusCode)
	}
}

func Test__weaviate_adapters_update_XML(t *testing.T) {
	jsonStr := bytes.NewBuffer([]byte(`{"activateUrl": "string"}`))
	result := doRequest("/adapters/1", "PUT", "application/xml", jsonStr, apiKeyCmdLine)
	if result.StatusCode != http.StatusNotImplemented {
		t.Errorf("Expected response code %d. Got %d\n", http.StatusNotImplemented, result.StatusCode)
	}
}

// weaviate.adapters.patch
func Test__weaviate_adapters_patch_JSON(t *testing.T) {
	jsonStr := bytes.NewBuffer([]byte(`{}`))
	result := doRequest("/adapters/1", "PATCH", "application/json", jsonStr, apiKeyCmdLine)
	if result.StatusCode != http.StatusNotImplemented {
		t.Errorf("Expected response code %d. Got %d\n", http.StatusNotImplemented, result.StatusCode)
	}
}

func Test__weaviate_adapters_patch_XML(t *testing.T) {
	jsonStr := bytes.NewBuffer([]byte(`{}`))
	result := doRequest("/adapters/1", "PATCH", "application/xml", jsonStr, apiKeyCmdLine)
	if result.StatusCode != http.StatusNotImplemented {
		t.Errorf("Expected response code %d. Got %d\n", http.StatusNotImplemented, result.StatusCode)
	}
}
<commit_msg>gh-25: Add all tests for locations.<commit_after>/*                          _       _
 *__      _____  __ ___   ___  __ _| |_ ___
 *\ \ /\ / / _ \/ _` \ \ / / |/ _` | __/ _ \
 * \ V  V /  __/ (_| |\ V /| | (_| | ||  __/
 *  \_/\_/ \___|\__,_| \_/ |_|\__,_|\__\___|
 *
 * Copyright © 2016 Weaviate. All rights reserved.
 * LICENSE: https://github.com/weaviate/weaviate/blob/master/LICENSE
 * AUTHOR: Bob van Luijt (bob@weaviate.com)
 * See www.weaviate.com for details
 * Contact: @weaviate_iot / yourfriends@weaviate.com
 */
package main

import (
	"bytes"
	"encoding/json"
	"flag"
	"io"
	"io/ioutil"
	"net/http"
	"testing"
	"time"

	// "github.com/weaviate/weaviate/connectors"
	// "github.com/weaviate/weaviate/connectors/datastore"
	"github.com/weaviate/weaviate/models"
)

/*
 * Request function
 */
func doRequest(endpoint string, method string, accept string, body io.Reader, apiKey string) *http.Response {
	tr := &http.Transport{
		MaxIdleConns:       10,
		IdleConnTimeout:    30 * time.Second,
		DisableCompression: true,
	}
	client := &http.Client{Transport: tr}

	req, _ := http.NewRequest(method, "http://localhost:8080/weaviate/v1-alpha"+endpoint, body)
	req.Header.Set("Content-Type", "application/json")
	req.Header.Set("Accept", accept)

	if apiKey != "" {
		req.Header.Set("X-API-KEY", apiKey)
	}

	response, err := client.Do(req)

	if err != nil {
		panic(err)
	}

	return response

}

func getResponseBody(response *http.Response) []byte {
	defer response.Body.Close()
	body, _ := ioutil.ReadAll(response.Body)

	return body
}

var apiKeyCmdLine string
var locationId string

func init() {
	flag.StringVar(&apiKeyCmdLine, "api-key", "", "API-KEY as used as haeder in the tests.")
	flag.Parse()
}

/******************
 * START TESTS
 ******************/

// weaviate.location.insert
func Test__weaviate_location_insert_JSON(t *testing.T) {
	// Create insert request
	jsonStr := bytes.NewBuffer([]byte(`{"address_components":[{"long_name":"TEST","short_name":"string","types":["UNDEFINED"]}],"formatted_address":"string","geometry":{"location":{},"location_type":"string","viewport":{"northeast":{},"southwest":{}}},"place_id":"string","types":["UNDEFINED"]} `))
	response := doRequest("/locations", "POST", "application/json", jsonStr, apiKeyCmdLine)

	// Check status code of insert
	if response.StatusCode != http.StatusAccepted {
		t.Errorf("Expected response code %d. Got %d\n", http.StatusAccepted, response.StatusCode)
	}

	body := getResponseBody(response)

	respObject := &models.Location{}
	json.Unmarshal(body, respObject)

	// Check whether generated UUID is added
	locationId = respObject.ID

	expLength := 36
	if len(locationId) != expLength {
		t.Errorf("Expected length of ID %d. Got %d\n", expLength, len(locationId))
	}
}

// weaviate.location.list
func Test__weaviate_location_list_JSON(t *testing.T) {
	// Create list request
	response := doRequest("/locations", "GET", "application/json", nil, apiKeyCmdLine)

	// Check status code of list
	if response.StatusCode != http.StatusOK {
		t.Errorf("Expected response code %d. Got %d\n", http.StatusOK, response.StatusCode)
	}

	body := getResponseBody(response)

	respObject := &models.LocationsListResponse{}
	json.Unmarshal(body, respObject)

	// Check most recent
	if respObject.Locations[0].ID != locationId {
		t.Errorf("Expected ID %s. Got %s\n", locationId, respObject.Locations[0].ID)
	}
}

// weaviate.location.get
func Test__weaviate_location_get_JSON(t *testing.T) {
	// Create get request
	response := doRequest("/locations/"+locationId, "GET", "application/json", nil, apiKeyCmdLine)

	// Check status code get request
	if response.StatusCode != http.StatusOK {
		t.Errorf("Expected response code %d. Got %d\n", http.StatusOK, response.StatusCode)
	}

	body := getResponseBody(response)

	respObject := &models.Location{}
	json.Unmarshal(body, respObject)

	// Check ID of object
	if respObject.ID != locationId {
		t.Errorf("Expected ID %s. Got %s\n", locationId, respObject.ID)
	}

	// Create get request with non-existing location
	responseNotFound := doRequest("/locations/11111111-1111-1111-1111-111111111111", "GET", "application/json", nil, apiKeyCmdLine)

	// Check response of non-existing location
	if responseNotFound.StatusCode != http.StatusNotFound {
		t.Errorf("Expected response code %d. Got %d\n", http.StatusNotFound, responseNotFound.StatusCode)
	}
}

// weaviate.location.update
func Test__weaviate_location_update_JSON(t *testing.T) {
	// Create update request
	newPlaceID := "updated_place_id"
	jsonStr := bytes.NewBuffer([]byte(`{"address_components":[{"long_name":"TEST","short_name":"string","types":["UNDEFINED"]}],"formatted_address":"string","geometry":{"location":{},"location_type":"string","viewport":{"northeast":{},"southwest":{}}},"place_id":"` + newPlaceID + `","types":["UNDEFINED"]} `))
	response := doRequest("/locations/"+locationId, "PUT", "application/json", jsonStr, apiKeyCmdLine)

	body := getResponseBody(response)

	respObject := &models.Location{}
	json.Unmarshal(body, respObject)

	// Check location ID is same
	if respObject.ID != locationId {
		t.Errorf("Expected ID %s. Got %s\n", locationId, respObject.ID)
	}

	// Check ID after update
	if respObject.PlaceID != newPlaceID {
		t.Errorf("Expected updated PlaceID %s. Got %s\n", newPlaceID, respObject.PlaceID)
	}

	// Check if update is also applied on object when using a new GET request on same object
	responseGet := doRequest("/locations/"+locationId, "GET", "application/json", nil, apiKeyCmdLine)

	bodyGet := getResponseBody(responseGet)

	respObjectGet := &models.Location{}
	json.Unmarshal(bodyGet, respObjectGet)

	// Check place after update and get
	if respObjectGet.PlaceID != newPlaceID {
		t.Errorf("Expected updated PlaceID after GET %s. Got %s\n", newPlaceID, respObject.PlaceID)
	}

	// Check put on non-existing ID
	emptyJSON := bytes.NewBuffer([]byte(`{}`))
	responseNotFound := doRequest("/locations/11111111-1111-1111-1111-111111111111", "PUT", "application/json", emptyJSON, apiKeyCmdLine)
	if responseNotFound.StatusCode != http.StatusNotFound {
		t.Errorf("Expected response code for not found %d. Got %d\n", http.StatusNotFound, responseNotFound.StatusCode)
	}
}

// weaviate.location.patch
func Test__weaviate_location_patch_JSON(t *testing.T) {
	// Create patch request
	newPlaceID := "patched_place_id"

	jsonStr := bytes.NewBuffer([]byte(`[{ "op": "replace", "path": "/place_id", "value": "` + newPlaceID + `"}]`))
	response := doRequest("/locations/"+locationId, "PATCH", "application/json", jsonStr, apiKeyCmdLine)

	body := getResponseBody(response)

	respObject := &models.Location{}
	json.Unmarshal(body, respObject)

	// Check ID is the same
	if respObject.ID != locationId {
		t.Errorf("Expected ID %s. Got %s\n", locationId, respObject.ID)
	}

	// Check ID after patch
	if respObject.PlaceID != newPlaceID {
		t.Errorf("Expected patched PlaceID %s. Got %s\n", newPlaceID, respObject.PlaceID)
	}

	// Check if patch is also applied on object when using a new GET request on same object
	responseGet := doRequest("/locations/"+locationId, "GET", "application/json", nil, apiKeyCmdLine)

	bodyGet := getResponseBody(responseGet)

	respObjectGet := &models.Location{}
	json.Unmarshal(bodyGet, respObjectGet)

	// Check place after patch and get
	if respObjectGet.PlaceID != newPlaceID {
		t.Errorf("Expected patched PlaceID after GET %s. Got %s\n", newPlaceID, respObject.PlaceID)
	}

	// Check patch with incorrect contents
	jsonStrError := bytes.NewBuffer([]byte(`{ "op": "replace", "path": "/place_id", "value": "` + newPlaceID + `"}`))
	responseError := doRequest("/locations/"+locationId, "PATCH", "application/json", jsonStrError, apiKeyCmdLine)

	if responseError.StatusCode != http.StatusBadRequest {
		t.Errorf("Expected response code for wrong input %d. Got %d\n", http.StatusBadRequest, responseError.StatusCode)
	}

	// Check patch on non-existing ID
	emptyJSON := bytes.NewBuffer([]byte(`[{}]`))
	responseNotFound := doRequest("/locations/11111111-1111-1111-1111-111111111111", "PATCH", "application/json", emptyJSON, apiKeyCmdLine)

	if responseNotFound.StatusCode != http.StatusNotFound {
		t.Errorf("Expected response code for not found %d. Got %d\n", http.StatusNotFound, responseNotFound.StatusCode)
	}
}

// weaviate.location.delete
func Test__weaviate_location_delete_JSON(t *testing.T) {
	// Create delete request
	response := doRequest("/locations/"+locationId, "DELETE", "application/json", nil, apiKeyCmdLine)

	// Check status code get request
	if response.StatusCode != http.StatusNoContent {
		t.Errorf("Expected response code %d. Got %d\n", http.StatusNoContent, response.StatusCode)
	}

	// Create delete request
	responseAlreadyDeleted := doRequest("/locations/"+locationId, "DELETE", "application/json", nil, apiKeyCmdLine)

	// Check status code get request
	if responseAlreadyDeleted.StatusCode != http.StatusNotFound {
		t.Errorf("Expected response code already deleted %d. Got %d\n", http.StatusNotFound, responseAlreadyDeleted.StatusCode)
	}

	// Create get request with non-existing location
	responseNotFound := doRequest("/locations/11111111-1111-1111-1111-111111111111", "DELETE", "application/json", nil, apiKeyCmdLine)

	// Check response of non-existing location
	if responseNotFound.StatusCode != http.StatusNotFound {
		t.Errorf("Expected response code not found %d. Got %d\n", http.StatusNotFound, responseNotFound.StatusCode)
	}
}

// weaviate.adapters.list
func Test__weaviate_adapters_list_JSON(t *testing.T) {
	result := doRequest("/adapters", "GET", "application/json", nil, apiKeyCmdLine)
	if result.StatusCode != http.StatusNotImplemented {
		t.Errorf("Expected response code %d. Got %d\n", http.StatusNotImplemented, result.StatusCode)
	}
}

func Test__weaviate_adapters_list_XML(t *testing.T) {
	result := doRequest("/adapters", "GET", "application/xml", nil, apiKeyCmdLine)
	if result.StatusCode != http.StatusNotImplemented {
		t.Errorf("Expected response code %d. Got %d\n", http.StatusNotImplemented, result.StatusCode)
	}
}

// weaviate.adapters.insert
func Test__weaviate_adapters_insert_JSON(t *testing.T) {
	jsonStr := bytes.NewBuffer([]byte(`{}`))
	result := doRequest("/adapters", "POST", "application/json", jsonStr, apiKeyCmdLine)
	if result.StatusCode != http.StatusNotImplemented {
		t.Errorf("Expected response code %d. Got %d\n", http.StatusNotImplemented, result.StatusCode)
	}
}

func Test__weaviate_adapters_insert_XML(t *testing.T) {
	jsonStr := bytes.NewBuffer([]byte(`{}`))
	result := doRequest("/adapters", "POST", "application/xml", jsonStr, apiKeyCmdLine)
	if result.StatusCode != http.StatusNotImplemented {
		t.Errorf("Expected response code %d. Got %d\n", http.StatusNotImplemented, result.StatusCode)
	}
}

// weaviate.adapters.delete
func Test__weaviate_adapters_delete_JSON(t *testing.T) {
	result := doRequest("/adapters/1", "DELETE", "application/json", nil, apiKeyCmdLine)
	if result.StatusCode != http.StatusNotImplemented {
		t.Errorf("Expected response code %d. Got %d\n", http.StatusNotImplemented, result.StatusCode)
	}
}

func Test__weaviate_adapters_delete_XML(t *testing.T) {
	result := doRequest("/adapters/1", "DELETE", "application/xml", nil, apiKeyCmdLine)
	if result.StatusCode != http.StatusNotImplemented {
		t.Errorf("Expected response code %d. Got %d\n", http.StatusNotImplemented, result.StatusCode)
	}
}

// weaviate.adapters.get
func Test__weaviate_adapters_get_JSON(t *testing.T) {
	result := doRequest("/adapters/1", "GET", "application/json", nil, apiKeyCmdLine)
	if result.StatusCode != http.StatusNotImplemented {
		t.Errorf("Expected response code %d. Got %d\n", http.StatusNotImplemented, result.StatusCode)
	}
}

func Test__weaviate_adapters_get_XML(t *testing.T) {
	result := doRequest("/adapters/1", "GET", "application/xml", nil, apiKeyCmdLine)
	if result.StatusCode != http.StatusNotImplemented {
		t.Errorf("Expected response code %d. Got %d\n", http.StatusNotImplemented, result.StatusCode)
	}
}

// weaviate.adapters.update
func Test__weaviate_adapters_update_JSON(t *testing.T) {
	jsonStr := bytes.NewBuffer([]byte(`{ "activateUrl": "string", "activated": true, "deactivateUrl": "string", "displayName": "string", "iconUrl": "string", "id": "string", "manageUrl": "string" }`))
	result := doRequest("/adapters/1", "PUT", "application/json", jsonStr, apiKeyCmdLine)
	if result.StatusCode != http.StatusNotImplemented {
		t.Errorf("Expected response code %d. Got %d\n", http.StatusNotImplemented, result.StatusCode)
	}
}

func Test__weaviate_adapters_update_XML(t *testing.T) {
	jsonStr := bytes.NewBuffer([]byte(`{"activateUrl": "string"}`))
	result := doRequest("/adapters/1", "PUT", "application/xml", jsonStr, apiKeyCmdLine)
	if result.StatusCode != http.StatusNotImplemented {
		t.Errorf("Expected response code %d. Got %d\n", http.StatusNotImplemented, result.StatusCode)
	}
}

// weaviate.adapters.patch
func Test__weaviate_adapters_patch_JSON(t *testing.T) {
	jsonStr := bytes.NewBuffer([]byte(`{}`))
	result := doRequest("/adapters/1", "PATCH", "application/json", jsonStr, apiKeyCmdLine)
	if result.StatusCode != http.StatusNotImplemented {
		t.Errorf("Expected response code %d. Got %d\n", http.StatusNotImplemented, result.StatusCode)
	}
}

func Test__weaviate_adapters_patch_XML(t *testing.T) {
	jsonStr := bytes.NewBuffer([]byte(`{}`))
	result := doRequest("/adapters/1", "PATCH", "application/xml", jsonStr, apiKeyCmdLine)
	if result.StatusCode != http.StatusNotImplemented {
		t.Errorf("Expected response code %d. Got %d\n", http.StatusNotImplemented, result.StatusCode)
	}
}
<|endoftext|>


<commit_before>package models

import (
	"errors"
	"fmt"
	"socialapi/config"
	"time"

	"github.com/koding/bongo"
)

type ChannelMessage struct {
	// unique identifier of the channel message
	Id int64 `json:"id"`

	// Body of the mesage
	Body string `json:"body"`

	// Generated Slug for body
	Slug string `json:"slug"                        sql:"NOT NULL;TYPE:VARCHAR(100);"`

	// type of the message
	TypeConstant string `json:"typeConstant"        sql:"NOT NULL;TYPE:VARCHAR(100);"`

	// Creator of the channel message
	AccountId int64 `json:"accountId"               sql:"NOT NULL"`

	// in which channel this message is created
	InitialChannelId int64 `json:"initialChannelId" sql:"NOT NULL"`

	// Creation date of the message
	CreatedAt time.Time `json:"createdAt"           sql:"DEFAULT:CURRENT_TIMESTAMP"`

	// Modification date of the message
	UpdatedAt time.Time `json:"updatedAt"           sql:"DEFAULT:CURRENT_TIMESTAMP"`
}

func (c *ChannelMessage) AfterCreate() {
	bongo.B.AfterCreate(c)
}

func (c *ChannelMessage) AfterUpdate() {
	bongo.B.AfterUpdate(c)
}

func (c *ChannelMessage) AfterDelete() {
	bongo.B.AfterDelete(c)
}

func (c *ChannelMessage) GetId() int64 {
	return c.Id
}

func (c ChannelMessage) TableName() string {
	return "api.channel_message"
}

const (
	ChannelMessage_TYPE_POST  = "post"
	ChannelMessage_TYPE_REPLY = "reply"
	ChannelMessage_TYPE_JOIN  = "join"
	ChannelMessage_TYPE_LEAVE = "leave"
	ChannelMessage_TYPE_CHAT  = "chat"
)

func NewChannelMessage() *ChannelMessage {
	return &ChannelMessage{}
}

func (c *ChannelMessage) Fetch() error {
	return bongo.B.Fetch(c)
}

func (c *ChannelMessage) One(q *bongo.Query) error {
	return bongo.B.One(c, c, q)
}

func (c *ChannelMessage) Some(data interface{}, q *bongo.Query) error {
	return bongo.B.Some(c, data, q)
}

func bodyLenCheck(body string) error {
	if len(body) < config.Get().Limits.MessageBodyMinLen {
		return fmt.Errorf("Message Body Length should be greater than %d, yours is %d ", config.Get().Limits.MessageBodyMinLen, len(body))
	}
	return nil
}

func (c *ChannelMessage) Update() error {
	if err := bodyLenCheck(c.Body); err != nil {
		return err
	}
	// only update body
	err := bongo.B.UpdatePartial(c,
		map[string]interface{}{
			"body": c.Body,
		},
	)
	return err
}

func (c *ChannelMessage) Create() error {
	if err := bodyLenCheck(c.Body); err != nil {
		return err
	}

	var err error
	c, err = Slugify(c)
	if err != nil {
		return err
	}

	return bongo.B.Create(c)
}

func (c *ChannelMessage) Delete() error {
	return bongo.B.Delete(c)
}

func (c *ChannelMessage) FetchByIds(ids []int64) ([]ChannelMessage, error) {
	var messages []ChannelMessage

	if len(ids) == 0 {
		return messages, nil
	}

	if err := bongo.B.FetchByIds(c, &messages, ids); err != nil {
		return nil, err
	}
	return messages, nil
}

func (c *ChannelMessage) FetchRelatives(query *Query) (*ChannelMessageContainer, error) {
	if c.Id == 0 {
		return nil, errors.New("Channel message id is not set")
	}
	container := NewChannelMessageContainer()
	container.Message = c

	i := NewInteraction()
	i.MessageId = c.Id

	oldId, err := FetchMongoIdByAccountId(c.AccountId)
	if err != nil {
		return nil, err
	}

	container.AccountOldId = oldId

	interactorIds, err := i.List("like")
	if err != nil {
		return nil, err
	}

	oldIds, err := FetchMongoIdsByAccountIds(interactorIds)
	if err != nil {
		return nil, err
	}

	interactionContainer := NewInteractionContainer()
	interactionContainer.Actors = oldIds

	isInteracted, err := i.IsInteracted(query.AccountId)
	if err != nil {
		return nil, err
	}

	interactionContainer.IsInteracted = isInteracted

	if container.Interactions == nil {
		container.Interactions = make(map[string]*InteractionContainer)
	}
	if _, ok := container.Interactions["like"]; !ok {
		container.Interactions["like"] = NewInteractionContainer()
	}
	container.Interactions["like"] = interactionContainer
	return container, nil
}

func (c *ChannelMessage) BuildMessage(query *Query) (*ChannelMessageContainer, error) {
	cmc, err := c.FetchRelatives(query)
	if err != nil {
		return nil, err
	}

	mr := NewMessageReply()
	mr.MessageId = c.Id
	replies, err := mr.List()
	if err != nil {
		return nil, err
	}

	populatedChannelMessagesReplies := make([]*ChannelMessageContainer, len(replies))
	for rl := 0; rl < len(replies); rl++ {
		cmrc, err := replies[rl].FetchRelatives(query)
		if err != nil {
			return nil, err
		}
		populatedChannelMessagesReplies[rl] = cmrc
	}

	cmc.Replies = populatedChannelMessagesReplies
	return cmc, nil
}
<commit_msg>Social: add new constant for private message<commit_after>package models

import (
	"errors"
	"fmt"
	"socialapi/config"
	"time"

	"github.com/koding/bongo"
)

type ChannelMessage struct {
	// unique identifier of the channel message
	Id int64 `json:"id"`

	// Body of the mesage
	Body string `json:"body"`

	// Generated Slug for body
	Slug string `json:"slug"                        sql:"NOT NULL;TYPE:VARCHAR(100);"`

	// type of the message
	TypeConstant string `json:"typeConstant"        sql:"NOT NULL;TYPE:VARCHAR(100);"`

	// Creator of the channel message
	AccountId int64 `json:"accountId"               sql:"NOT NULL"`

	// in which channel this message is created
	InitialChannelId int64 `json:"initialChannelId" sql:"NOT NULL"`

	// Creation date of the message
	CreatedAt time.Time `json:"createdAt"           sql:"DEFAULT:CURRENT_TIMESTAMP"`

	// Modification date of the message
	UpdatedAt time.Time `json:"updatedAt"           sql:"DEFAULT:CURRENT_TIMESTAMP"`
}

func (c *ChannelMessage) AfterCreate() {
	bongo.B.AfterCreate(c)
}

func (c *ChannelMessage) AfterUpdate() {
	bongo.B.AfterUpdate(c)
}

func (c *ChannelMessage) AfterDelete() {
	bongo.B.AfterDelete(c)
}

func (c *ChannelMessage) GetId() int64 {
	return c.Id
}

func (c ChannelMessage) TableName() string {
	return "api.channel_message"
}

const (
	ChannelMessage_TYPE_POST            = "post"
	ChannelMessage_TYPE_REPLY           = "reply"
	ChannelMessage_TYPE_JOIN            = "join"
	ChannelMessage_TYPE_LEAVE           = "leave"
	ChannelMessage_TYPE_CHAT            = "chat"
	ChannelMessage_TYPE_PRIVATE_MESSAGE = "privateMessage"
)

func NewChannelMessage() *ChannelMessage {
	return &ChannelMessage{}
}

func (c *ChannelMessage) Fetch() error {
	return bongo.B.Fetch(c)
}

func (c *ChannelMessage) One(q *bongo.Query) error {
	return bongo.B.One(c, c, q)
}

func (c *ChannelMessage) Some(data interface{}, q *bongo.Query) error {
	return bongo.B.Some(c, data, q)
}

func bodyLenCheck(body string) error {
	if len(body) < config.Get().Limits.MessageBodyMinLen {
		return fmt.Errorf("Message Body Length should be greater than %d, yours is %d ", config.Get().Limits.MessageBodyMinLen, len(body))
	}
	return nil
}

func (c *ChannelMessage) Update() error {
	if err := bodyLenCheck(c.Body); err != nil {
		return err
	}
	// only update body
	err := bongo.B.UpdatePartial(c,
		map[string]interface{}{
			"body": c.Body,
		},
	)
	return err
}

func (c *ChannelMessage) Create() error {
	if err := bodyLenCheck(c.Body); err != nil {
		return err
	}

	var err error
	c, err = Slugify(c)
	if err != nil {
		return err
	}

	return bongo.B.Create(c)
}

func (c *ChannelMessage) Delete() error {
	return bongo.B.Delete(c)
}

func (c *ChannelMessage) FetchByIds(ids []int64) ([]ChannelMessage, error) {
	var messages []ChannelMessage

	if len(ids) == 0 {
		return messages, nil
	}

	if err := bongo.B.FetchByIds(c, &messages, ids); err != nil {
		return nil, err
	}
	return messages, nil
}

func (c *ChannelMessage) FetchRelatives(query *Query) (*ChannelMessageContainer, error) {
	if c.Id == 0 {
		return nil, errors.New("Channel message id is not set")
	}
	container := NewChannelMessageContainer()
	container.Message = c

	i := NewInteraction()
	i.MessageId = c.Id

	oldId, err := FetchMongoIdByAccountId(c.AccountId)
	if err != nil {
		return nil, err
	}

	container.AccountOldId = oldId

	interactorIds, err := i.List("like")
	if err != nil {
		return nil, err
	}

	oldIds, err := FetchMongoIdsByAccountIds(interactorIds)
	if err != nil {
		return nil, err
	}

	interactionContainer := NewInteractionContainer()
	interactionContainer.Actors = oldIds

	isInteracted, err := i.IsInteracted(query.AccountId)
	if err != nil {
		return nil, err
	}

	interactionContainer.IsInteracted = isInteracted

	if container.Interactions == nil {
		container.Interactions = make(map[string]*InteractionContainer)
	}
	if _, ok := container.Interactions["like"]; !ok {
		container.Interactions["like"] = NewInteractionContainer()
	}
	container.Interactions["like"] = interactionContainer
	return container, nil
}

func (c *ChannelMessage) BuildMessage(query *Query) (*ChannelMessageContainer, error) {
	cmc, err := c.FetchRelatives(query)
	if err != nil {
		return nil, err
	}

	mr := NewMessageReply()
	mr.MessageId = c.Id
	replies, err := mr.List()
	if err != nil {
		return nil, err
	}

	populatedChannelMessagesReplies := make([]*ChannelMessageContainer, len(replies))
	for rl := 0; rl < len(replies); rl++ {
		cmrc, err := replies[rl].FetchRelatives(query)
		if err != nil {
			return nil, err
		}
		populatedChannelMessagesReplies[rl] = cmrc
	}

	cmc.Replies = populatedChannelMessagesReplies
	return cmc, nil
}
<|endoftext|>


<commit_before>package api

import (
	"encoding/json"
	"errors"
	"fmt"
	"koding/db/mongodb/modelhelper"
	"net/http"
	"net/url"
	"socialapi/models"
	"socialapi/workers/common/response"
	"strings"

	"github.com/nlopes/slack"

	"golang.org/x/oauth2"
	"gopkg.in/mgo.v2"
)

const slackAway = "away"

// Slack holds runtime config for slack OAuth system
type Slack struct {
	Hostname          string
	Protocol          string
	VerificationToken string
	OAuthConf         *oauth2.Config
}

// SlackMessageRequest carries message creation request from client side
type SlackMessageRequest struct {
	Channel string
	Text    string
	Params  slack.PostMessageParameters
}

// Send initiates Slack OAuth
func (s *Slack) Send(u *url.URL, h http.Header, _ interface{}, context *models.Context) (int, http.Header, interface{}, error) {
	if !context.IsLoggedIn() {
		return response.NewBadRequest(models.ErrNotLoggedIn)
	}

	session, err := models.Cache.Session.ById(context.Client.SessionID)
	if err != nil {
		return response.NewBadRequest(models.ErrNotLoggedIn)
	}

	url := s.OAuthConf.AuthCodeURL(session.Id.Hex(), oauth2.AccessTypeOffline)
	h.Set("Location", url)
	return http.StatusTemporaryRedirect, h, nil, nil

}

// Callback handler is used for handling redirection requests from Slack API
//
// If we can get the token successfully, then we store user's token in mongo in
// Callback handler
func (s *Slack) Callback(u *url.URL, h http.Header, _ interface{}, context *models.Context) (int, http.Header, interface{}, error) {
	state := u.Query().Get("state")
	if state == "" {
		return response.NewBadRequest(errors.New("state is not set"))
	}

	session, err := modelhelper.GetSessionById(state)
	if err != nil {
		return response.NewBadRequest(models.ErrNotLoggedIn)
	}

	redirectURL, err := url.Parse(s.OAuthConf.RedirectURL)
	if err != nil {
		return response.NewBadRequest(err)
	}

	// we want to redirect slacks redirection into our success handler with team
	// name included in the redirection url, this is required because user does
	// not need to be logged in plain koding.com doamin
	// eg: dev.koding.com:8090/api/social/slack/oauth/callback?<query params>
	// 			should be redirected to
	// 		teamname.dev.koding.com:8090/api/social/slack/oauth/success?<query params>

	// set incoming request's query params into redirected url
	redirectURL.RawQuery = u.Query().Encode()

	// change subdomain if not only it is koding
	if session.GroupName != models.Channel_KODING_NAME {
		// set team's subdomain
		redirectURL.Host = fmt.Sprintf("%s.%s", session.GroupName, redirectURL.Host)
	}

	// replace 'callback' with 'success'
	redirectURL.Path = strings.Replace(redirectURL.Path, "callback", "success", -1)

	h.Set("Location", redirectURL.String())
	return http.StatusTemporaryRedirect, h, nil, nil
}

// Success handler is used for handling redirection requests from Callback handler
//
// We need this for handling the internal redirection of team requests
func (s *Slack) Success(u *url.URL, h http.Header, _ interface{}, context *models.Context) (int, http.Header, interface{}, error) {
	// get session data from state
	state := u.Query().Get("state")
	if state == "" {
		return response.NewBadRequest(errors.New("state is not set"))
	}

	session, err := modelhelper.GetSessionById(state)
	if err != nil {
		return response.NewBadRequest(models.ErrNotLoggedIn)
	}

	// get user info
	user, err := modelhelper.GetUser(session.Username)
	if err != nil && err != mgo.ErrNotFound {
		return response.NewBadRequest(err)
	}

	if err == mgo.ErrNotFound {
		return response.NewBadRequest(err)
	}

	// start exchanging code for a token
	code := u.Query().Get("code")
	if code == "" {
		return response.NewBadRequest(errors.New("code is not set"))
	}

	token, err := s.OAuthConf.Exchange(oauth2.NoContext, code)
	if err != nil {
		return response.NewBadRequest(err)
	}

	// update the slack data
	if err := updateUserSlackToken(user, session.GroupName, token.AccessToken); err != nil {
		return response.NewBadRequest(err)
	}

	h.Set("Location", "/Admin/Invitations/Slack")
	return http.StatusTemporaryRedirect, h, nil, nil
}

// ListUsers lists users of a slack team
func (s *Slack) ListUsers(u *url.URL, h http.Header, _ interface{}, context *models.Context) (int, http.Header, interface{}, error) {
	if !context.IsLoggedIn() {
		return response.NewBadRequest(models.ErrNotLoggedIn)
	}

	token, err := getSlackTokenWithContext(context)
	if err != nil {
		return response.NewBadRequest(err)
	}

	return response.HandleResultAndError(getUsers(token))
}

// ListChannels lists the channels of a slack team
func (s *Slack) ListChannels(u *url.URL, h http.Header, _ interface{}, context *models.Context) (int, http.Header, interface{}, error) {
	if !context.IsLoggedIn() {
		return response.NewBadRequest(models.ErrNotLoggedIn)
	}

	var token string
	var groupToken string

	userToken, err := getSlackToken(context)
	if err != nil || token == "" {
		groupToken, err = getAnySlackTokenWithGroup(context)
		if err != nil {
			return response.NewBadRequest(err)
		}
	}

	if userToken != "" {
		token = userToken
		return response.HandleResultAndError(getChannels(token))
	} else {
		token = groupToken
		return response.HandleResultAndError(getOnlyChannels(token))
	}
}

// TeamInfo shows basic info regarding a slack team
func (s *Slack) TeamInfo(u *url.URL, h http.Header, _ interface{}, context *models.Context) (int, http.Header, interface{}, error) {
	if !context.IsLoggedIn() {
		return response.NewBadRequest(models.ErrNotLoggedIn)
	}

	token, err := getSlackToken(context)
	if err != nil {
		return response.NewBadRequest(err)
	}

	return response.HandleResultAndError(getTeamInfo(token))
}

// PostMessage posts a message to a slack channel/group
func (s *Slack) PostMessage(u *url.URL, h http.Header, req *SlackMessageRequest, context *models.Context) (int, http.Header, interface{}, error) {
	if !context.IsLoggedIn() {
		return response.NewBadRequest(models.ErrNotLoggedIn)
	}

	token, err := getSlackToken(context)
	if err != nil {
		return response.NewBadRequest(err)
	}
	return response.HandleResultAndError(postMessage(token, req))
}

// SlashCommand handles slash commands coming from slack
//
// Note: this is experimental, on prod instances this will just say hi,
// otherwise will output incoming request
func (s *Slack) SlashCommand(w http.ResponseWriter, req *http.Request) {
	if err := req.ParseForm(); err != nil {
		http.Error(w, err.Error(), http.StatusBadRequest)
		return
	}

	command, err := newSlashCommandFromURLValues(req.PostForm)
	if err != nil {
		http.Error(w, err.Error(), http.StatusBadRequest)
		return
	}

	if command.Token != s.VerificationToken {
		errMessage := fmt.Sprintf("request from unidentified source: %s - %s", command.Token, req.Host)
		http.Error(w, errMessage, http.StatusBadRequest)
		return
	}

	fmt.Fprintln(w, "hi from koding bot!")

	if command.Robot != "koding" {
		fmt.Fprintln(w, "here is some debug log for non-prod requests")
		fmt.Fprintln(w)

		if err := json.NewEncoder(w).Encode(command); err != nil {
			http.Error(w, err.Error(), http.StatusBadRequest)
			return
		}
	}
}
<commit_msg>go: remove extra string variable<commit_after>package api

import (
	"encoding/json"
	"errors"
	"fmt"
	"koding/db/mongodb/modelhelper"
	"net/http"
	"net/url"
	"socialapi/models"
	"socialapi/workers/common/response"
	"strings"

	"github.com/nlopes/slack"

	"golang.org/x/oauth2"
	"gopkg.in/mgo.v2"
)

const slackAway = "away"

// Slack holds runtime config for slack OAuth system
type Slack struct {
	Hostname          string
	Protocol          string
	VerificationToken string
	OAuthConf         *oauth2.Config
}

// SlackMessageRequest carries message creation request from client side
type SlackMessageRequest struct {
	Channel string
	Text    string
	Params  slack.PostMessageParameters
}

// Send initiates Slack OAuth
func (s *Slack) Send(u *url.URL, h http.Header, _ interface{}, context *models.Context) (int, http.Header, interface{}, error) {
	if !context.IsLoggedIn() {
		return response.NewBadRequest(models.ErrNotLoggedIn)
	}

	session, err := models.Cache.Session.ById(context.Client.SessionID)
	if err != nil {
		return response.NewBadRequest(models.ErrNotLoggedIn)
	}

	url := s.OAuthConf.AuthCodeURL(session.Id.Hex(), oauth2.AccessTypeOffline)
	h.Set("Location", url)
	return http.StatusTemporaryRedirect, h, nil, nil

}

// Callback handler is used for handling redirection requests from Slack API
//
// If we can get the token successfully, then we store user's token in mongo in
// Callback handler
func (s *Slack) Callback(u *url.URL, h http.Header, _ interface{}, context *models.Context) (int, http.Header, interface{}, error) {
	state := u.Query().Get("state")
	if state == "" {
		return response.NewBadRequest(errors.New("state is not set"))
	}

	session, err := modelhelper.GetSessionById(state)
	if err != nil {
		return response.NewBadRequest(models.ErrNotLoggedIn)
	}

	redirectURL, err := url.Parse(s.OAuthConf.RedirectURL)
	if err != nil {
		return response.NewBadRequest(err)
	}

	// we want to redirect slacks redirection into our success handler with team
	// name included in the redirection url, this is required because user does
	// not need to be logged in plain koding.com doamin
	// eg: dev.koding.com:8090/api/social/slack/oauth/callback?<query params>
	// 			should be redirected to
	// 		teamname.dev.koding.com:8090/api/social/slack/oauth/success?<query params>

	// set incoming request's query params into redirected url
	redirectURL.RawQuery = u.Query().Encode()

	// change subdomain if not only it is koding
	if session.GroupName != models.Channel_KODING_NAME {
		// set team's subdomain
		redirectURL.Host = fmt.Sprintf("%s.%s", session.GroupName, redirectURL.Host)
	}

	// replace 'callback' with 'success'
	redirectURL.Path = strings.Replace(redirectURL.Path, "callback", "success", -1)

	h.Set("Location", redirectURL.String())
	return http.StatusTemporaryRedirect, h, nil, nil
}

// Success handler is used for handling redirection requests from Callback handler
//
// We need this for handling the internal redirection of team requests
func (s *Slack) Success(u *url.URL, h http.Header, _ interface{}, context *models.Context) (int, http.Header, interface{}, error) {
	// get session data from state
	state := u.Query().Get("state")
	if state == "" {
		return response.NewBadRequest(errors.New("state is not set"))
	}

	session, err := modelhelper.GetSessionById(state)
	if err != nil {
		return response.NewBadRequest(models.ErrNotLoggedIn)
	}

	// get user info
	user, err := modelhelper.GetUser(session.Username)
	if err != nil && err != mgo.ErrNotFound {
		return response.NewBadRequest(err)
	}

	if err == mgo.ErrNotFound {
		return response.NewBadRequest(err)
	}

	// start exchanging code for a token
	code := u.Query().Get("code")
	if code == "" {
		return response.NewBadRequest(errors.New("code is not set"))
	}

	token, err := s.OAuthConf.Exchange(oauth2.NoContext, code)
	if err != nil {
		return response.NewBadRequest(err)
	}

	// update the slack data
	if err := updateUserSlackToken(user, session.GroupName, token.AccessToken); err != nil {
		return response.NewBadRequest(err)
	}

	h.Set("Location", "/Admin/Invitations/Slack")
	return http.StatusTemporaryRedirect, h, nil, nil
}

// ListUsers lists users of a slack team
func (s *Slack) ListUsers(u *url.URL, h http.Header, _ interface{}, context *models.Context) (int, http.Header, interface{}, error) {
	if !context.IsLoggedIn() {
		return response.NewBadRequest(models.ErrNotLoggedIn)
	}

	token, err := getSlackTokenWithContext(context)
	if err != nil {
		return response.NewBadRequest(err)
	}

	return response.HandleResultAndError(getUsers(token))
}

// ListChannels lists the channels of a slack team
func (s *Slack) ListChannels(u *url.URL, h http.Header, _ interface{}, context *models.Context) (int, http.Header, interface{}, error) {
	if !context.IsLoggedIn() {
		return response.NewBadRequest(models.ErrNotLoggedIn)
	}

	var groupToken string

	userToken, err := getSlackToken(context)
	if err != nil || userToken == "" {
		groupToken, err = getAnySlackTokenWithGroup(context)
		if err != nil {
			return response.NewBadRequest(err)
		}
	}

	if userToken != "" {
		return response.HandleResultAndError(getChannels(userToken))
	} else {
		return response.HandleResultAndError(getOnlyChannels(groupToken))
	}
}

// TeamInfo shows basic info regarding a slack team
func (s *Slack) TeamInfo(u *url.URL, h http.Header, _ interface{}, context *models.Context) (int, http.Header, interface{}, error) {
	if !context.IsLoggedIn() {
		return response.NewBadRequest(models.ErrNotLoggedIn)
	}

	token, err := getSlackToken(context)
	if err != nil {
		return response.NewBadRequest(err)
	}

	return response.HandleResultAndError(getTeamInfo(token))
}

// PostMessage posts a message to a slack channel/group
func (s *Slack) PostMessage(u *url.URL, h http.Header, req *SlackMessageRequest, context *models.Context) (int, http.Header, interface{}, error) {
	if !context.IsLoggedIn() {
		return response.NewBadRequest(models.ErrNotLoggedIn)
	}

	token, err := getSlackToken(context)
	if err != nil {
		return response.NewBadRequest(err)
	}
	return response.HandleResultAndError(postMessage(token, req))
}

// SlashCommand handles slash commands coming from slack
//
// Note: this is experimental, on prod instances this will just say hi,
// otherwise will output incoming request
func (s *Slack) SlashCommand(w http.ResponseWriter, req *http.Request) {
	if err := req.ParseForm(); err != nil {
		http.Error(w, err.Error(), http.StatusBadRequest)
		return
	}

	command, err := newSlashCommandFromURLValues(req.PostForm)
	if err != nil {
		http.Error(w, err.Error(), http.StatusBadRequest)
		return
	}

	if command.Token != s.VerificationToken {
		errMessage := fmt.Sprintf("request from unidentified source: %s - %s", command.Token, req.Host)
		http.Error(w, errMessage, http.StatusBadRequest)
		return
	}

	fmt.Fprintln(w, "hi from koding bot!")

	if command.Robot != "koding" {
		fmt.Fprintln(w, "here is some debug log for non-prod requests")
		fmt.Fprintln(w)

		if err := json.NewEncoder(w).Encode(command); err != nil {
			http.Error(w, err.Error(), http.StatusBadRequest)
			return
		}
	}
}
<|endoftext|>


<commit_before>package goriot

import (
	"errors"
	"fmt"
	"strconv"
	"strings"
)

type masteryBook struct {
	Pages      []MasteryPage `json:"pages"`
	SummonerID int64         `json:"summonerId"`
}

//MasteryPage represents a League of Legends mastery page
type MasteryPage struct {
	Current   bool      `json:"current"`
	ID        int64     `json:"id"`
	Name      string    `json:"name"`
	Masteries []Mastery `json:"masteries"`
}

//Mastery located inside a page
type Mastery struct {
	ID   int `json:"id"`
	Rank int `json:"rank"`
}

type runeBook struct {
	Pages      []RunePage `json:"pages"`
	SummonerID int        `json:"summonerId"`
}

//RunePage is a League of Legends rune page
type RunePage struct {
	Current bool       `json:"current"`
	ID      int64      `json:"id"`
	Name    string     `json:"name"`
	Slots   []RuneSlot `json:"slots"`
}

//RuneSlot is a slot for a Rune to go on a RunePage
type RuneSlot struct {
	Rune       Rune `json:"rune"`
	RuneSlotID int  `json:"runeSlotId"`
}

//Rune is a League of Legends Rune
type Rune struct {
	Description string `json:"description"`
	ID          int    `json:"id"`
	Name        string `json:"name"`
	Tier        int    `json:"tier"`
}

//Summoner is a player of League of Legends
type Summoner struct {
	ProfileIconID int    `json:"profileIconId"`
	SummonerLevel int    `json:"summonerLevel"`
	ID            int64  `json:"id"`
	Name          string `json:"name"`
	RevisionDate  int64  `json:"revisionDate"`
}

//MasteriesBySummoner retrieves the mastery pages of the supplied summonerIDs from Riot Games API.
//It returns a map of array pf MasteryPage with the key being the summonerID and any errors that occured from the server
//The global API key must be set before use
func MasteriesBySummoner(region string, summonerID ...int64) (masteries map[int64][]MasteryPage, err error) {
	if !IsKeySet() {
		return masteries, ErrAPIKeyNotSet
	}
	masteries = make(map[int64][]MasteryPage)
	var pages map[string]masteryBook
	summonerIDstr, err := createSummonerIDString(summonerID)
	if err != nil {
		return
	}
	args := "api_key=" + apikey
	url := fmt.Sprintf("%v/lol/%v/v1.4/summoner/%v/masteries?%v", BaseURL, region, summonerIDstr, args)
	err = requestAndUnmarshal(url, &pages)
	if err != nil {
		return
	}
	for k, v := range pages {
		n, err := strconv.ParseInt(k, 10, 64)
		if err != nil {
			return masteries, err
		}
		masteries[n] = v.Pages
	}
	return masteries, err
}

//RunesBySummoner retrieves the rune pages of the supplied summonerIDs from Riot Games API.
//It returns a map of array of RunePage with the key being the summonerID and any errors that occured from the server
//The global API key must be set before use
func RunesBySummoner(region string, summonerID ...int64) (runes map[int64][]RunePage, err error) {
	if !IsKeySet() {
		return runes, ErrAPIKeyNotSet
	}
	runes = make(map[int64][]RunePage)
	var pages map[string]runeBook
	summonerIDstr, err := createSummonerIDString(summonerID)
	if err != nil {
		return
	}
	args := "api_key=" + apikey
	url := fmt.Sprintf("%v/lol/%v/v1.3/summoner/%v/runes?%v", BaseURL, region, summonerIDstr, args)

	err = requestAndUnmarshal(url, &pages)
	if err != nil {
		return
	}
	for k, v := range pages {
		n, err := strconv.ParseInt(k, 10, 64)
		if err != nil {
			return runes, err
		}
		runes[n] = v.Pages
	}
	return runes, err
}

//SummonerByName retrieves the summoner information of the provided summoner names from Riot Games API.
//It returns a Map of Summoner with the key being the summoner name and any errors that occured from the server
//The global API key must be set before use
//WARNING: The map's key is not necessarily the same string used in the request. It is
//recommended to use NormalizeSummonerName before calling this function
func SummonerByName(region string, name ...string) (summoners map[string]Summoner, err error) {
	if !IsKeySet() {
		return summoners, ErrAPIKeyNotSet
	}
	names := strings.Join(name, ", ")
	summoners = make(map[string]Summoner)
	args := "api_key=" + apikey
	url := fmt.Sprintf("%v/lol/%v/v1.3/summoner/by-name/%v?%v", BaseURL, region, names, args)
	err = requestAndUnmarshal(url, &summoners)
	if err != nil {
		return
	}
	return
}

//SummonerByID retrieves the summoner information of the provided summoner IDs from Riot Games API.
//It returns a map of Summoner with the key being summonerID and any errors that occured from the server
//The global API key must be set before use
func SummonerByID(region string, summonerID ...int64) (summoners map[int64]Summoner, err error) {
	if !IsKeySet() {
		return summoners, ErrAPIKeyNotSet
	}

	var summonersString map[string]Summoner
	summoners = make(map[int64]Summoner)
	summonerIDstr, err := createSummonerIDString(summonerID)
	if err != nil {
		return
	}

	args := "api_key=" + apikey
	url := fmt.Sprintf("%v/lol/%v/v1.3/summoner/%v?%v", BaseURL, region, summonerIDstr, args)

	err = requestAndUnmarshal(url, &summonersString)
	if err != nil {
		return
	}
	for k, v := range summonersString {
		n, err := strconv.ParseInt(k, 10, 64)
		if err != nil {
			return summoners, err
		}
		summoners[n] = v
	}
	return
}

//SummonerNamesByID retrieves multiple summoner's information of the provided summoner IDs from Riot Games API.
//It returns an map of string with the key being the summonerID and any errors that occured from the server
//The global API key must be set before use
func SummonerNamesByID(region string, summonerID ...int64) (summoners map[int64]string, err error) {
	if !IsKeySet() {
		return summoners, ErrAPIKeyNotSet
	}
	var summonerNames map[string]string
	summoners = make(map[int64]string)
	summonerIDstr, err := createSummonerIDString(summonerID)
	if err != nil {
		return
	}
	args := "api_key=" + apikey
	url := fmt.Sprintf("%v/lol/%v/v1.3/summoner/%v/name?%v", BaseURL, region, summonerIDstr, args)

	err = requestAndUnmarshal(url, &summonerNames)
	if err != nil {
		return
	}
	for k, v := range summonerNames {
		n, err := strconv.ParseInt(k, 10, 64)
		if err != nil {
			return summoners, err
		}
		summoners[n] = v
	}
	return summoners, err
}

func createSummonerIDString(summonerID []int64) (summonerIDstr string, err error) {
	if len(summonerID) > 40 {
		return summonerIDstr, errors.New("A Maximum of 40 SummonerIDs are allowed")
	}
	for k, v := range summonerID {
		summonerIDstr += strconv.FormatInt(v, 10)
		if k != len(summonerID)-1 {
			summonerIDstr += ","
		}
	}
	return
}

//NormalizeSummonerName takes an arbitrary number of strings and returns a string array containing the strings
//standardized to league of legends internal standard (lowecase and strings removed)
func NormalizeSummonerName(summonerNames ...string) []string {
	for i, v := range summonerNames {
		summonerName := strings.ToLower(v)
		summonerName = strings.Replace(summonerName, " ", "", -1)
		summonerNames[i] = summonerName
	}
	return summonerNames
}
<commit_msg>Updated Rune changes to match Summoner-v1.4<commit_after>package goriot

import (
	"errors"
	"fmt"
	"strconv"
	"strings"
)

type masteryBook struct {
	Pages      []MasteryPage `json:"pages"`
	SummonerID int64         `json:"summonerId"`
}

//MasteryPage represents a League of Legends mastery page
type MasteryPage struct {
	Current   bool      `json:"current"`
	ID        int64     `json:"id"`
	Name      string    `json:"name"`
	Masteries []Mastery `json:"masteries"`
}

//Mastery located inside a page
type Mastery struct {
	ID   int `json:"id"`
	Rank int `json:"rank"`
}

type runeBook struct {
	Pages      []RunePage `json:"pages"`
	SummonerID int        `json:"summonerId"`
}

//RunePage is a League of Legends rune page
type RunePage struct {
	Current bool       `json:"current"`
	ID      int64      `json:"id"`
	Name    string     `json:"name"`
	Slots   []RuneSlot `json:"slots"`
}

//RuneSlot is a slot for a Rune to go on a RunePage
type RuneSlot struct {
	RuneId     int `json:"runeId"`
	RuneSlotID int `json:"runeSlotId"`
}

//Summoner is a player of League of Legends
type Summoner struct {
	ProfileIconID int    `json:"profileIconId"`
	SummonerLevel int    `json:"summonerLevel"`
	ID            int64  `json:"id"`
	Name          string `json:"name"`
	RevisionDate  int64  `json:"revisionDate"`
}

//MasteriesBySummoner retrieves the mastery pages of the supplied summonerIDs from Riot Games API.
//It returns a map of array pf MasteryPage with the key being the summonerID and any errors that occured from the server
//The global API key must be set before use
func MasteriesBySummoner(region string, summonerID ...int64) (masteries map[int64][]MasteryPage, err error) {
	if !IsKeySet() {
		return masteries, ErrAPIKeyNotSet
	}
	masteries = make(map[int64][]MasteryPage)
	var pages map[string]masteryBook
	summonerIDstr, err := createSummonerIDString(summonerID)
	if err != nil {
		return
	}
	args := "api_key=" + apikey
	url := fmt.Sprintf("%v/lol/%v/v1.4/summoner/%v/masteries?%v", BaseURL, region, summonerIDstr, args)
	err = requestAndUnmarshal(url, &pages)
	if err != nil {
		return
	}
	for k, v := range pages {
		n, err := strconv.ParseInt(k, 10, 64)
		if err != nil {
			return masteries, err
		}
		masteries[n] = v.Pages
	}
	return masteries, err
}

//RunesBySummoner retrieves the rune pages of the supplied summonerIDs from Riot Games API.
//It returns a map of array of RunePage with the key being the summonerID and any errors that occured from the server
//The global API key must be set before use
func RunesBySummoner(region string, summonerID ...int64) (runes map[int64][]RunePage, err error) {
	if !IsKeySet() {
		return runes, ErrAPIKeyNotSet
	}
	runes = make(map[int64][]RunePage)
	var pages map[string]runeBook
	summonerIDstr, err := createSummonerIDString(summonerID)
	if err != nil {
		return
	}
	args := "api_key=" + apikey
	url := fmt.Sprintf("%v/lol/%v/v1.4/summoner/%v/runes?%v", BaseURL, region, summonerIDstr, args)

	err = requestAndUnmarshal(url, &pages)
	if err != nil {
		return
	}
	for k, v := range pages {
		n, err := strconv.ParseInt(k, 10, 64)
		if err != nil {
			return runes, err
		}
		runes[n] = v.Pages
	}
	return runes, err
}

//SummonerByName retrieves the summoner information of the provided summoner names from Riot Games API.
//It returns a Map of Summoner with the key being the summoner name and any errors that occured from the server
//The global API key must be set before use
//WARNING: The map's key is not necessarily the same string used in the request. It is
//recommended to use NormalizeSummonerName before calling this function
func SummonerByName(region string, name ...string) (summoners map[string]Summoner, err error) {
	if !IsKeySet() {
		return summoners, ErrAPIKeyNotSet
	}
	names := strings.Join(name, ", ")
	summoners = make(map[string]Summoner)
	args := "api_key=" + apikey
	url := fmt.Sprintf("%v/lol/%v/v1.3/summoner/by-name/%v?%v", BaseURL, region, names, args)
	err = requestAndUnmarshal(url, &summoners)
	if err != nil {
		return
	}
	return
}

//SummonerByID retrieves the summoner information of the provided summoner IDs from Riot Games API.
//It returns a map of Summoner with the key being summonerID and any errors that occured from the server
//The global API key must be set before use
func SummonerByID(region string, summonerID ...int64) (summoners map[int64]Summoner, err error) {
	if !IsKeySet() {
		return summoners, ErrAPIKeyNotSet
	}

	var summonersString map[string]Summoner
	summoners = make(map[int64]Summoner)
	summonerIDstr, err := createSummonerIDString(summonerID)
	if err != nil {
		return
	}

	args := "api_key=" + apikey
	url := fmt.Sprintf("%v/lol/%v/v1.3/summoner/%v?%v", BaseURL, region, summonerIDstr, args)

	err = requestAndUnmarshal(url, &summonersString)
	if err != nil {
		return
	}
	for k, v := range summonersString {
		n, err := strconv.ParseInt(k, 10, 64)
		if err != nil {
			return summoners, err
		}
		summoners[n] = v
	}
	return
}

//SummonerNamesByID retrieves multiple summoner's information of the provided summoner IDs from Riot Games API.
//It returns an map of string with the key being the summonerID and any errors that occured from the server
//The global API key must be set before use
func SummonerNamesByID(region string, summonerID ...int64) (summoners map[int64]string, err error) {
	if !IsKeySet() {
		return summoners, ErrAPIKeyNotSet
	}
	var summonerNames map[string]string
	summoners = make(map[int64]string)
	summonerIDstr, err := createSummonerIDString(summonerID)
	if err != nil {
		return
	}
	args := "api_key=" + apikey
	url := fmt.Sprintf("%v/lol/%v/v1.3/summoner/%v/name?%v", BaseURL, region, summonerIDstr, args)

	err = requestAndUnmarshal(url, &summonerNames)
	if err != nil {
		return
	}
	for k, v := range summonerNames {
		n, err := strconv.ParseInt(k, 10, 64)
		if err != nil {
			return summoners, err
		}
		summoners[n] = v
	}
	return summoners, err
}

func createSummonerIDString(summonerID []int64) (summonerIDstr string, err error) {
	if len(summonerID) > 40 {
		return summonerIDstr, errors.New("A Maximum of 40 SummonerIDs are allowed")
	}
	for k, v := range summonerID {
		summonerIDstr += strconv.FormatInt(v, 10)
		if k != len(summonerID)-1 {
			summonerIDstr += ","
		}
	}
	return
}

//NormalizeSummonerName takes an arbitrary number of strings and returns a string array containing the strings
//standardized to league of legends internal standard (lowecase and strings removed)
func NormalizeSummonerName(summonerNames ...string) []string {
	for i, v := range summonerNames {
		summonerName := strings.ToLower(v)
		summonerName = strings.Replace(summonerName, " ", "", -1)
		summonerNames[i] = summonerName
	}
	return summonerNames
}
<|endoftext|>


<commit_before>package platform_test

import (
	"time"

	. "github.com/onsi/ginkgo"
	. "github.com/onsi/gomega"

	boshlog "bosh/logger"
	. "bosh/platform"
	fakecd "bosh/platform/cdutil/fakes"
	boshcmd "bosh/platform/commands"
	fakedisk "bosh/platform/disk/fakes"
	boshnet "bosh/platform/net"
	fakestats "bosh/platform/stats/fakes"
	boshvitals "bosh/platform/vitals"
	boshsettings "bosh/settings"
	boshdirs "bosh/settings/directories"
	fakesys "bosh/system/fakes"
)

const UBUNTU_EXPECTED_NETWORK_INTERFACES = `auto lo
iface lo inet loopback

auto eth0
iface eth0 inet static
    address 192.168.195.6
    network 192.168.195.0
    netmask 255.255.255.0
    broadcast 192.168.195.255
    gateway 192.168.195.1`

const UBUNTU_EXPECTED_RESOLV_CONF = `nameserver 10.80.130.1
nameserver 10.80.130.2
`

func init() {
	const UBUNTU_EXPECTED_DHCP_CONFIG = `# Generated by bosh-agent

option rfc3442-classless-static-routes code 121 = array of unsigned integer 8;

send host-name "<hostname>";

request subnet-mask, broadcast-address, time-offset, routers,
	domain-name, domain-name-servers, domain-search, host-name,
	netbios-name-servers, netbios-scope, interface-mtu,
	rfc3442-classless-static-routes, ntp-servers;

prepend domain-name-servers zz.zz.zz.zz;
prepend domain-name-servers yy.yy.yy.yy;
prepend domain-name-servers xx.xx.xx.xx;
`

	Describe("Testing with Ginkgo", func() {
		var (
			collector       *fakestats.FakeStatsCollector
			fs              *fakesys.FakeFileSystem
			cmdRunner       *fakesys.FakeCmdRunner
			diskManager     *fakedisk.FakeDiskManager
			dirProvider     boshdirs.DirectoriesProvider
			diskWaitTimeout time.Duration
			platform        Platform
			cdutil          *fakecd.FakeCdUtil
			compressor      boshcmd.Compressor
			copier          boshcmd.Copier
			vitalsService   boshvitals.Service
			logger          boshlog.Logger
		)

		BeforeEach(func() {
			collector = &fakestats.FakeStatsCollector{}
			fs = fakesys.NewFakeFileSystem()
			cmdRunner = fakesys.NewFakeCmdRunner()
			diskManager = fakedisk.NewFakeDiskManager()
			dirProvider = boshdirs.NewDirectoriesProvider("/fake-dir")
			diskWaitTimeout = 1 * time.Millisecond
			cdutil = fakecd.NewFakeCdUtil()
			compressor = boshcmd.NewTarballCompressor(cmdRunner, fs)
			copier = boshcmd.NewCpCopier(cmdRunner, fs)
			vitalsService = boshvitals.NewService(collector, dirProvider)
			logger = boshlog.NewLogger(boshlog.LEVEL_NONE)
		})

		JustBeforeEach(func() {
			netManager := boshnet.NewUbuntuNetManager(fs, cmdRunner, 1*time.Millisecond)

			platform = NewLinuxPlatform(
				fs,
				cmdRunner,
				collector,
				compressor,
				copier,
				dirProvider,
				vitalsService,
				cdutil,
				diskManager,
				netManager,
				1*time.Millisecond,
				logger,
			)
		})

		It("ubuntu setup dhcp", func() {
			networks := boshsettings.Networks{
				"bosh": boshsettings.Network{
					Default: []string{"dns"},
					Dns:     []string{"xx.xx.xx.xx", "yy.yy.yy.yy", "zz.zz.zz.zz"},
				},
				"vip": boshsettings.Network{
					Default: []string{},
					Dns:     []string{"aa.aa.aa.aa"},
				},
			}

			platform.SetupDhcp(networks)

			dhcpConfig := fs.GetFileTestStat("/etc/dhcp3/dhclient.conf")
			Expect(dhcpConfig).ToNot(BeNil())
			Expect(dhcpConfig.StringContents()).To(Equal(UBUNTU_EXPECTED_DHCP_CONFIG))

			Expect(len(cmdRunner.RunCommands)).To(Equal(2))
			Expect(cmdRunner.RunCommands[0]).To(Equal([]string{"pkill", "dhclient3"}))
			Expect(cmdRunner.RunCommands[1]).To(Equal([]string{"/etc/init.d/networking", "restart"}))
		})

		It("ubuntu setup dhcp with pre existing configuration", func() {
			fs.WriteFileString("/etc/dhcp3/dhclient.conf", UBUNTU_EXPECTED_DHCP_CONFIG)
			networks := boshsettings.Networks{
				"bosh": boshsettings.Network{
					Default: []string{"dns"},
					Dns:     []string{"xx.xx.xx.xx", "yy.yy.yy.yy", "zz.zz.zz.zz"},
				},
				"vip": boshsettings.Network{
					Default: []string{},
					Dns:     []string{"aa.aa.aa.aa"},
				},
			}

			platform.SetupDhcp(networks)

			dhcpConfig := fs.GetFileTestStat("/etc/dhcp3/dhclient.conf")
			Expect(dhcpConfig).ToNot(BeNil())
			Expect(dhcpConfig.StringContents()).To(Equal(UBUNTU_EXPECTED_DHCP_CONFIG))

			Expect(len(cmdRunner.RunCommands)).To(Equal(0))
		})

		It("ubuntu setup manual networking", func() {
			networks := boshsettings.Networks{
				"bosh": boshsettings.Network{
					Default: []string{"dns", "gateway"},
					Ip:      "192.168.195.6",
					Netmask: "255.255.255.0",
					Gateway: "192.168.195.1",
					Mac:     "22:00:0a:1f:ac:2a",
					Dns:     []string{"10.80.130.2", "10.80.130.1"},
				},
			}
			fs.WriteFile("/sys/class/net/eth0", []byte{})
			fs.WriteFileString("/sys/class/net/eth0/address", "22:00:0a:1f:ac:2a\n")
			fs.SetGlob("/sys/class/net/*", []string{"/sys/class/net/eth0"})

			platform.SetupManualNetworking(networks)

			networkConfig := fs.GetFileTestStat("/etc/network/interfaces")
			Expect(networkConfig).ToNot(BeNil())
			Expect(networkConfig.StringContents()).To(Equal(UBUNTU_EXPECTED_NETWORK_INTERFACES))

			resolvConf := fs.GetFileTestStat("/etc/resolv.conf")
			Expect(resolvConf).ToNot(BeNil())
			Expect(resolvConf.StringContents()).To(Equal(UBUNTU_EXPECTED_RESOLV_CONF))

			time.Sleep(100 * time.Millisecond)

			Expect(len(cmdRunner.RunCommands)).To(Equal(8))
			Expect(cmdRunner.RunCommands[0]).To(Equal([]string{"service", "network-interface", "stop", "INTERFACE=eth0"}))
			Expect(cmdRunner.RunCommands[1]).To(Equal([]string{"service", "network-interface", "start", "INTERFACE=eth0"}))
			Expect(cmdRunner.RunCommands[2]).To(Equal([]string{"arping", "-c", "1", "-U", "-I", "eth0", "192.168.195.6"}))
			Expect(cmdRunner.RunCommands[7]).To(Equal([]string{"arping", "-c", "1", "-U", "-I", "eth0", "192.168.195.6"}))
		})

	})
}
<commit_msg>formatting<commit_after>package platform_test

import (
	"time"

	. "github.com/onsi/ginkgo"
	. "github.com/onsi/gomega"

	boshlog "bosh/logger"
	. "bosh/platform"
	fakecd "bosh/platform/cdutil/fakes"
	boshcmd "bosh/platform/commands"
	fakedisk "bosh/platform/disk/fakes"
	boshnet "bosh/platform/net"
	fakestats "bosh/platform/stats/fakes"
	boshvitals "bosh/platform/vitals"
	boshsettings "bosh/settings"
	boshdirs "bosh/settings/directories"
	fakesys "bosh/system/fakes"
)

const UBUNTU_EXPECTED_NETWORK_INTERFACES = `auto lo
iface lo inet loopback

auto eth0
iface eth0 inet static
    address 192.168.195.6
    network 192.168.195.0
    netmask 255.255.255.0
    broadcast 192.168.195.255
    gateway 192.168.195.1`

const UBUNTU_EXPECTED_RESOLV_CONF = `nameserver 10.80.130.1
nameserver 10.80.130.2
`

func init() {
	const UBUNTU_EXPECTED_DHCP_CONFIG = `# Generated by bosh-agent

option rfc3442-classless-static-routes code 121 = array of unsigned integer 8;

send host-name "<hostname>";

request subnet-mask, broadcast-address, time-offset, routers,
	domain-name, domain-name-servers, domain-search, host-name,
	netbios-name-servers, netbios-scope, interface-mtu,
	rfc3442-classless-static-routes, ntp-servers;

prepend domain-name-servers zz.zz.zz.zz;
prepend domain-name-servers yy.yy.yy.yy;
prepend domain-name-servers xx.xx.xx.xx;
`

	Describe("Testing with Ginkgo", func() {
		var (
			collector       *fakestats.FakeStatsCollector
			fs              *fakesys.FakeFileSystem
			cmdRunner       *fakesys.FakeCmdRunner
			diskManager     *fakedisk.FakeDiskManager
			dirProvider     boshdirs.DirectoriesProvider
			diskWaitTimeout time.Duration
			platform        Platform
			cdutil          *fakecd.FakeCdUtil
			compressor      boshcmd.Compressor
			copier          boshcmd.Copier
			vitalsService   boshvitals.Service
			logger          boshlog.Logger
		)

		BeforeEach(func() {
			collector = &fakestats.FakeStatsCollector{}
			fs = fakesys.NewFakeFileSystem()
			cmdRunner = fakesys.NewFakeCmdRunner()
			diskManager = fakedisk.NewFakeDiskManager()
			dirProvider = boshdirs.NewDirectoriesProvider("/fake-dir")
			diskWaitTimeout = 1 * time.Millisecond
			cdutil = fakecd.NewFakeCdUtil()
			compressor = boshcmd.NewTarballCompressor(cmdRunner, fs)
			copier = boshcmd.NewCpCopier(cmdRunner, fs)
			vitalsService = boshvitals.NewService(collector, dirProvider)
			logger = boshlog.NewLogger(boshlog.LEVEL_NONE)
		})

		JustBeforeEach(func() {
			netManager := boshnet.NewUbuntuNetManager(fs, cmdRunner, 1*time.Millisecond)

			platform = NewLinuxPlatform(
				fs,
				cmdRunner,
				collector,
				compressor,
				copier,
				dirProvider,
				vitalsService,
				cdutil,
				diskManager,
				netManager,
				1*time.Millisecond,
				logger,
			)
		})

		Describe("SetupDhcp", func() {
			Context("when dhcp was not previously configured", func() {
				It("sets up dhcp and restarts dhclient", func() {
					networks := boshsettings.Networks{
						"bosh": boshsettings.Network{
							Default: []string{"dns"},
							Dns:     []string{"xx.xx.xx.xx", "yy.yy.yy.yy", "zz.zz.zz.zz"},
						},
						"vip": boshsettings.Network{
							Default: []string{},
							Dns:     []string{"aa.aa.aa.aa"},
						},
					}

					platform.SetupDhcp(networks)

					dhcpConfig := fs.GetFileTestStat("/etc/dhcp3/dhclient.conf")
					Expect(dhcpConfig).ToNot(BeNil())
					Expect(dhcpConfig.StringContents()).To(Equal(UBUNTU_EXPECTED_DHCP_CONFIG))

					Expect(len(cmdRunner.RunCommands)).To(Equal(2))
					Expect(cmdRunner.RunCommands[0]).To(Equal([]string{"pkill", "dhclient3"}))
					Expect(cmdRunner.RunCommands[1]).To(Equal([]string{"/etc/init.d/networking", "restart"}))
				})
			})

			Context("when dhcp was previously configured with different configuration", func() {
				It("sets up dhcp and restarts dhclient", func() {
					fs.WriteFileString("/etc/dhcp3/dhclient.conf", "fake-other-configuration")

					networks := boshsettings.Networks{
						"bosh": boshsettings.Network{
							Default: []string{"dns"},
							Dns:     []string{"xx.xx.xx.xx", "yy.yy.yy.yy", "zz.zz.zz.zz"},
						},
						"vip": boshsettings.Network{
							Default: []string{},
							Dns:     []string{"aa.aa.aa.aa"},
						},
					}

					platform.SetupDhcp(networks)

					dhcpConfig := fs.GetFileTestStat("/etc/dhcp3/dhclient.conf")
					Expect(dhcpConfig).ToNot(BeNil())
					Expect(dhcpConfig.StringContents()).To(Equal(UBUNTU_EXPECTED_DHCP_CONFIG))

					Expect(len(cmdRunner.RunCommands)).To(Equal(2))
					Expect(cmdRunner.RunCommands[0]).To(Equal([]string{"pkill", "dhclient3"}))
					Expect(cmdRunner.RunCommands[1]).To(Equal([]string{"/etc/init.d/networking", "restart"}))
				})
			})

			Context("when dhcp was previously configured with the same configuration", func() {
				It("does not restart dhclient", func() {
					fs.WriteFileString("/etc/dhcp3/dhclient.conf", UBUNTU_EXPECTED_DHCP_CONFIG)

					networks := boshsettings.Networks{
						"bosh": boshsettings.Network{
							Default: []string{"dns"},
							Dns:     []string{"xx.xx.xx.xx", "yy.yy.yy.yy", "zz.zz.zz.zz"},
						},
						"vip": boshsettings.Network{
							Default: []string{},
							Dns:     []string{"aa.aa.aa.aa"},
						},
					}

					platform.SetupDhcp(networks)

					dhcpConfig := fs.GetFileTestStat("/etc/dhcp3/dhclient.conf")
					Expect(dhcpConfig).ToNot(BeNil())
					Expect(dhcpConfig.StringContents()).To(Equal(UBUNTU_EXPECTED_DHCP_CONFIG))

					Expect(len(cmdRunner.RunCommands)).To(Equal(0))
				})
			})
		})

		Describe("SetupManualNetworking", func() {
			It("sets up interface and restarts networking", func() {
				networks := boshsettings.Networks{
					"bosh": boshsettings.Network{
						Default: []string{"dns", "gateway"},
						Ip:      "192.168.195.6",
						Netmask: "255.255.255.0",
						Gateway: "192.168.195.1",
						Mac:     "22:00:0a:1f:ac:2a",
						Dns:     []string{"10.80.130.2", "10.80.130.1"},
					},
				}
				fs.WriteFile("/sys/class/net/eth0", []byte{})
				fs.WriteFileString("/sys/class/net/eth0/address", "22:00:0a:1f:ac:2a\n")
				fs.SetGlob("/sys/class/net/*", []string{"/sys/class/net/eth0"})

				platform.SetupManualNetworking(networks)

				networkConfig := fs.GetFileTestStat("/etc/network/interfaces")
				Expect(networkConfig).ToNot(BeNil())
				Expect(networkConfig.StringContents()).To(Equal(UBUNTU_EXPECTED_NETWORK_INTERFACES))

				resolvConf := fs.GetFileTestStat("/etc/resolv.conf")
				Expect(resolvConf).ToNot(BeNil())
				Expect(resolvConf.StringContents()).To(Equal(UBUNTU_EXPECTED_RESOLV_CONF))

				time.Sleep(100 * time.Millisecond)

				Expect(len(cmdRunner.RunCommands)).To(Equal(8))
				Expect(cmdRunner.RunCommands[0]).To(Equal([]string{"service", "network-interface", "stop", "INTERFACE=eth0"}))
				Expect(cmdRunner.RunCommands[1]).To(Equal([]string{"service", "network-interface", "start", "INTERFACE=eth0"}))
				Expect(cmdRunner.RunCommands[2]).To(Equal([]string{"arping", "-c", "1", "-U", "-I", "eth0", "192.168.195.6"}))
				Expect(cmdRunner.RunCommands[7]).To(Equal([]string{"arping", "-c", "1", "-U", "-I", "eth0", "192.168.195.6"}))
			})
		})
	})
}
<|endoftext|>


<commit_before>// ----------------------------------------------------------------------------
//
//     ***     AUTO GENERATED CODE    ***    AUTO GENERATED CODE     ***
//
// ----------------------------------------------------------------------------
//
//     This file is automatically generated by Magic Modules and manual
//     changes will be clobbered when the file is regenerated.
//
//     Please read more about how to change this file in
//     .github/CONTRIBUTING.md.
//
// ----------------------------------------------------------------------------

package google

import (
	"fmt"
	"log"
	"reflect"
	"strings"

	"github.com/hashicorp/terraform/helper/schema"
)

func resourceContainerAnalysisNote() *schema.Resource {
	return &schema.Resource{
		Create: resourceContainerAnalysisNoteCreate,
		Read:   resourceContainerAnalysisNoteRead,
		Update: resourceContainerAnalysisNoteUpdate,
		Delete: resourceContainerAnalysisNoteDelete,

		Importer: &schema.ResourceImporter{
			State: resourceContainerAnalysisNoteImport,
		},

		Schema: map[string]*schema.Schema{
			"attestation_authority": {
				Type:     schema.TypeList,
				Required: true,
				MaxItems: 1,
				Elem: &schema.Resource{
					Schema: map[string]*schema.Schema{
						"hint": {
							Type:     schema.TypeList,
							Required: true,
							MaxItems: 1,
							Elem: &schema.Resource{
								Schema: map[string]*schema.Schema{
									"human_readable_name": {
										Type:     schema.TypeString,
										Required: true,
									},
								},
							},
						},
					},
				},
			},
			"name": {
				Type:     schema.TypeString,
				Required: true,
				ForceNew: true,
			},
			"project": {
				Type:     schema.TypeString,
				Optional: true,
				Computed: true,
				ForceNew: true,
			},
		},
	}
}

func resourceContainerAnalysisNoteCreate(d *schema.ResourceData, meta interface{}) error {
	config := meta.(*Config)

	obj := make(map[string]interface{})
	nameProp, err := expandContainerAnalysisNoteName(d.Get("name"), d, config)
	if err != nil {
		return err
	} else if v, ok := d.GetOkExists("name"); !isEmptyValue(reflect.ValueOf(nameProp)) && (ok || !reflect.DeepEqual(v, nameProp)) {
		obj["name"] = nameProp
	}
	attestationAuthorityProp, err := expandContainerAnalysisNoteAttestationAuthority(d.Get("attestation_authority"), d, config)
	if err != nil {
		return err
	} else if v, ok := d.GetOkExists("attestation_authority"); !isEmptyValue(reflect.ValueOf(attestationAuthorityProp)) && (ok || !reflect.DeepEqual(v, attestationAuthorityProp)) {
		obj["attestationAuthority"] = attestationAuthorityProp
	}

	url, err := replaceVars(d, config, "https://containeranalysis.googleapis.com/v1alpha1/projects/{{project}}/notes?noteId={{name}}")
	if err != nil {
		return err
	}

	log.Printf("[DEBUG] Creating new Note: %#v", obj)
	res, err := sendRequest(config, "POST", url, obj)
	if err != nil {
		return fmt.Errorf("Error creating Note: %s", err)
	}

	// Store the ID now
	id, err := replaceVars(d, config, "{{name}}")
	if err != nil {
		return fmt.Errorf("Error constructing id: %s", err)
	}
	d.SetId(id)

	log.Printf("[DEBUG] Finished creating Note %q: %#v", d.Id(), res)

	return resourceContainerAnalysisNoteRead(d, meta)
}

func resourceContainerAnalysisNoteRead(d *schema.ResourceData, meta interface{}) error {
	config := meta.(*Config)

	url, err := replaceVars(d, config, "https://containeranalysis.googleapis.com/v1alpha1/projects/{{project}}/notes/{{name}}")
	if err != nil {
		return err
	}

	res, err := sendRequest(config, "GET", url, nil)
	if err != nil {
		return handleNotFoundError(err, d, fmt.Sprintf("ContainerAnalysisNote %q", d.Id()))
	}

	if err := d.Set("name", flattenContainerAnalysisNoteName(res["name"])); err != nil {
		return fmt.Errorf("Error reading Note: %s", err)
	}
	if err := d.Set("attestation_authority", flattenContainerAnalysisNoteAttestationAuthority(res["attestationAuthority"])); err != nil {
		return fmt.Errorf("Error reading Note: %s", err)
	}
	project, err := getProject(d, config)
	if err != nil {
		return err
	}
	if err := d.Set("project", project); err != nil {
		return fmt.Errorf("Error reading Note: %s", err)
	}

	return nil
}

func resourceContainerAnalysisNoteUpdate(d *schema.ResourceData, meta interface{}) error {
	config := meta.(*Config)

	obj := make(map[string]interface{})
	nameProp, err := expandContainerAnalysisNoteName(d.Get("name"), d, config)
	if err != nil {
		return err
	} else if v, ok := d.GetOkExists("name"); !isEmptyValue(reflect.ValueOf(v)) && (ok || !reflect.DeepEqual(v, nameProp)) {
		obj["name"] = nameProp
	}
	attestationAuthorityProp, err := expandContainerAnalysisNoteAttestationAuthority(d.Get("attestation_authority"), d, config)
	if err != nil {
		return err
	} else if v, ok := d.GetOkExists("attestation_authority"); !isEmptyValue(reflect.ValueOf(v)) && (ok || !reflect.DeepEqual(v, attestationAuthorityProp)) {
		obj["attestationAuthority"] = attestationAuthorityProp
	}

	url, err := replaceVars(d, config, "https://containeranalysis.googleapis.com/v1alpha1/projects/{{project}}/notes/{{name}}")
	if err != nil {
		return err
	}

	log.Printf("[DEBUG] Updating Note %q: %#v", d.Id(), obj)
	updateMask := []string{}
	if d.HasChange("attestation_authority.0.hint.0.human_readable_name") {
		updateMask = append(updateMask, "attestationAuthority.hint.humanReadableName")
	}
	// updateMask is a URL parameter but not present in the schema, so replaceVars
	// won't set it
	url, err = addQueryParams(url, map[string]string{"updateMask": strings.Join(updateMask, ",")})
	if err != nil {
		return err
	}
	_, err = sendRequest(config, "PATCH", url, obj)

	if err != nil {
		return fmt.Errorf("Error updating Note %q: %s", d.Id(), err)
	}

	return resourceContainerAnalysisNoteRead(d, meta)
}

func resourceContainerAnalysisNoteDelete(d *schema.ResourceData, meta interface{}) error {
	config := meta.(*Config)

	url, err := replaceVars(d, config, "https://containeranalysis.googleapis.com/v1alpha1/projects/{{project}}/notes/{{name}}")
	if err != nil {
		return err
	}

	var obj map[string]interface{}
	log.Printf("[DEBUG] Deleting Note %q", d.Id())
	res, err := sendRequest(config, "DELETE", url, obj)
	if err != nil {
		return handleNotFoundError(err, d, "Note")
	}

	log.Printf("[DEBUG] Finished deleting Note %q: %#v", d.Id(), res)
	return nil
}

func resourceContainerAnalysisNoteImport(d *schema.ResourceData, meta interface{}) ([]*schema.ResourceData, error) {
	config := meta.(*Config)
	parseImportId([]string{"projects/(?P<project>[^/]+)/notes/(?P<name>[^/]+)", "(?P<project>[^/]+)/(?P<name>[^/]+)", "(?P<name>[^/]+)"}, d, config)

	// Replace import id for the resource id
	id, err := replaceVars(d, config, "{{name}}")
	if err != nil {
		return nil, fmt.Errorf("Error constructing id: %s", err)
	}
	d.SetId(id)

	return []*schema.ResourceData{d}, nil
}

func flattenContainerAnalysisNoteName(v interface{}) interface{} {
	if v == nil {
		return v
	}
	return NameFromSelfLinkStateFunc(v)
}

func flattenContainerAnalysisNoteAttestationAuthority(v interface{}) interface{} {
	if v == nil {
		return nil
	}
	original := v.(map[string]interface{})
	transformed := make(map[string]interface{})
	transformed["hint"] =
		flattenContainerAnalysisNoteAttestationAuthorityHint(original["hint"])
	return []interface{}{transformed}
}
func flattenContainerAnalysisNoteAttestationAuthorityHint(v interface{}) interface{} {
	if v == nil {
		return nil
	}
	original := v.(map[string]interface{})
	transformed := make(map[string]interface{})
	transformed["human_readable_name"] =
		flattenContainerAnalysisNoteAttestationAuthorityHintHumanReadableName(original["humanReadableName"])
	return []interface{}{transformed}
}
func flattenContainerAnalysisNoteAttestationAuthorityHintHumanReadableName(v interface{}) interface{} {
	return v
}

func expandContainerAnalysisNoteName(v interface{}, d *schema.ResourceData, config *Config) (interface{}, error) {
	return v, nil
}

func expandContainerAnalysisNoteAttestationAuthority(v interface{}, d *schema.ResourceData, config *Config) (interface{}, error) {
	l := v.([]interface{})
	if len(l) == 0 {
		return nil, nil
	}
	raw := l[0]
	original := raw.(map[string]interface{})
	transformed := make(map[string]interface{})

	transformedHint, err := expandContainerAnalysisNoteAttestationAuthorityHint(original["hint"], d, config)
	if err != nil {
		return nil, err
	} else if val := reflect.ValueOf(transformedHint); val.IsValid() && !isEmptyValue(val) {
		transformed["hint"] = transformedHint
	}

	return transformed, nil
}

func expandContainerAnalysisNoteAttestationAuthorityHint(v interface{}, d *schema.ResourceData, config *Config) (interface{}, error) {
	l := v.([]interface{})
	if len(l) == 0 {
		return nil, nil
	}
	raw := l[0]
	original := raw.(map[string]interface{})
	transformed := make(map[string]interface{})

	transformedHumanReadableName, err := expandContainerAnalysisNoteAttestationAuthorityHintHumanReadableName(original["human_readable_name"], d, config)
	if err != nil {
		return nil, err
	} else if val := reflect.ValueOf(transformedHumanReadableName); val.IsValid() && !isEmptyValue(val) {
		transformed["humanReadableName"] = transformedHumanReadableName
	}

	return transformed, nil
}

func expandContainerAnalysisNoteAttestationAuthorityHintHumanReadableName(v interface{}, d *schema.ResourceData, config *Config) (interface{}, error) {
	return v, nil
}
<commit_msg>use beta api for container analysis (#2135)<commit_after>// ----------------------------------------------------------------------------
//
//     ***     AUTO GENERATED CODE    ***    AUTO GENERATED CODE     ***
//
// ----------------------------------------------------------------------------
//
//     This file is automatically generated by Magic Modules and manual
//     changes will be clobbered when the file is regenerated.
//
//     Please read more about how to change this file in
//     .github/CONTRIBUTING.md.
//
// ----------------------------------------------------------------------------

package google

import (
	"fmt"
	"log"
	"reflect"
	"strings"

	"github.com/hashicorp/terraform/helper/schema"
)

func resourceContainerAnalysisNote() *schema.Resource {
	return &schema.Resource{
		Create: resourceContainerAnalysisNoteCreate,
		Read:   resourceContainerAnalysisNoteRead,
		Update: resourceContainerAnalysisNoteUpdate,
		Delete: resourceContainerAnalysisNoteDelete,

		Importer: &schema.ResourceImporter{
			State: resourceContainerAnalysisNoteImport,
		},

		Schema: map[string]*schema.Schema{
			"attestation_authority": {
				Type:     schema.TypeList,
				Required: true,
				MaxItems: 1,
				Elem: &schema.Resource{
					Schema: map[string]*schema.Schema{
						"hint": {
							Type:     schema.TypeList,
							Required: true,
							MaxItems: 1,
							Elem: &schema.Resource{
								Schema: map[string]*schema.Schema{
									"human_readable_name": {
										Type:     schema.TypeString,
										Required: true,
									},
								},
							},
						},
					},
				},
			},
			"name": {
				Type:     schema.TypeString,
				Required: true,
				ForceNew: true,
			},
			"project": {
				Type:     schema.TypeString,
				Optional: true,
				Computed: true,
				ForceNew: true,
			},
		},
	}
}

func resourceContainerAnalysisNoteCreate(d *schema.ResourceData, meta interface{}) error {
	config := meta.(*Config)

	obj := make(map[string]interface{})
	nameProp, err := expandContainerAnalysisNoteName(d.Get("name"), d, config)
	if err != nil {
		return err
	} else if v, ok := d.GetOkExists("name"); !isEmptyValue(reflect.ValueOf(nameProp)) && (ok || !reflect.DeepEqual(v, nameProp)) {
		obj["name"] = nameProp
	}
	attestationAuthorityProp, err := expandContainerAnalysisNoteAttestationAuthority(d.Get("attestation_authority"), d, config)
	if err != nil {
		return err
	} else if v, ok := d.GetOkExists("attestation_authority"); !isEmptyValue(reflect.ValueOf(attestationAuthorityProp)) && (ok || !reflect.DeepEqual(v, attestationAuthorityProp)) {
		obj["attestationAuthority"] = attestationAuthorityProp
	}

	url, err := replaceVars(d, config, "https://containeranalysis.googleapis.com/v1beta1/projects/{{project}}/notes?noteId={{name}}")
	if err != nil {
		return err
	}

	log.Printf("[DEBUG] Creating new Note: %#v", obj)
	res, err := sendRequest(config, "POST", url, obj)
	if err != nil {
		return fmt.Errorf("Error creating Note: %s", err)
	}

	// Store the ID now
	id, err := replaceVars(d, config, "{{name}}")
	if err != nil {
		return fmt.Errorf("Error constructing id: %s", err)
	}
	d.SetId(id)

	log.Printf("[DEBUG] Finished creating Note %q: %#v", d.Id(), res)

	return resourceContainerAnalysisNoteRead(d, meta)
}

func resourceContainerAnalysisNoteRead(d *schema.ResourceData, meta interface{}) error {
	config := meta.(*Config)

	url, err := replaceVars(d, config, "https://containeranalysis.googleapis.com/v1beta1/projects/{{project}}/notes/{{name}}")
	if err != nil {
		return err
	}

	res, err := sendRequest(config, "GET", url, nil)
	if err != nil {
		return handleNotFoundError(err, d, fmt.Sprintf("ContainerAnalysisNote %q", d.Id()))
	}

	if err := d.Set("name", flattenContainerAnalysisNoteName(res["name"])); err != nil {
		return fmt.Errorf("Error reading Note: %s", err)
	}
	if err := d.Set("attestation_authority", flattenContainerAnalysisNoteAttestationAuthority(res["attestationAuthority"])); err != nil {
		return fmt.Errorf("Error reading Note: %s", err)
	}
	project, err := getProject(d, config)
	if err != nil {
		return err
	}
	if err := d.Set("project", project); err != nil {
		return fmt.Errorf("Error reading Note: %s", err)
	}

	return nil
}

func resourceContainerAnalysisNoteUpdate(d *schema.ResourceData, meta interface{}) error {
	config := meta.(*Config)

	obj := make(map[string]interface{})
	nameProp, err := expandContainerAnalysisNoteName(d.Get("name"), d, config)
	if err != nil {
		return err
	} else if v, ok := d.GetOkExists("name"); !isEmptyValue(reflect.ValueOf(v)) && (ok || !reflect.DeepEqual(v, nameProp)) {
		obj["name"] = nameProp
	}
	attestationAuthorityProp, err := expandContainerAnalysisNoteAttestationAuthority(d.Get("attestation_authority"), d, config)
	if err != nil {
		return err
	} else if v, ok := d.GetOkExists("attestation_authority"); !isEmptyValue(reflect.ValueOf(v)) && (ok || !reflect.DeepEqual(v, attestationAuthorityProp)) {
		obj["attestationAuthority"] = attestationAuthorityProp
	}

	url, err := replaceVars(d, config, "https://containeranalysis.googleapis.com/v1beta1/projects/{{project}}/notes/{{name}}")
	if err != nil {
		return err
	}

	log.Printf("[DEBUG] Updating Note %q: %#v", d.Id(), obj)
	updateMask := []string{}
	if d.HasChange("attestation_authority.0.hint.0.human_readable_name") {
		updateMask = append(updateMask, "attestationAuthority.hint.humanReadableName")
	}
	// updateMask is a URL parameter but not present in the schema, so replaceVars
	// won't set it
	url, err = addQueryParams(url, map[string]string{"updateMask": strings.Join(updateMask, ",")})
	if err != nil {
		return err
	}
	_, err = sendRequest(config, "PATCH", url, obj)

	if err != nil {
		return fmt.Errorf("Error updating Note %q: %s", d.Id(), err)
	}

	return resourceContainerAnalysisNoteRead(d, meta)
}

func resourceContainerAnalysisNoteDelete(d *schema.ResourceData, meta interface{}) error {
	config := meta.(*Config)

	url, err := replaceVars(d, config, "https://containeranalysis.googleapis.com/v1beta1/projects/{{project}}/notes/{{name}}")
	if err != nil {
		return err
	}

	var obj map[string]interface{}
	log.Printf("[DEBUG] Deleting Note %q", d.Id())
	res, err := sendRequest(config, "DELETE", url, obj)
	if err != nil {
		return handleNotFoundError(err, d, "Note")
	}

	log.Printf("[DEBUG] Finished deleting Note %q: %#v", d.Id(), res)
	return nil
}

func resourceContainerAnalysisNoteImport(d *schema.ResourceData, meta interface{}) ([]*schema.ResourceData, error) {
	config := meta.(*Config)
	parseImportId([]string{"projects/(?P<project>[^/]+)/notes/(?P<name>[^/]+)", "(?P<project>[^/]+)/(?P<name>[^/]+)", "(?P<name>[^/]+)"}, d, config)

	// Replace import id for the resource id
	id, err := replaceVars(d, config, "{{name}}")
	if err != nil {
		return nil, fmt.Errorf("Error constructing id: %s", err)
	}
	d.SetId(id)

	return []*schema.ResourceData{d}, nil
}

func flattenContainerAnalysisNoteName(v interface{}) interface{} {
	if v == nil {
		return v
	}
	return NameFromSelfLinkStateFunc(v)
}

func flattenContainerAnalysisNoteAttestationAuthority(v interface{}) interface{} {
	if v == nil {
		return nil
	}
	original := v.(map[string]interface{})
	transformed := make(map[string]interface{})
	transformed["hint"] =
		flattenContainerAnalysisNoteAttestationAuthorityHint(original["hint"])
	return []interface{}{transformed}
}
func flattenContainerAnalysisNoteAttestationAuthorityHint(v interface{}) interface{} {
	if v == nil {
		return nil
	}
	original := v.(map[string]interface{})
	transformed := make(map[string]interface{})
	transformed["human_readable_name"] =
		flattenContainerAnalysisNoteAttestationAuthorityHintHumanReadableName(original["humanReadableName"])
	return []interface{}{transformed}
}
func flattenContainerAnalysisNoteAttestationAuthorityHintHumanReadableName(v interface{}) interface{} {
	return v
}

func expandContainerAnalysisNoteName(v interface{}, d *schema.ResourceData, config *Config) (interface{}, error) {
	return v, nil
}

func expandContainerAnalysisNoteAttestationAuthority(v interface{}, d *schema.ResourceData, config *Config) (interface{}, error) {
	l := v.([]interface{})
	if len(l) == 0 {
		return nil, nil
	}
	raw := l[0]
	original := raw.(map[string]interface{})
	transformed := make(map[string]interface{})

	transformedHint, err := expandContainerAnalysisNoteAttestationAuthorityHint(original["hint"], d, config)
	if err != nil {
		return nil, err
	} else if val := reflect.ValueOf(transformedHint); val.IsValid() && !isEmptyValue(val) {
		transformed["hint"] = transformedHint
	}

	return transformed, nil
}

func expandContainerAnalysisNoteAttestationAuthorityHint(v interface{}, d *schema.ResourceData, config *Config) (interface{}, error) {
	l := v.([]interface{})
	if len(l) == 0 {
		return nil, nil
	}
	raw := l[0]
	original := raw.(map[string]interface{})
	transformed := make(map[string]interface{})

	transformedHumanReadableName, err := expandContainerAnalysisNoteAttestationAuthorityHintHumanReadableName(original["human_readable_name"], d, config)
	if err != nil {
		return nil, err
	} else if val := reflect.ValueOf(transformedHumanReadableName); val.IsValid() && !isEmptyValue(val) {
		transformed["humanReadableName"] = transformedHumanReadableName
	}

	return transformed, nil
}

func expandContainerAnalysisNoteAttestationAuthorityHintHumanReadableName(v interface{}, d *schema.ResourceData, config *Config) (interface{}, error) {
	return v, nil
}
<|endoftext|>


<commit_before>// +build ignore

package main

import (
	"archive/zip"
	"bytes"
	"fmt"
	"io"
	"io/ioutil"
	"log"
	"net/http"
	"os"
	"path"
	"path/filepath"
	"strings"

	"github.com/PuerkitoBio/goquery"
)

func main() {
	site := "https://www.sqlite.org/download.html"
	fmt.Printf("scraping %v\n", site)
	doc, err := goquery.NewDocument(site)
	if err != nil {
		log.Fatal(err)
	}
	var url string
	doc.Find("a").Each(func(_ int, s *goquery.Selection) {
		if url == "" && strings.HasPrefix(s.Text(), "sqlite-amalgamation-") {
			url = "https://www.sqlite.org/2017/" + s.Text()
		}
	})
	if url == "" {
		return
	}
	fmt.Printf("downloading %v\n", url)
	resp, err := http.Get(url)
	if err != nil {
		log.Fatal(err)
	}

	b, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		resp.Body.Close()
		log.Fatal(err)
	}

	fmt.Printf("extracting %v\n", path.Base(url))
	r, err := zip.NewReader(bytes.NewReader(b), resp.ContentLength)
	if err != nil {
		resp.Body.Close()
		log.Fatal(err)
	}
	resp.Body.Close()

	for _, zf := range r.File {
		var f *os.File
		switch path.Base(zf.Name) {
		case "sqlite3.c":
			f, err = os.Create("sqlite3-binding.c")
		case "sqlite3.h":
			f, err = os.Create("sqlite3-binding.h")
		case "sqlite3ext.h":
			f, err = os.Create("sqlite3ext.h")
		default:
			continue
		}
		if err != nil {
			log.Fatal(err)
		}
		zr, err := zf.Open()
		if err != nil {
			log.Fatal(err)
		}

		_, err = io.WriteString(f, "#ifndef USE_LIBSQLITE3\n")
		if err != nil {
			zr.Close()
			f.Close()
			log.Fatal(err)
		}
		_, err = io.Copy(f, zr)
		if err != nil {
			zr.Close()
			f.Close()
			log.Fatal(err)
		}
		_, err = io.WriteString(f, "#else // USE_LIBSQLITE3\n // If users really want to link against the system sqlite3 we\n// need to make this file a noop.\n #endif")
		if err != nil {
			zr.Close()
			f.Close()
			log.Fatal(err)
		}
		zr.Close()
		f.Close()
		fmt.Printf("extracted %v\n", filepath.Base(f.Name()))
	}
}
<commit_msg>replace header name<commit_after>// +build ignore

package main

import (
	"archive/zip"
	"bufio"
	"bytes"
	"fmt"
	"io"
	"io/ioutil"
	"log"
	"net/http"
	"os"
	"path"
	"path/filepath"
	"strings"

	"github.com/PuerkitoBio/goquery"
)

func main() {
	site := "https://www.sqlite.org/download.html"
	fmt.Printf("scraping %v\n", site)
	doc, err := goquery.NewDocument(site)
	if err != nil {
		log.Fatal(err)
	}
	var url string
	doc.Find("a").Each(func(_ int, s *goquery.Selection) {
		if url == "" && strings.HasPrefix(s.Text(), "sqlite-amalgamation-") {
			url = "https://www.sqlite.org/2017/" + s.Text()
		}
	})
	if url == "" {
		return
	}
	fmt.Printf("downloading %v\n", url)
	resp, err := http.Get(url)
	if err != nil {
		log.Fatal(err)
	}

	b, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		resp.Body.Close()
		log.Fatal(err)
	}

	fmt.Printf("extracting %v\n", path.Base(url))
	r, err := zip.NewReader(bytes.NewReader(b), resp.ContentLength)
	if err != nil {
		resp.Body.Close()
		log.Fatal(err)
	}
	resp.Body.Close()

	for _, zf := range r.File {
		var f *os.File
		switch path.Base(zf.Name) {
		case "sqlite3.c":
			f, err = os.Create("sqlite3-binding.c")
		case "sqlite3.h":
			f, err = os.Create("sqlite3-binding.h")
		case "sqlite3ext.h":
			f, err = os.Create("sqlite3ext.h")
		default:
			continue
		}
		if err != nil {
			log.Fatal(err)
		}
		zr, err := zf.Open()
		if err != nil {
			log.Fatal(err)
		}

		_, err = io.WriteString(f, "#ifndef USE_LIBSQLITE3\n")
		if err != nil {
			zr.Close()
			f.Close()
			log.Fatal(err)
		}
		scanner := bufio.NewScanner(zr)
		for scanner.Scan() {
			text := scanner.Text()
			if text == `#include "sqlite3.h"` {
				text = `#include "sqlite3-binding.h"`
			}
			_, err = fmt.Fprintln(f, text)
			if err != nil {
				break
			}
		}
		err = scanner.Err()
		if err != nil {
			zr.Close()
			f.Close()
			log.Fatal(err)
		}
		_, err = io.WriteString(f, "#else // USE_LIBSQLITE3\n // If users really want to link against the system sqlite3 we\n// need to make this file a noop.\n #endif")
		if err != nil {
			zr.Close()
			f.Close()
			log.Fatal(err)
		}
		zr.Close()
		f.Close()
		fmt.Printf("extracted %v\n", filepath.Base(f.Name()))
	}
}
<|endoftext|>