<commit_before>package main

// This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. If a copy of the MPL was not distributed with this file, You can obtain one at https://mozilla.org/MPL/2.0/.

import (
	"crypto/md5"
	"fmt"
	"io/ioutil"
	"net/http"
	"net/http/httptest"
	"path"
	"strings"
	"testing"
)

var startingHash = "2ccc62d64502f9e7f1231c5b228136d3ee0fa72c"
var firstGitserveMD5 = "0566ec561947146909cf40192cda39ec"
var firstTaggedGitserveMD5 = "bc01be1e5c1fbdbe31ac89ae8fb154cd"
var nestedFileMD5 = "d8e8fca2dc0f896fd7cb4cb0031ba249"

func TestDisplayingObject(t *testing.T) {
	firstCommit, err := getObject(startingHash, "prefix", "gitserve.go")

	firstCommitMD5 := fmt.Sprintf("%x", md5.Sum(firstCommit))

	if err != nil {
		t.Error(err)
	}
	if firstCommitMD5 != firstGitserveMD5 {
		t.Errorf("%s came back- not %s\n", firstCommitMD5, firstGitserveMD5)
	}
}

func TestGetHumanNames(t *testing.T) {
	// `git show-ref` is going to be the source of this data
	// take off the leading 'refs/', and use the rest as the list of object sources
	// means the data source can be fed via `git fetch` (shows up under 'remotes')
	// or `git push` (data shows up under 'heads'). As long as the user is consistent,
	// and there's an interface to list refs, everything should be pretty reasonable,
	// though it's less concise, than, say, github's url structure (they can cheat &
	// require `git push`)
	var refs []string
	refs, err := getRefs()
	if err != nil {
		t.Error(err)
	}

	// Check that existing tags exist
	// Check that remotes/origin/master exists
	// This *is* a little dependent on where you get this from,
	// so maybe I should build a little dedicated demo submodule ...
	var rootedTag, zeroethTag, remoteMasterBranch bool = false, false, false
	for _, ref := range refs {
		if ref == "remotes/origin/master" {
			remoteMasterBranch = true
		} else if ref == "tags/0.0.0.0.1" {
			zeroethTag = true
		} else if ref == "tags/rooted/tags/are/tricky" {
			rootedTag = true
		}
	}
	if !rootedTag {
		t.Error("didn't find tags/rooted/tags/are/tricky")
	} else if !zeroethTag {
		t.Error("didn't find tags/0.0.0.0.1")
	} else if !remoteMasterBranch {
		t.Error("didn't find remotes/origin/master- this can be checkout dependent, sorry for the flaky test")
	}
}

func TestDisplayingMissingObject(t *testing.T) {
	firstCommit, err := getObject(startingHash, "prefix", "quack")

	if err == nil {
		t.Error("This should be an error- this is not a legit file")
	}
	if firstCommit != nil {
		t.Errorf("What are you doing returning content here? '%q'", firstCommit)
	}
}

func TestDisplayingBadRoot(t *testing.T) {
	firstCommit, err := getObject("invalid_hash", "prefix", "gitserve.go")

	if err == nil {
		t.Error("This should be an error- this is not a legit hash")
	}
	if firstCommit != nil {
		t.Errorf("What are you doing returning content here? '%q'", firstCommit)
	}
}

func TestPickLongestRef(t *testing.T) {
	for _, testCase := range []struct {
		Path        string
		CorrectRef  string
		CorrectPath string
		Refs        []string
	}{
		{"master/Makefile", "heads/master", "Makefile", []string{"heads/master", "tags/1.7"}},
	} {
		ref, path, err := pickLongestRef(testCase.Path, testCase.Refs)
		if ref != testCase.CorrectRef || path != testCase.CorrectPath {
			t.Log("ref", ref, "path", path)
			t.Errorf("Could not match /blob/%s against ref '%s'", testCase.Path, testCase.CorrectRef)
		} else if err != nil {
			t.Error("Threw an error (%s) inappropriately picking %s out of %q", err, ref, path)
		}
	}

	ref, path, err := pickLongestRef("master/Makefile", []string{"heads/master", "tags/1.7"})
	if ref != "heads/master" || path != "Makefile" {
		t.Log("ref", ref, "path", path)
		t.Error("Could not match /blob/master/Makefile against ref 'master'")
	} else if err != nil {
		t.Error("Threw an error inappropriately picking foo out of ['heads/master', 'tags/1.7']")
	}

	ref, path, err = pickLongestRef("foo", []string{"foo", "bar", "baz"})
	if ref != "foo" || path != "" {
		t.Log("ref", ref, "path", path)
		t.Error("Could not match /blob/foo against ref 'foo'")
	} else if err != nil {
		t.Error("Threw an error inappropriately picking foo out of ['foo','bar','baz']")
	}

	ref, path, err = pickLongestRef("foo/baz.txt", []string{"foo", "bar", "baz"})
	if ref != "foo" || path != "baz.txt" {
		t.Log("ref", ref, "path", path)
		t.Error("Could not match /blob/foo/baz.txt against ref 'foo'")
	} else if err != nil {
		t.Error("Threw an error inappropriately with file name")
	}

	ref, path, err = pickLongestRef("tags/can/have/slashes/baz.txt", []string{"tags/can/have/slashes", "tags/can", "tags"})
	if ref != "tags/can/have/slashes" || path != "baz.txt" {
		t.Log("ref", ref, "path", path)
		t.Error("Could not match /blob/tags/can/have/slashes/baz.txt")
	} else if err != nil {
		t.Error("Threw an error inappropriately with a nested ref")
	}

	ref, path, err = pickLongestRef("do/not/eat/everything/baz.txt", []string{"do", "not", "eat"})
	if ref != "do" || path != "not/eat/everything/baz.txt" {
		t.Log("ref", ref, "path", path)
		t.Error("Could not match /blob/do/not/eat/everything/baz.txt to 'do'")
	} else if err != nil {
		t.Error("Threw an error inappropriately with a non-greedy match")
	}
}

func TestPathRsplit(t *testing.T) {
	for _, testCase := range []struct {
		Path, OutputA, OutputB string
	}{
		{"foo", "foo", ""},
		{"/foo", "foo", ""},
		{"foo/", "foo", ""},
		{"", "", ""},
		{"/", "", ""},
		{"/foo/bar/baz", "foo", "bar/baz"},
		{"foo/bar/baz", "foo", "bar/baz"},
	} {
		root, branch := pathRsplit(testCase.Path)
		if root != testCase.OutputA {
			t.Error("root", root, "does not match", testCase.OutputA, "from", testCase.Path)
		}
		if branch != testCase.OutputB {
			t.Error("branch", branch, "does not match", testCase.OutputB, "from", testCase.Path)
		}
	}
}

func TestHttpTreeApi(t *testing.T) {
	// If you go to http://server:port/blob/master, you might hope to get a file
	// listing instead of a 404
	for _, tc := range []struct {
		Blob, Path      string
		ExpectedEntries []string
	}{
		// XXX FIXME Check branch name root too
		{"rooted/tags/may/confuse", "/", []string{"gitserve.go", "gitserve_test.go"}},
		{"2ccc6", "/", []string{"gitserve.go"}},
		{"82fcd77642", "/a", []string{"b"}},
		{"82fcd77642", "/a/", []string{"blob/82fcd77642/a/b"}},
		{"82fcd77642", "/a/b", []string{"c/"}},
		{"82fcd77642", "/a/b/c/", []string{"testfile"}},
	} {
		req, err := http.NewRequest("GET", path.Join("/blob/", tc.Blob, tc.Path), nil)
		if err != nil {
			t.Fatal("Test request failed", err)
		}
		w := httptest.NewRecorder()
		servePath(w, req)

		listing := w.Body.String()
		t.Log(path.Join("/blob/", tc.Blob, tc.Path))
		for _, entry := range tc.ExpectedEntries {
			if !strings.Contains(listing, entry) {
				t.Fatal("Output not what we expected- missing ", entry, " from ", tc.Path, " @ ", tc.Blob, "got:\n", textSample(listing))
			}
		}
	}
}

func textSample(incoming string) string {
	if len(incoming) > 200 {
		return incoming[0:200]
	}
	return incoming
}

func TestHttpBlobApi(t *testing.T) {
	// branches & tags can't start or end with a '/', which is a blessing
	// probably should dump a list of all branches & tags, do a 'startswith'
	// on the incoming string, and if it matches up inside of '/'s, then use that.

	for _, tc := range []struct {
		BlobName,
		BlobMd5,
		Path string
	}{
		{startingHash, firstGitserveMD5, "gitserve.go"},           // Easy case is definitely "no slashes allowed"
		{"tags/0.0.0.0.1", firstTaggedGitserveMD5, "gitserve.go"}, // Let's try it with a human-readable name
		{"82fcd77642ac584c7debd8709b48d799d7b9fa33", nestedFileMD5, "a/b/c/testfile"},
	} {
		url := path.Join("/blob/", tc.BlobName, tc.Path)
		t.Log(url)
		req, err := http.NewRequest("GET", url, nil)
		if err != nil {
			t.Error("Test request failed", err)
		}
		w := httptest.NewRecorder()
		servePath(w, req)
		if w.Code != 200 {
			t.Error(w.Code, w.Body.String())
		}
		outputHash := fmt.Sprintf("%x", md5.Sum([]byte(w.Body.String())))
		if outputHash != tc.BlobMd5 {
			t.Log(fmt.Sprintf("failed: %q", w.Body.String()))
			ioutil.WriteFile("/tmp/failed", []byte(w.Body.String()), 0644)
			t.Error("Output not what we expected- check ", tc.Path, "\n\nand hashes ", outputHash, " vs ", tc.BlobMd5, " bad output sample:\n", textSample(w.Body.String()))
		}
		t.Log("-=-=-=-==-==-=-=-=-=-=-==-==-=-==-=-")
	}
}
<commit_msg>Convert TestPickLongestRef 100% to table based testing<commit_after>package main

// This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. If a copy of the MPL was not distributed with this file, You can obtain one at https://mozilla.org/MPL/2.0/.

import (
	"crypto/md5"
	"fmt"
	"io/ioutil"
	"net/http"
	"net/http/httptest"
	"path"
	"strings"
	"testing"
)

var startingHash = "2ccc62d64502f9e7f1231c5b228136d3ee0fa72c"
var firstGitserveMD5 = "0566ec561947146909cf40192cda39ec"
var firstTaggedGitserveMD5 = "bc01be1e5c1fbdbe31ac89ae8fb154cd"
var nestedFileMD5 = "d8e8fca2dc0f896fd7cb4cb0031ba249"

func TestDisplayingObject(t *testing.T) {
	firstCommit, err := getObject(startingHash, "prefix", "gitserve.go")

	firstCommitMD5 := fmt.Sprintf("%x", md5.Sum(firstCommit))

	if err != nil {
		t.Error(err)
	}
	if firstCommitMD5 != firstGitserveMD5 {
		t.Errorf("%s came back- not %s\n", firstCommitMD5, firstGitserveMD5)
	}
}

func TestGetHumanNames(t *testing.T) {
	// `git show-ref` is going to be the source of this data
	// take off the leading 'refs/', and use the rest as the list of object sources
	// means the data source can be fed via `git fetch` (shows up under 'remotes')
	// or `git push` (data shows up under 'heads'). As long as the user is consistent,
	// and there's an interface to list refs, everything should be pretty reasonable,
	// though it's less concise, than, say, github's url structure (they can cheat &
	// require `git push`)
	var refs []string
	refs, err := getRefs()
	if err != nil {
		t.Error(err)
	}

	// Check that existing tags exist
	// Check that remotes/origin/master exists
	// This *is* a little dependent on where you get this from,
	// so maybe I should build a little dedicated demo submodule ...
	var rootedTag, zeroethTag, remoteMasterBranch bool = false, false, false
	for _, ref := range refs {
		if ref == "remotes/origin/master" {
			remoteMasterBranch = true
		} else if ref == "tags/0.0.0.0.1" {
			zeroethTag = true
		} else if ref == "tags/rooted/tags/are/tricky" {
			rootedTag = true
		}
	}
	if !rootedTag {
		t.Error("didn't find tags/rooted/tags/are/tricky")
	} else if !zeroethTag {
		t.Error("didn't find tags/0.0.0.0.1")
	} else if !remoteMasterBranch {
		t.Error("didn't find remotes/origin/master- this can be checkout dependent, sorry for the flaky test")
	}
}

func TestDisplayingMissingObject(t *testing.T) {
	firstCommit, err := getObject(startingHash, "prefix", "quack")

	if err == nil {
		t.Error("This should be an error- this is not a legit file")
	}
	if firstCommit != nil {
		t.Errorf("What are you doing returning content here? '%q'", firstCommit)
	}
}

func TestDisplayingBadRoot(t *testing.T) {
	firstCommit, err := getObject("invalid_hash", "prefix", "gitserve.go")

	if err == nil {
		t.Error("This should be an error- this is not a legit hash")
	}
	if firstCommit != nil {
		t.Errorf("What are you doing returning content here? '%q'", firstCommit)
	}
}

func TestPickLongestRef(t *testing.T) {
	for _, testCase := range []struct {
		Path        string
		CorrectRef  string
		CorrectPath string
		Refs        []string
	}{
		{"master/Makefile", "heads/master", "Makefile", []string{"heads/master", "tags/1.7"}},
		{"foo", "foo", "", []string{"foo", "bar", "baz"}},
		{"foo/baz.txt", "foo", "baz.txt", []string{"foo", "bar", "baz"}},
		{"tags/can/have/slashes/baz.txt", "tags/can/have/slashes", "baz.txt", []string{"tags/can/have/slashes", "tags/can", "tags"}},
		{"do/not/eat/everything/baz.txt", "do", "not/eat/everything/baz.txt", []string{"do", "not", "eat"}},
	} {
		ref, path, err := pickLongestRef(testCase.Path, testCase.Refs)
		if ref != testCase.CorrectRef || path != testCase.CorrectPath {
			t.Log("ref", ref, "path", path)
			t.Errorf("Could not match /blob/%s against ref '%s'", testCase.Path, testCase.CorrectRef)
		} else if err != nil {
			t.Error("Threw an error (%s) inappropriately picking %s out of %q", err, ref, path)
		}
	}
}

func TestPathRsplit(t *testing.T) {
	for _, testCase := range []struct {
		Path, OutputA, OutputB string
	}{
		{"foo", "foo", ""},
		{"/foo", "foo", ""},
		{"foo/", "foo", ""},
		{"", "", ""},
		{"/", "", ""},
		{"/foo/bar/baz", "foo", "bar/baz"},
		{"foo/bar/baz", "foo", "bar/baz"},
	} {
		root, branch := pathRsplit(testCase.Path)
		if root != testCase.OutputA {
			t.Error("root", root, "does not match", testCase.OutputA, "from", testCase.Path)
		}
		if branch != testCase.OutputB {
			t.Error("branch", branch, "does not match", testCase.OutputB, "from", testCase.Path)
		}
	}
}

func TestHttpTreeApi(t *testing.T) {
	// If you go to http://server:port/blob/master, you might hope to get a file
	// listing instead of a 404
	for _, tc := range []struct {
		Blob, Path      string
		ExpectedEntries []string
	}{
		// XXX FIXME Check branch name root too
		{"rooted/tags/may/confuse", "/", []string{"gitserve.go", "gitserve_test.go"}},
		{"2ccc6", "/", []string{"gitserve.go"}},
		{"82fcd77642", "/a", []string{"b"}},
		{"82fcd77642", "/a/", []string{"blob/82fcd77642/a/b"}},
		{"82fcd77642", "/a/b", []string{"c/"}},
		{"82fcd77642", "/a/b/c/", []string{"testfile"}},
	} {
		req, err := http.NewRequest("GET", path.Join("/blob/", tc.Blob, tc.Path), nil)
		if err != nil {
			t.Fatal("Test request failed", err)
		}
		w := httptest.NewRecorder()
		servePath(w, req)

		listing := w.Body.String()
		t.Log(path.Join("/blob/", tc.Blob, tc.Path))
		for _, entry := range tc.ExpectedEntries {
			if !strings.Contains(listing, entry) {
				t.Fatal("Output not what we expected- missing ", entry, " from ", tc.Path, " @ ", tc.Blob, "got:\n", textSample(listing))
			}
		}
	}
}

func textSample(incoming string) string {
	if len(incoming) > 200 {
		return incoming[0:200]
	}
	return incoming
}

func TestHttpBlobApi(t *testing.T) {
	// branches & tags can't start or end with a '/', which is a blessing
	// probably should dump a list of all branches & tags, do a 'startswith'
	// on the incoming string, and if it matches up inside of '/'s, then use that.

	for _, tc := range []struct {
		BlobName,
		BlobMd5,
		Path string
	}{
		{startingHash, firstGitserveMD5, "gitserve.go"},           // Easy case is definitely "no slashes allowed"
		{"tags/0.0.0.0.1", firstTaggedGitserveMD5, "gitserve.go"}, // Let's try it with a human-readable name
		{"82fcd77642ac584c7debd8709b48d799d7b9fa33", nestedFileMD5, "a/b/c/testfile"},
	} {
		url := path.Join("/blob/", tc.BlobName, tc.Path)
		t.Log(url)
		req, err := http.NewRequest("GET", url, nil)
		if err != nil {
			t.Error("Test request failed", err)
		}
		w := httptest.NewRecorder()
		servePath(w, req)
		if w.Code != 200 {
			t.Error(w.Code, w.Body.String())
		}
		outputHash := fmt.Sprintf("%x", md5.Sum([]byte(w.Body.String())))
		if outputHash != tc.BlobMd5 {
			t.Log(fmt.Sprintf("failed: %q", w.Body.String()))
			ioutil.WriteFile("/tmp/failed", []byte(w.Body.String()), 0644)
			t.Error("Output not what we expected- check ", tc.Path, "\n\nand hashes ", outputHash, " vs ", tc.BlobMd5, " bad output sample:\n", textSample(w.Body.String()))
		}
		t.Log("-=-=-=-==-==-=-=-=-=-=-==-==-=-==-=-")
	}
}
<|endoftext|>


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

import (
	"github.com/megamsys/libgo/db"
	"crypto/rand"
    "math/big"
    "strings"
    "errors"
	log "code.google.com/p/log4go"
)

type Message struct {
	Id string `json:"id"`
}

type EventMessage struct {
	AssemblyId     string 	`json:"assembly_id"`
	ComponentId    string 	`json:"component_id"`
	Event          string 	`json:"event"`
}

type PredefClouds struct {
	Id          string     `json:"id"`
	Name        string     `json:"name"`
	Accounts_id string     `json:"accounts_id"`
	Jsonclaz    string     `json:"json_claz"`
	Spec        *PDCSpec   `json:"spec"`
	Access      *PDCAccess `json:"access"`
	Ideal       string     `json:"ideal"`
	CreatedAT   string     `json:"created_at"`
	Performance string     `json:"performance"`
}

type PDCSpec struct {
	TypeName string `json:"type_name"`
	Groups   string `json:"groups"`
	Image    string `json:"image"`
	Flavor   string `json:"flavor"`
	TenantID string `json:"tenant_id"`
}

type PDCAccess struct {
	Sshkey         string `json:"ssh_key"`
	IdentityFile   string `json:"identity_file"`
	Sshuser        string `json:"ssh_user"`
	VaultLocation  string `json:"vault_location"`
	SshpubLocation string `json:"sshpub_location"`
	Zone           string `json:"zone"`
	Region         string `json:"region"`
}

type Request struct {
	Id	             string     `json:"id"`
	AssembliesId     string     `json:"node_id"`
	AssembliesName   string     `json:"node_name"`
	ReqType          string     `json:"req_type"`
	CreatedAt        string     `json:"created_at"`
}

/**
**fetch the request json from riak and parse the json to struct
**/
func (req *Request) Get(reqId string) (*Request, error) {
    log.Info("Get Request message %v", reqId)
    conn, err := db.Conn("requests")
	if err != nil {
		return req, err
	}
	//appout := &Requests{}
	ferr := conn.FetchStruct(reqId, req)
	if ferr != nil {
		return req, ferr
	}
	defer conn.Close()

	return req, nil

}

type KeyValuePair struct {
	Key     string   `json:"key"`
	Value   string   `json:"value"`
}

type Policy struct {
	Name    string   `json:"name"`
	Ptype   string   `json:"ptype"`
	Members []string `json:"members"`
}

type Operations struct {
	OperationType 				string 				`json:"operation_type"`
	Description 				string				`json:"description"`
	OperationRequirements		[]*KeyValuePair		`json:"operation_requirements"`
}

type Artifacts struct {
	ArtifactType 			string 			`json:"artifact_type"`
	Content     		 	string 			`json:"content"`
	ArtifactRequirements  	[]*KeyValuePair	`json:"artifact_requirements"`
}

type Component struct {
	Id                         string 				`json:"id"`
	Name                       string 				`json:"name"`
	ToscaType                  string 				`json:"tosca_type"`
	Inputs                     []*KeyValuePair		`json:"inputs"`
	Outputs					   []*KeyValuePair		`json:"outputs"`
	Artifacts                  *Artifacts			`json:"artifacts"`
	RelatedComponents          []string				`json:"related_components"`
	Operations     			   []*Operations    	`json:"operations"`
	Status         			   string    			`json:"status"`
	CreatedAt                  string 				`json:"created_at"`
}

/**
**fetch the component json from riak and parse the json to struct
**/
func (asm *Component) Get(asmId string) (*Component, error) {
    log.Info("Get Component message %v", asmId)
    conn, err := db.Conn("components")
	if err != nil {
		return asm, err
	}
	//appout := &Requests{}
	ferr := conn.FetchStruct(asmId, asm)
	if ferr != nil {
		return asm, ferr
	}
	defer conn.Close()

	return asm, nil

}

type Assemblies struct {
   Id             string  	    	`json:"id"`
   AccountsId     string    		`json:"accounts_id"`
   JsonClaz       string   			`json:"json_claz"`
   Name           string   			`json:"name"`
   Assemblies     []string   		`json:"assemblies"`
   Inputs         []*KeyValuePair   `json:"inputs"`
   CreatedAt      string   			`json:"created_at"`
   }

 func (asm *Assemblies) Get(asmId string) (*Assemblies, error) {
    log.Info("Get Assemblies message %v", asmId)
    conn, err := db.Conn("assemblies")
	if err != nil {
		return asm, err
	}
	//appout := &Requests{}
	ferr := conn.FetchStruct(asmId, asm)
	if ferr != nil {
		return asm, ferr
	}
	defer conn.Close()
	log.Debug(asm)
	log.Debug("----------ASSEMBLIES--------")
	return asm, nil

}

type Assembly struct {
   Id             string   	 		`json:"id"`
   JsonClaz       string   			`json:"json_claz"`
   Name           string   			`json:"name"`
   ToscaType      string        	`json:"tosca_type"`
   Components     []string   		`json:"components"`
   Requirements	  []*KeyValuePair	`json:"requirements"`
   Policies       []*Policy  		`json:"policies"`
   Inputs         []*KeyValuePair   `json:"inputs"`
   Operations     []*Operations    	`json:"operations"`
   Outputs        []*KeyValuePair  	`json:"outputs"`
   Status         string    		`json:"status"`
   CreatedAt      string   			`json:"created_at"`
   }

type AssemblyWithComponents struct {
	Id         		string 				`json:"id"`
	Name       		string 				`json:"name"`
	ToscaType  		string          	`json:tosca_type"`
	Components 		[]*Component
	Requirements	[]*KeyValuePair		`json:"requirements"`
    Policies        []*Policy  			`json:"policies"`
    Inputs          []*KeyValuePair   	`json:"inputs"`
    Operations      []*Operations    	`json:"operations"`
    Outputs         []*KeyValuePair  	`json:"outputs"`
    Status          string    			`json:"status"`
    Command         string
    CreatedAt       string   			`json:"created_at"`
}

/**
**fetch the Assembly data from riak and parse the json to struct
**/
func (req *Assembly) Get(reqId string) (*Assembly, error) {
    log.Info("Get Assembly message %v", reqId)
    conn, err := db.Conn("assembly")
	if err != nil {
		return req, err
	}
	//appout := &Requests{}
	ferr := conn.FetchStruct(reqId, req)
	if ferr != nil {
		return req, ferr
	}
	defer conn.Close()

	return req, nil

}

func (asm *Assembly) GetAssemblyWithComponents(asmId string) (*AssemblyWithComponents, error) {
    log.Info("Get Assembly message %v", asmId)
    var j = -1
    asmresult := &AssemblyWithComponents{}
	conn, err := db.Conn("assembly")
	if err != nil {
		return asmresult, err
	}
	//appout := &Requests{}
	ferr := conn.FetchStruct(asmId, asm)
	if ferr != nil {
		return asmresult, ferr
	}
	var arraycomponent = make([]*Component, len(asm.Components))
	for i := range asm.Components {
		 t := strings.TrimSpace(asm.Components[i])
		if len(t) > 1  {
		  componentID := asm.Components[i]
		  component := Component{Id: componentID }
          com, err := component.Get(componentID)
		  if err != nil {
		       log.Error("Error: Riak didn't cooperate:\n%s.", err)
		       return asmresult, err
		  }
	      j++
		  arraycomponent[j] = com
		  }
	    }
	log.Info("else entry")
	result := &AssemblyWithComponents{Id: asm.Id, Name: asm.Name, ToscaType: asm.ToscaType,  Components: arraycomponent, Requirements: asm.Requirements, Policies: asm.Policies, Inputs: asm.Inputs, Outputs: asm.Outputs, Operations: asm.Operations, Status: asm.Status, CreatedAt: asm.CreatedAt}
	defer conn.Close()
	return result, nil
}

func ParseKeyValuePair(keyvaluepair []*KeyValuePair, searchkey string) (*KeyValuePair, error) {
 	for i := range keyvaluepair {
		if keyvaluepair[i].Key == searchkey {
			return keyvaluepair[i], nil
		}
	}
	return nil, errors.New("The specific search key was not found in pair input...")
}

/**
generate the rand string
**/
func RandString(n int) string {
    const alphanum = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"
    symbols := big.NewInt(int64(len(alphanum)))
    states := big.NewInt(0)
    states.Exp(symbols, big.NewInt(int64(n)), nil)
    r, err := rand.Int(rand.Reader, states)
    if err != nil {
        panic(err)
    }
    var bytes = make([]byte, n)
    r2 := big.NewInt(0)
    symbol := big.NewInt(0)
    for i := range bytes {
        r2.DivMod(r, symbols, symbol)
        r, r2 = r2, r
        bytes[i] = alphanum[symbol.Int64()]
    }
    return string(bytes)
}

<commit_msg>changed catrequests json fields<commit_after>/*
** Copyright [2013-2015] [Megam Systems]
**
** Licensed under the Apache License, Version 2.0 (the "License");
** you may not use this file except in compliance with the License.
** You may obtain a copy of the License at
**
** http://www.apache.org/licenses/LICENSE-2.0
**
** Unless required by applicable law or agreed to in writing, software
** distributed under the License is distributed on an "AS IS" BASIS,
** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
** See the License for the specific language governing permissions and
** limitations under the License.
*/
package global

import (
	"github.com/megamsys/libgo/db"
	"crypto/rand"
    "math/big"
    "strings"
    "errors"
	log "code.google.com/p/log4go"
)

type Message struct {
	Id string `json:"id"`
}

type EventMessage struct {
	AssemblyId     string 	`json:"assembly_id"`
	ComponentId    string 	`json:"component_id"`
	Event          string 	`json:"event"`
}

type PredefClouds struct {
	Id          string     `json:"id"`
	Name        string     `json:"name"`
	Accounts_id string     `json:"accounts_id"`
	Jsonclaz    string     `json:"json_claz"`
	Spec        *PDCSpec   `json:"spec"`
	Access      *PDCAccess `json:"access"`
	Ideal       string     `json:"ideal"`
	CreatedAT   string     `json:"created_at"`
	Performance string     `json:"performance"`
}

type PDCSpec struct {
	TypeName string `json:"type_name"`
	Groups   string `json:"groups"`
	Image    string `json:"image"`
	Flavor   string `json:"flavor"`
	TenantID string `json:"tenant_id"`
}

type PDCAccess struct {
	Sshkey         string `json:"ssh_key"`
	IdentityFile   string `json:"identity_file"`
	Sshuser        string `json:"ssh_user"`
	VaultLocation  string `json:"vault_location"`
	SshpubLocation string `json:"sshpub_location"`
	Zone           string `json:"zone"`
	Region         string `json:"region"`
}

type Request struct {
	Id	             string     `json:"id"`
	AssembliesId     string     `json:"cat_id"`
	AssembliesName   string     `json:"name"`
	ReqType          string     `json:"cattype"`
	CreatedAt        string     `json:"created_at"`
}

/**
**fetch the request json from riak and parse the json to struct
**/
func (req *Request) Get(reqId string) (*Request, error) {
    log.Info("Get Request message %v", reqId)
    conn, err := db.Conn("requests")
	if err != nil {
		return req, err
	}
	//appout := &Requests{}
	ferr := conn.FetchStruct(reqId, req)
	if ferr != nil {
		return req, ferr
	}
	defer conn.Close()

	return req, nil

}

type KeyValuePair struct {
	Key     string   `json:"key"`
	Value   string   `json:"value"`
}

type Policy struct {
	Name    string   `json:"name"`
	Ptype   string   `json:"ptype"`
	Members []string `json:"members"`
}

type Operations struct {
	OperationType 				string 				`json:"operation_type"`
	Description 				string				`json:"description"`
	OperationRequirements		[]*KeyValuePair		`json:"operation_requirements"`
}

type Artifacts struct {
	ArtifactType 			string 			`json:"artifact_type"`
	Content     		 	string 			`json:"content"`
	ArtifactRequirements  	[]*KeyValuePair	`json:"artifact_requirements"`
}

type Component struct {
	Id                         string 				`json:"id"`
	Name                       string 				`json:"name"`
	ToscaType                  string 				`json:"tosca_type"`
	Inputs                     []*KeyValuePair		`json:"inputs"`
	Outputs					   []*KeyValuePair		`json:"outputs"`
	Artifacts                  *Artifacts			`json:"artifacts"`
	RelatedComponents          []string				`json:"related_components"`
	Operations     			   []*Operations    	`json:"operations"`
	Status         			   string    			`json:"status"`
	CreatedAt                  string 				`json:"created_at"`
}

/**
**fetch the component json from riak and parse the json to struct
**/
func (asm *Component) Get(asmId string) (*Component, error) {
    log.Info("Get Component message %v", asmId)
    conn, err := db.Conn("components")
	if err != nil {
		return asm, err
	}
	//appout := &Requests{}
	ferr := conn.FetchStruct(asmId, asm)
	if ferr != nil {
		return asm, ferr
	}
	defer conn.Close()

	return asm, nil

}

type Assemblies struct {
   Id             string  	    	`json:"id"`
   AccountsId     string    		`json:"accounts_id"`
   JsonClaz       string   			`json:"json_claz"`
   Name           string   			`json:"name"`
   Assemblies     []string   		`json:"assemblies"`
   Inputs         []*KeyValuePair   `json:"inputs"`
   CreatedAt      string   			`json:"created_at"`
   }

 func (asm *Assemblies) Get(asmId string) (*Assemblies, error) {
    log.Info("Get Assemblies message %v", asmId)
    conn, err := db.Conn("assemblies")
	if err != nil {
		return asm, err
	}
	//appout := &Requests{}
	ferr := conn.FetchStruct(asmId, asm)
	if ferr != nil {
		return asm, ferr
	}
	defer conn.Close()
	log.Debug(asm)
	log.Debug("----------ASSEMBLIES--------")
	return asm, nil

}

type Assembly struct {
   Id             string   	 		`json:"id"`
   JsonClaz       string   			`json:"json_claz"`
   Name           string   			`json:"name"`
   ToscaType      string        	`json:"tosca_type"`
   Components     []string   		`json:"components"`
   Requirements	  []*KeyValuePair	`json:"requirements"`
   Policies       []*Policy  		`json:"policies"`
   Inputs         []*KeyValuePair   `json:"inputs"`
   Operations     []*Operations    	`json:"operations"`
   Outputs        []*KeyValuePair  	`json:"outputs"`
   Status         string    		`json:"status"`
   CreatedAt      string   			`json:"created_at"`
   }

type AssemblyWithComponents struct {
	Id         		string 				`json:"id"`
	Name       		string 				`json:"name"`
	ToscaType  		string          	`json:tosca_type"`
	Components 		[]*Component
	Requirements	[]*KeyValuePair		`json:"requirements"`
    Policies        []*Policy  			`json:"policies"`
    Inputs          []*KeyValuePair   	`json:"inputs"`
    Operations      []*Operations    	`json:"operations"`
    Outputs         []*KeyValuePair  	`json:"outputs"`
    Status          string    			`json:"status"`
    Command         string
    CreatedAt       string   			`json:"created_at"`
}

/**
**fetch the Assembly data from riak and parse the json to struct
**/
func (req *Assembly) Get(reqId string) (*Assembly, error) {
    log.Info("Get Assembly message %v", reqId)
    conn, err := db.Conn("assembly")
	if err != nil {
		return req, err
	}
	//appout := &Requests{}
	ferr := conn.FetchStruct(reqId, req)
	if ferr != nil {
		return req, ferr
	}
	defer conn.Close()

	return req, nil

}

func (asm *Assembly) GetAssemblyWithComponents(asmId string) (*AssemblyWithComponents, error) {
    log.Info("Get Assembly message %v", asmId)
    var j = -1
    asmresult := &AssemblyWithComponents{}
	conn, err := db.Conn("assembly")
	if err != nil {
		return asmresult, err
	}
	//appout := &Requests{}
	ferr := conn.FetchStruct(asmId, asm)
	if ferr != nil {
		return asmresult, ferr
	}
	var arraycomponent = make([]*Component, len(asm.Components))
	for i := range asm.Components {
		 t := strings.TrimSpace(asm.Components[i])
		if len(t) > 1  {
		  componentID := asm.Components[i]
		  component := Component{Id: componentID }
          com, err := component.Get(componentID)
		  if err != nil {
		       log.Error("Error: Riak didn't cooperate:\n%s.", err)
		       return asmresult, err
		  }
	      j++
		  arraycomponent[j] = com
		  }
	    }
	log.Info("else entry")
	result := &AssemblyWithComponents{Id: asm.Id, Name: asm.Name, ToscaType: asm.ToscaType,  Components: arraycomponent, Requirements: asm.Requirements, Policies: asm.Policies, Inputs: asm.Inputs, Outputs: asm.Outputs, Operations: asm.Operations, Status: asm.Status, CreatedAt: asm.CreatedAt}
	defer conn.Close()
	return result, nil
}

func ParseKeyValuePair(keyvaluepair []*KeyValuePair, searchkey string) (*KeyValuePair, error) {
 	for i := range keyvaluepair {
		if keyvaluepair[i].Key == searchkey {
			return keyvaluepair[i], nil
		}
	}
	return nil, errors.New("The specific search key was not found in pair input...")
}

/**
generate the rand string
**/
func RandString(n int) string {
    const alphanum = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"
    symbols := big.NewInt(int64(len(alphanum)))
    states := big.NewInt(0)
    states.Exp(symbols, big.NewInt(int64(n)), nil)
    r, err := rand.Int(rand.Reader, states)
    if err != nil {
        panic(err)
    }
    var bytes = make([]byte, n)
    r2 := big.NewInt(0)
    symbol := big.NewInt(0)
    for i := range bytes {
        r2.DivMod(r, symbols, symbol)
        r, r2 = r2, r
        bytes[i] = alphanum[symbol.Int64()]
    }
    return string(bytes)
}

<|endoftext|>


<commit_before>package gmail

import (
	"bytes"
	"encoding/base64"
	"errors"
	"mime"
	"text/template"

	gm "google.golang.org/api/gmail/v1"
)

// messageTeplate содержит разобранный и готовый для использования шаблон
// для отправки сообщения по почте.
var messageTeplate = template.Must(
	template.New("").Funcs(template.FuncMap{"qenc": func(name string) string {
		return mime.QEncoding.Encode("utf-8", name)
	}}).Parse(`From: {{qenc .Name}}
Reply-To: {{qenc .Name}} <{{.From}}>
To: {{.To}}
Subject: {{qenc .Subject}}

{{ .Body }}`))

// Message описывает формат сообщения для отправки через GMail.
type Message struct {
	Name    string // имя отправителя
	From    string // e-mail отправителя
	To      string // e-mail получателя
	Subject string // тема сообщения
	Body    string // основное содержимое письма
}

// GetText преобразует сообщения по шаблону в текст и возвращает его.
func (m Message) Bytes() ([]byte, error) {
	var buf bytes.Buffer
	if err := messageTeplate.Execute(&buf, m); err != nil {
		return nil, err // возвращаем ошибку
	}
	return buf.Bytes(), nil // возвращаем получившийся текст
}

// ErrGMailServiceNotInitialized описывает ошибку не инициализированного
// сервиса GMail.
var ErrGMailServiceNotInitialized = errors.New("gmail service not initialized")

// Send отправляет сообщение через GMail.
//
// Перед отправкой необходимо инициализировать сервис, вызвав функцию
// gmail.Init(), которая должна выполняться до старта сервера, потому что может
// потребовать ввода кода ответа при первой инициализации сервиса.
func (m Message) Send() error {
	if gmailService == nil || gmailService.Users == nil {
		return ErrGMailServiceNotInitialized
	}

	text, err := m.Bytes() // получаем текст сформированного сообщения
	if err != nil {
		return err
	}
	// кодируем содержимое сообщения в формат Base64
	body := base64.RawURLEncoding.EncodeToString(text)
	// формируем сообщение в формате GMail
	var gmailMessage = &gm.Message{Raw: body}
	// отправляем сообщение на сервер GMail
	_, err = gmailService.Users.Messages.Send("me", gmailMessage).Do()
	return err // возвращаем статус отправки сообщения

}
<commit_msg>gmail<commit_after>package gmail

import (
	"bytes"
	"encoding/base64"
	"errors"
	"mime"
	"text/template"

	gm "google.golang.org/api/gmail/v1"
)

// messageTeplate содержит разобранный и готовый для использования шаблон
// для отправки сообщения по почте.
var messageTeplate = template.Must(
	template.New("").Funcs(template.FuncMap{"qenc": func(name string) string {
		return mime.QEncoding.Encode("utf-8", name)
	}}).Parse(`From: {{qenc .Name}}
Reply-To: {{qenc .Name}} <{{.From}}>
To: {{.To}}
Subject: {{qenc .Subject}}

{{ .Body }}`))

// Message описывает формат сообщения для отправки через GMail.
type Message struct {
	Name    string // имя отправителя
	From    string // e-mail отправителя
	To      string // e-mail получателя
	Subject string // тема сообщения
	Body    string // основное содержимое письма
}

// GetText преобразует сообщения по шаблону в текст и возвращает его.
func (m Message) Bytes() ([]byte, error) {
	var buf bytes.Buffer
	if err := messageTeplate.Execute(&buf, m); err != nil {
		return nil, err // возвращаем ошибку
	}
	return buf.Bytes(), nil // возвращаем получившийся текст
}

// ErrServiceNotInitialized описывает ошибку не инициализированного
// сервиса GMail.
var ErrServiceNotInitialized = errors.New("gmail service not initialized")

// Send отправляет сообщение через GMail.
//
// Перед отправкой необходимо инициализировать сервис, вызвав функцию
// gmail.Init(), которая должна выполняться до старта сервера, потому что может
// потребовать ввода кода ответа при первой инициализации сервиса.
func (m Message) Send() error {
	if gmailService == nil || gmailService.Users == nil {
		return ErrServiceNotInitialized
	}

	text, err := m.Bytes() // получаем текст сформированного сообщения
	if err != nil {
		return err
	}
	// кодируем содержимое сообщения в формат Base64
	body := base64.RawURLEncoding.EncodeToString(text)
	// формируем сообщение в формате GMail
	var gmailMessage = &gm.Message{Raw: body}
	// отправляем сообщение на сервер GMail
	_, err = gmailService.Users.Messages.Send("me", gmailMessage).Do()
	return err // возвращаем статус отправки сообщения

}
<|endoftext|>


<commit_before>package util

import (
	"fmt"
	"strings"

	"github.com/aryann/difflib"
	"github.com/davecgh/go-spew/spew"
	"github.com/fatih/color"
)

// DebugDump Pretty print a data structure
func DebugDump(obj interface{}) {
	color.Set(color.FgCyan)
	spew.Dump(obj)
	color.Unset()
}

// DebugDumpDiff Pretty print differences between data structures
func DebugDumpDiff(left interface{}, right interface{}) {

	l := strings.Split(spew.Sdump(left), "\n")
	r := strings.Split(spew.Sdump(right), "\n")

	DebugDiffStrings(l, r)
}

//DebugDiffString Diff two strings
func DebugDiffString(l, r string) {
	// If the string contains a newline, then split on newlines first
	if strings.Contains(l, "\n") {
		DebugDiffStrings(strings.Split(l, "\n"), strings.Split(r, "\n"))
	} else {
		DebugDiffStrings([]string{l}, []string{r})
	}
}

// DebugDiffStrings Diff two arrays of strings
func DebugDiffStrings(l, r []string) {

	diffs := difflib.Diff(l, r)

	for _, diff := range diffs {
		var prefix string
		switch diff.Delta {
		case difflib.Common:
			prefix = "    "
			color.Set(color.FgGreen)
		case difflib.LeftOnly:
			prefix = " << "
			color.Set(color.FgRed)
		case difflib.RightOnly:
			prefix = " >> "
			color.Set(color.FgYellow)
		}
		fmtStr := fmt.Sprintf("%s %s", prefix, diff.Payload)
		fmt.Println(fmtStr)
	}
	color.Unset()
}
<commit_msg>Added DebugDumpDiff utility function<commit_after>package util

import (
	"fmt"
	"strings"

	"github.com/aryann/difflib"
	"github.com/davecgh/go-spew/spew"
	"github.com/fatih/color"
)

// DebugDump Pretty print a data structure
func DebugDump(obj interface{}) {
	color.Set(color.FgCyan)
	spew.Dump(obj)
	color.Unset()
}

// DebugDumpDiff Pretty print differences between data structures
func DebugDumpDiff(left interface{}, right interface{}) {

	l := strings.Split(spew.Sdump(left), "\n")
	r := strings.Split(spew.Sdump(right), "\n")

	DebugDiffStrings(l, r)
}

// DebugDumpDiffDetail Pretty print differences between data structures
func DebugDumpDiffDetail(left interface{}, right interface{}, leftTitle, rightTitle string) {

	yellow := color.New(color.FgYellow).SprintFunc()
	red := color.New(color.FgRed).SprintFunc()
	fmt.Printf("\t\t ===  Diff === \n")
	fmt.Printf("\t %s %s\t %s %s\n\n", red("<<<<"), red(leftTitle), yellow(rightTitle), yellow(">>>>"))

	l := strings.Split(spew.Sdump(left), "\n")
	r := strings.Split(spew.Sdump(right), "\n")

	DebugDiffStrings(l, r)
}

//DebugDiffString Diff two strings
func DebugDiffString(l, r string) {
	// If the string contains a newline, then split on newlines first
	if strings.Contains(l, "\n") {
		DebugDiffStrings(strings.Split(l, "\n"), strings.Split(r, "\n"))
	} else {
		DebugDiffStrings([]string{l}, []string{r})
	}
}

// DebugDiffStrings Diff two arrays of strings
func DebugDiffStrings(l, r []string) {

	diffs := difflib.Diff(l, r)

	for _, diff := range diffs {
		var prefix string
		switch diff.Delta {
		case difflib.Common:
			prefix = "    "
			color.Set(color.FgGreen)
		case difflib.LeftOnly:
			prefix = " << "
			color.Set(color.FgRed)
		case difflib.RightOnly:
			prefix = " >> "
			color.Set(color.FgYellow)
		}
		fmtStr := fmt.Sprintf("%s %s", prefix, diff.Payload)
		fmt.Println(fmtStr)
	}
	color.Unset()
}
<|endoftext|>


<commit_before>package main

import {
	"net/http"

	"github.com/russross/backfriday"
}

func main () {
	http.HandleFunc ("/markdown", PrintString)
	http.Handle("/", http.FileServer(http.Dir("public")))
	http.ListenAndServe(":8000", nil)
}

func PrintString (rw http.ResponseWriter, r *http.Request){
	rw.Write ("Hola Mundo!")
}
<commit_msg>Hello world<commit_after>package main

import (
	"net/http"
	"io"
)

func main () {
	http.HandleFunc ("/markdown", PrintString)
	http.Handle("/", http.FileServer(http.Dir("public")))
	http.ListenAndServe(":8000", nil)
}

func PrintString (rw http.ResponseWriter, r *http.Request){
	io.WriteString (rw, "Hola Mundo!\n")
}
<|endoftext|>


<commit_before>package goraptor

import (
	"errors"
	"fmt"
	"log"
	"os"
	"runtime"
	"strings"
	"testing"
	"time"
)

func TestGlobal(t *testing.T) {
	log.Print("[log levels]")
	for level, str := range LogLevels {
		log.Printf("%d - %s", level, str)
	}
	log.Print(" ")
	log.Print("[parser syntax]")
	for _, s := range ParserSyntax {
		log.Print(s)
	}
	log.Print(" ")
	log.Print("[serializer syntax]")
	for _, s := range SerializerSyntax {
		log.Print(s)
	}
	log.Print(" ")
}

func codec(s *Statement) (err error) {
	subj := s.Subject
	pred := s.Predicate
	obj := s.Object

	sbuf, err := subj.GobEncode()
	if err != nil {
		errs := fmt.Sprintf("GobEncode(%s): %s", subj, err)
		err = errors.New(errs)
		return
	}
	pbuf, err := pred.GobEncode()
	if err != nil {
		errs := fmt.Sprintf("GobEncode(%s): %s", pred, err)
		err = errors.New(errs)
		return
	}
	obuf, err := obj.GobEncode()
	if err != nil {
		errs := fmt.Sprintf("GobEncode(%s): %s", obj, err)
		err = errors.New(errs)
		return
	}

	subj2, err := TermDecode(sbuf)
	if err != nil {
		errs := fmt.Sprintf("TermDecode(%s): %s", subj, err)
		err = errors.New(errs)
		return
	}
	pred2, err := TermDecode(pbuf)
	if err != nil {
		errs := fmt.Sprintf("TermDecode(%s): %s", pred, err)
		err = errors.New(errs)
		return
	}
	obj2, err := TermDecode(obuf)
	if err != nil {
		errs := fmt.Sprintf("TermDecode(%s): %s", obj, err)
		err = errors.New(errs)
		return
	}

	if !subj.Equals(subj2) {
		errs := fmt.Sprintf("%s != %s", subj, subj2)
		err = errors.New(errs)
		return
	}
	if !pred.Equals(pred2) {
		errs := fmt.Sprintf("%s != %s", pred, pred2)
		err = errors.New(errs)
		return
	}
	if !obj.Equals(obj2) {
		errs := fmt.Sprintf("%s != %s", obj, obj2)
		err = errors.New(errs)
		return
	}

	s2 := &Statement{subj2, pred2, obj2, nil}
	if !s.Equals(s2) {
		errs := fmt.Sprintf("%s != %s", s, s2)
		err = errors.New(errs)
		return
	}

	ssbuf, err := s.GobEncode()
	if err != nil {
		errs := fmt.Sprintf("Statement.GobEncode(%s): %s", s, err)
		err = errors.New(errs)
		return
	}

	s3 := &Statement{}
	err = s3.GobDecode(ssbuf)
	if err != nil {
		errs := fmt.Sprintf("Statement.GobDecode(%s): %s", s, err)
		err = errors.New(errs)
		return
	}
	if !s.Equals(s3) {
		errs := fmt.Sprintf("%s != %s", s, s3)
		err = errors.New(errs)
		return
	}
	return
}

func TestRaptorParseFile(t *testing.T) {
	parser := NewParser("rdfxml")
	defer parser.Free()

	count := 0
	exp := 153
	out := parser.ParseFile("foaf.rdf", "")
	for {
		s, ok := <-out
		if !ok {
			break
		}
		count++
		err := codec(s)
		if err != nil {
			t.Fatal(err)
		}
	}
	if count != exp {
		t.Errorf("Expected %d statements got %d\n", count, exp)
	}
}

func TestRaptorParseUri(t *testing.T) {
	parser := NewParser("guess")
	defer parser.Free()

	count := 0
	out := parser.ParseUri("http://www.w3.org/People/Berners-Lee/card", "")
	for {
		s, ok := <-out
		if !ok {
			break
		}
		count++
		err := codec(s)
		if err != nil {
			t.Fatal(err)
		}
	}
	if count == 0 {
		t.Errorf("Expected to find some statements... maybe there is no network?")
	}
}

func TestRaptorParseBuf(t *testing.T) {
	turtle := `
@prefix ex: <http://example.org/>.

ex:foo ex:p1 [ ex:bar "hello" ].
_:b1 ex:p2 ex:foo.
`
	parser := NewParser("turtle")
	defer parser.Free()

	count := 0
	for s := range parser.Parse(strings.NewReader(turtle), "http://example.org/") {
		count++
		err := codec(s)
		if err != nil {
			t.Fatal(err)
		}
	}
	if count != 3 {
		t.Errorf("Expected to find three statements")
	}
}

func TestRaptorSerializeFile(t *testing.T) {
	parser := NewParser("rdfxml")
	defer parser.Free()

	serializer := NewSerializer("turtle")
	defer serializer.Free()

	fp, err := os.OpenFile("/dev/null", os.O_WRONLY, 0644)
	if err != nil {
		t.Fatalf("Open(/dev/null): %s", err)
	}
	defer fp.Close()

	err = serializer.SetFile(fp, "")
	if err != nil {
		t.Fatalf("SetFile(%s, \"\"): %s", fp, err)
	}

	statements := parser.ParseFile("foaf.rdf", "")
	serializer.AddN(statements)
}

func TestRaptorSerializeString(t *testing.T) {
	parser := NewParser("rdfxml")
	defer parser.Free()

	serializer := NewSerializer("turtle")
	defer serializer.Free()

	parser.SetNamespaceHandler(func(prefix, uri string) { serializer.SetNamespace(prefix, uri) })

	statements := parser.ParseFile("foaf.rdf", "")
	str, err := serializer.Serialize(statements, "")
	if err != nil {
		t.Fatalf("Serialize(): %s", err)
	}
	if len(str) == 0 {
		t.Errorf("serialize to string failed, got empty string")
	}
	//	log.Print(str)
}

func TestTiger(t *testing.T) {
	parser := NewParser("ntriples")
	ch := parser.ParseFile("TGR06001_sample.nt", "")
	count := 0
	start := time.Now()
	for {
		s, ok := <-ch
		if !ok {
			break
		}
		_ = fmt.Sprintf("%s", s)
		count++
		if count%10000 == 0 {
			end := time.Now()
			dt := uint64(count) * 1e9 / uint64(end.Sub(start))
			log.Printf("%d statements loaded at %d tps", count, dt)
		}
	}
	end := time.Now()
	dt := uint64(count) * 1e9 / uint64(end.Sub(start))
	log.Printf("%d statements loaded at %d tps", count, dt)
}

func benchParse() {
	parser := NewParser("rdfxml")
	out := parser.ParseFile("foaf.rdf", "")
	for {
		s, ok := <-out
		if !ok {
			break
		}
		codec(s)
		_ = s
	}
	parser.Free()
}

func BenchmarkCodecMemory(b *testing.B) {
	m := new(runtime.MemStats)

	for i := 0; i < b.N; i++ {
		runtime.ReadMemStats(m)
		log.Printf("start alloc: %d total: %d heap: %d",
			m.Alloc,
			m.TotalAlloc,
			m.HeapAlloc)
		benchParse()
		Reset()
		runtime.GC()
		runtime.ReadMemStats(m)
		log.Printf("  end alloc: %d total: %d heap: %d",
			m.Alloc,
			m.TotalAlloc,
			m.HeapAlloc)

	}
}
<commit_msg>Print labels for each test.<commit_after>package goraptor

import (
	"errors"
	"fmt"
	"log"
	"os"
	"runtime"
	"strings"
	"testing"
	"time"
)

func TestGlobal(t *testing.T) {
	log.Println("TestGlobal")
	log.Print("[log levels]")
	for level, str := range LogLevels {
		log.Printf("%d - %s", level, str)
	}
	log.Print(" ")
	log.Print("[parser syntax]")
	for _, s := range ParserSyntax {
		log.Print(s)
	}
	log.Print(" ")
	log.Print("[serializer syntax]")
	for _, s := range SerializerSyntax {
		log.Print(s)
	}
	log.Print(" ")
}

func codec(s *Statement) (err error) {
	subj := s.Subject
	pred := s.Predicate
	obj := s.Object

	sbuf, err := subj.GobEncode()
	if err != nil {
		errs := fmt.Sprintf("GobEncode(%s): %s", subj, err)
		err = errors.New(errs)
		return
	}
	pbuf, err := pred.GobEncode()
	if err != nil {
		errs := fmt.Sprintf("GobEncode(%s): %s", pred, err)
		err = errors.New(errs)
		return
	}
	obuf, err := obj.GobEncode()
	if err != nil {
		errs := fmt.Sprintf("GobEncode(%s): %s", obj, err)
		err = errors.New(errs)
		return
	}

	subj2, err := TermDecode(sbuf)
	if err != nil {
		errs := fmt.Sprintf("TermDecode(%s): %s", subj, err)
		err = errors.New(errs)
		return
	}
	pred2, err := TermDecode(pbuf)
	if err != nil {
		errs := fmt.Sprintf("TermDecode(%s): %s", pred, err)
		err = errors.New(errs)
		return
	}
	obj2, err := TermDecode(obuf)
	if err != nil {
		errs := fmt.Sprintf("TermDecode(%s): %s", obj, err)
		err = errors.New(errs)
		return
	}

	if !subj.Equals(subj2) {
		errs := fmt.Sprintf("%s != %s", subj, subj2)
		err = errors.New(errs)
		return
	}
	if !pred.Equals(pred2) {
		errs := fmt.Sprintf("%s != %s", pred, pred2)
		err = errors.New(errs)
		return
	}
	if !obj.Equals(obj2) {
		errs := fmt.Sprintf("%s != %s", obj, obj2)
		err = errors.New(errs)
		return
	}

	s2 := &Statement{subj2, pred2, obj2, nil}
	if !s.Equals(s2) {
		errs := fmt.Sprintf("%s != %s", s, s2)
		err = errors.New(errs)
		return
	}

	ssbuf, err := s.GobEncode()
	if err != nil {
		errs := fmt.Sprintf("Statement.GobEncode(%s): %s", s, err)
		err = errors.New(errs)
		return
	}

	s3 := &Statement{}
	err = s3.GobDecode(ssbuf)
	if err != nil {
		errs := fmt.Sprintf("Statement.GobDecode(%s): %s", s, err)
		err = errors.New(errs)
		return
	}
	if !s.Equals(s3) {
		errs := fmt.Sprintf("%s != %s", s, s3)
		err = errors.New(errs)
		return
	}
	return
}

func TestRaptorParseFile(t *testing.T) {
	log.Println("TestRaptorParseFile")
	parser := NewParser("rdfxml")
	defer parser.Free()

	count := 0
	exp := 153
	out := parser.ParseFile("foaf.rdf", "")
	for {
		s, ok := <-out
		if !ok {
			break
		}
		count++
		err := codec(s)
		if err != nil {
			t.Fatal(err)
		}
	}
	if count != exp {
		t.Errorf("Expected %d statements got %d\n", count, exp)
	}
}

func TestRaptorParseUri(t *testing.T) {
	log.Println("TestRaptorParseUri")
	parser := NewParser("guess")
	defer parser.Free()

	count := 0
	out := parser.ParseUri("http://www.w3.org/People/Berners-Lee/card", "")
	for {
		s, ok := <-out
		if !ok {
			break
		}
		count++
		err := codec(s)
		if err != nil {
			t.Fatal(err)
		}
	}
	if count == 0 {
		t.Errorf("Expected to find some statements... maybe there is no network?")
	}
}

func TestRaptorParseBuf(t *testing.T) {
	log.Println("TestRaptorParseBuf")
	turtle := `
@prefix ex: <http://example.org/>.

ex:foo ex:p1 [ ex:bar "hello" ].
_:b1 ex:p2 ex:foo.
`
	parser := NewParser("turtle")
	defer parser.Free()

	count := 0
	for s := range parser.Parse(strings.NewReader(turtle), "http://example.org/") {
		count++
		err := codec(s)
		if err != nil {
			t.Fatal(err)
		}
	}
	if count != 3 {
		t.Errorf("Expected to find three statements")
	}
}

func TestRaptorSerializeFile(t *testing.T) {
	log.Println("TestRaptorSerializeFile")
	parser := NewParser("rdfxml")
	defer parser.Free()

	serializer := NewSerializer("turtle")
	defer serializer.Free()

	fp, err := os.OpenFile("/dev/null", os.O_WRONLY, 0644)
	if err != nil {
		t.Fatalf("Open(/dev/null): %s", err)
	}
	defer fp.Close()

	err = serializer.SetFile(fp, "")
	if err != nil {
		t.Fatalf("SetFile(%s, \"\"): %s", fp, err)
	}

	statements := parser.ParseFile("foaf.rdf", "")
	serializer.AddN(statements)
}

func TestRaptorSerializeString(t *testing.T) {
	log.Println("TestRaptorSerializeString")
	parser := NewParser("rdfxml")
	defer parser.Free()

	serializer := NewSerializer("turtle")
	defer serializer.Free()

	parser.SetNamespaceHandler(func(prefix, uri string) { serializer.SetNamespace(prefix, uri) })

	statements := parser.ParseFile("foaf.rdf", "")
	str, err := serializer.Serialize(statements, "")
	if err != nil {
		t.Fatalf("Serialize(): %s", err)
	}
	if len(str) == 0 {
		t.Errorf("serialize to string failed, got empty string")
	}
	//	log.Print(str)
}

func TestTiger(t *testing.T) {
	log.Println("TestTiger")
	parser := NewParser("ntriples")
	ch := parser.ParseFile("TGR06001_sample.nt", "")
	count := 0
	start := time.Now()
	for {
		s, ok := <-ch
		if !ok {
			break
		}
		_ = fmt.Sprintf("%s", s)
		count++
		if count%10000 == 0 {
			end := time.Now()
			dt := uint64(count) * 1e9 / uint64(end.Sub(start))
			log.Printf("%d statements loaded at %d tps", count, dt)
		}
	}
	end := time.Now()
	dt := uint64(count) * 1e9 / uint64(end.Sub(start))
	log.Printf("%d statements loaded at %d tps", count, dt)
}

func benchParse() {
	parser := NewParser("rdfxml")
	out := parser.ParseFile("foaf.rdf", "")
	for {
		s, ok := <-out
		if !ok {
			break
		}
		codec(s)
		_ = s
	}
	parser.Free()
}

func BenchmarkCodecMemory(b *testing.B) {
	m := new(runtime.MemStats)

	for i := 0; i < b.N; i++ {
		runtime.ReadMemStats(m)
		log.Printf("start alloc: %d total: %d heap: %d",
			m.Alloc,
			m.TotalAlloc,
			m.HeapAlloc)
		benchParse()
		Reset()
		runtime.GC()
		runtime.ReadMemStats(m)
		log.Printf("  end alloc: %d total: %d heap: %d",
			m.Alloc,
			m.TotalAlloc,
			m.HeapAlloc)

	}
}
<|endoftext|>


<commit_before>// Copyright © 2016 The Things Network
// Use of this source code is governed by the MIT license that can be found in the LICENSE file.

package broker

import (
	"crypto/md5"
	"encoding/hex"
	"fmt"
	"sort"
	"time"

	pb "github.com/TheThingsNetwork/ttn/api/broker"
	pb_discovery "github.com/TheThingsNetwork/ttn/api/discovery"
	"github.com/TheThingsNetwork/ttn/api/gateway"
	"github.com/TheThingsNetwork/ttn/api/networkserver"
	pb_lorawan "github.com/TheThingsNetwork/ttn/api/protocol/lorawan"
	"github.com/TheThingsNetwork/ttn/core/fcnt"
	"github.com/TheThingsNetwork/ttn/core/types"
	"github.com/TheThingsNetwork/ttn/utils/errors"
	"github.com/apex/log"
	"github.com/brocaar/lorawan"
)

const maxFCntGap = 16384

func (b *broker) HandleUplink(uplink *pb.UplinkMessage) error {
	ctx := b.Ctx.WithField("GatewayID", uplink.GatewayMetadata.GatewayId)
	var err error
	start := time.Now()
	defer func() {
		if err != nil {
			ctx.WithError(err).Warn("Could not handle uplink")
		} else {
			ctx.WithField("Duration", time.Now().Sub(start)).Info("Handled uplink")
		}
	}()

	time := time.Now()

	// De-duplicate uplink messages
	duplicates := b.deduplicateUplink(uplink)
	if len(duplicates) == 0 {
		return nil
	}

	base := duplicates[0]

	if base.ProtocolMetadata.GetLorawan() == nil {
		err = errors.NewErrInvalidArgument("Uplink", "does not contain LoRaWAN metadata")
		return err
	}

	// LoRaWAN: Unmarshal
	var phyPayload lorawan.PHYPayload
	err = phyPayload.UnmarshalBinary(base.Payload)
	if err != nil {
		return err
	}
	macPayload, ok := phyPayload.MACPayload.(*lorawan.MACPayload)
	if !ok {
		err = errors.NewErrInvalidArgument("Uplink", "does not contain a MAC payload")
		return err
	}

	// Request devices from NS
	devAddr := types.DevAddr(macPayload.FHDR.DevAddr)
	ctx = ctx.WithField("DevAddr", devAddr)
	var getDevicesResp *networkserver.DevicesResponse
	getDevicesResp, err = b.ns.GetDevices(b.Component.GetContext(b.nsToken), &networkserver.DevicesRequest{
		DevAddr: &devAddr,
		FCnt:    macPayload.FHDR.FCnt,
	})
	if err != nil {
		return errors.BuildGRPCError(errors.Wrap(errors.FromGRPCError(err), "NetworkServer did not return devices"))
	}
	if len(getDevicesResp.Results) == 0 {
		err = errors.NewErrNotFound(fmt.Sprintf("Device with DevAddr %s and FCnt <= %d", devAddr, macPayload.FHDR.FCnt))
		return err
	}
	ctx = ctx.WithField("DevAddrResults", len(getDevicesResp.Results))

	// Sort by FCntUp to optimize the number of MIC checks
	sort.Sort(ByFCntUp(getDevicesResp.Results))

	// Find AppEUI/DevEUI through MIC check
	var device *pb_lorawan.Device
	var micChecks int
	for _, candidate := range getDevicesResp.Results {
		nwkSKey := lorawan.AES128Key(*candidate.NwkSKey)
		if candidate.Uses32BitFCnt {
			macPayload.FHDR.FCnt = fcnt.GetFull(macPayload.FHDR.FCnt, uint16(candidate.FCntUp))
		}
		micChecks++
		ok, err = phyPayload.ValidateMIC(nwkSKey)
		if err != nil {
			return err
		}
		if ok {
			device = candidate
			break
		}
	}
	if device == nil {
		err = errors.NewErrNotFound("device that validates MIC")
		return err
	}
	ctx = ctx.WithFields(log.Fields{
		"MICChecks": micChecks,
		"DevEUI":    device.DevEui,
		"AppEUI":    device.AppEui,
		"AppID":     device.AppId,
		"DevID":     device.DevId,
	})

	if device.DisableFCntCheck {
		// TODO: Add warning to message?
	} else if device.FCntUp == 0 {

	} else if macPayload.FHDR.FCnt <= device.FCntUp || macPayload.FHDR.FCnt-device.FCntUp > maxFCntGap {
		// Replay attack or FCnt gap too big
		err = errors.NewErrNotFound("device with matching FCnt")
		return err
	}

	// Add FCnt to Metadata (because it's not marshaled in lorawan payload)
	base.ProtocolMetadata.GetLorawan().FCnt = macPayload.FHDR.FCnt

	// Collect GatewayMetadata and DownlinkOptions
	var gatewayMetadata []*gateway.RxMetadata
	var downlinkOptions []*pb.DownlinkOption
	var downlinkMessage *pb.DownlinkMessage
	for _, duplicate := range duplicates {
		gatewayMetadata = append(gatewayMetadata, duplicate.GatewayMetadata)
		downlinkOptions = append(downlinkOptions, duplicate.DownlinkOptions...)
	}

	// Select best DownlinkOption
	if len(downlinkOptions) > 0 {
		downlinkMessage = &pb.DownlinkMessage{
			DownlinkOption: selectBestDownlink(downlinkOptions),
		}
	}

	// Build Uplink
	deduplicatedUplink := &pb.DeduplicatedUplinkMessage{
		Payload:          base.Payload,
		DevEui:           device.DevEui,
		DevId:            device.DevId,
		AppEui:           device.AppEui,
		AppId:            device.AppId,
		ProtocolMetadata: base.ProtocolMetadata,
		GatewayMetadata:  gatewayMetadata,
		ServerTime:       time.UnixNano(),
		ResponseTemplate: downlinkMessage,
	}

	// Pass Uplink through NS
	deduplicatedUplink, err = b.ns.Uplink(b.Component.GetContext(b.nsToken), deduplicatedUplink)
	if err != nil {
		return errors.BuildGRPCError(errors.Wrap(errors.FromGRPCError(err), "NetworkServer did not handle uplink"))
	}

	var announcements []*pb_discovery.Announcement
	announcements, err = b.Discovery.GetAllHandlersForAppID(device.AppId)
	if err != nil {
		return err
	}
	if len(announcements) == 0 {
		err = errors.NewErrNotFound(fmt.Sprintf("Handler for AppID %s", device.AppId))
		return err
	}
	if len(announcements) > 1 {
		err = errors.NewErrInternal(fmt.Sprintf("Multiple Handlers for AppID %s", device.AppId))
		return err
	}

	var handler chan<- *pb.DeduplicatedUplinkMessage
	handler, err = b.getHandler(announcements[0].Id)
	if err != nil {
		return err
	}

	handler <- deduplicatedUplink

	return nil
}

func (b *broker) deduplicateUplink(duplicate *pb.UplinkMessage) (uplinks []*pb.UplinkMessage) {
	sum := md5.Sum(duplicate.Payload)
	key := hex.EncodeToString(sum[:])
	list := b.uplinkDeduplicator.Deduplicate(key, duplicate)
	if len(list) == 0 {
		return
	}
	for _, duplicate := range list {
		uplinks = append(uplinks, duplicate.(*pb.UplinkMessage))
	}
	return
}

func selectBestDownlink(options []*pb.DownlinkOption) *pb.DownlinkOption {
	sort.Sort(ByScore(options))
	return options[0]
}

// ByFCntUp implements sort.Interface for []*pb_lorawan.Device based on FCnt
type ByFCntUp []*pb_lorawan.Device

func (a ByFCntUp) Len() int      { return len(a) }
func (a ByFCntUp) Swap(i, j int) { a[i], a[j] = a[j], a[i] }
func (a ByFCntUp) Less(i, j int) bool {
	// Devices that disable the FCnt check have low priority
	if a[i].DisableFCntCheck {
		return 2*int(a[i].FCntUp)+100 < int(a[j].FCntUp)
	}
	return int(a[i].FCntUp) < int(a[j].FCntUp)
}
<commit_msg>Fix #250<commit_after>// Copyright © 2016 The Things Network
// Use of this source code is governed by the MIT license that can be found in the LICENSE file.

package broker

import (
	"crypto/md5"
	"encoding/hex"
	"fmt"
	"sort"
	"time"

	pb "github.com/TheThingsNetwork/ttn/api/broker"
	pb_discovery "github.com/TheThingsNetwork/ttn/api/discovery"
	"github.com/TheThingsNetwork/ttn/api/gateway"
	"github.com/TheThingsNetwork/ttn/api/networkserver"
	pb_lorawan "github.com/TheThingsNetwork/ttn/api/protocol/lorawan"
	"github.com/TheThingsNetwork/ttn/core/fcnt"
	"github.com/TheThingsNetwork/ttn/core/types"
	"github.com/TheThingsNetwork/ttn/utils/errors"
	"github.com/apex/log"
	"github.com/brocaar/lorawan"
)

const maxFCntGap = 16384

func (b *broker) HandleUplink(uplink *pb.UplinkMessage) error {
	ctx := b.Ctx.WithField("GatewayID", uplink.GatewayMetadata.GatewayId)
	var err error
	start := time.Now()
	defer func() {
		if err != nil {
			ctx.WithError(err).Warn("Could not handle uplink")
		} else {
			ctx.WithField("Duration", time.Now().Sub(start)).Info("Handled uplink")
		}
	}()

	time := time.Now()

	// De-duplicate uplink messages
	duplicates := b.deduplicateUplink(uplink)
	if len(duplicates) == 0 {
		return nil
	}

	base := duplicates[0]

	if base.ProtocolMetadata.GetLorawan() == nil {
		err = errors.NewErrInvalidArgument("Uplink", "does not contain LoRaWAN metadata")
		return err
	}

	// LoRaWAN: Unmarshal
	var phyPayload lorawan.PHYPayload
	err = phyPayload.UnmarshalBinary(base.Payload)
	if err != nil {
		return err
	}
	macPayload, ok := phyPayload.MACPayload.(*lorawan.MACPayload)
	if !ok {
		err = errors.NewErrInvalidArgument("Uplink", "does not contain a MAC payload")
		return err
	}

	// Request devices from NS
	devAddr := types.DevAddr(macPayload.FHDR.DevAddr)
	ctx = ctx.WithField("DevAddr", devAddr)
	var getDevicesResp *networkserver.DevicesResponse
	getDevicesResp, err = b.ns.GetDevices(b.Component.GetContext(b.nsToken), &networkserver.DevicesRequest{
		DevAddr: &devAddr,
		FCnt:    macPayload.FHDR.FCnt,
	})
	if err != nil {
		return errors.BuildGRPCError(errors.Wrap(errors.FromGRPCError(err), "NetworkServer did not return devices"))
	}
	if len(getDevicesResp.Results) == 0 {
		err = errors.NewErrNotFound(fmt.Sprintf("Device with DevAddr %s and FCnt <= %d", devAddr, macPayload.FHDR.FCnt))
		return err
	}
	ctx = ctx.WithField("DevAddrResults", len(getDevicesResp.Results))

	// Sort by FCntUp to optimize the number of MIC checks
	sort.Sort(ByFCntUp(getDevicesResp.Results))

	// Find AppEUI/DevEUI through MIC check
	var device *pb_lorawan.Device
	var micChecks int
	for _, candidate := range getDevicesResp.Results {
		nwkSKey := lorawan.AES128Key(*candidate.NwkSKey)
		if candidate.Uses32BitFCnt {
			macPayload.FHDR.FCnt = fcnt.GetFull(candidate.FCntUp, uint16(macPayload.FHDR.FCnt))
		}
		micChecks++
		ok, err = phyPayload.ValidateMIC(nwkSKey)
		if err != nil {
			return err
		}
		if ok {
			device = candidate
			break
		}
	}
	if device == nil {
		err = errors.NewErrNotFound("device that validates MIC")
		return err
	}
	ctx = ctx.WithFields(log.Fields{
		"MICChecks": micChecks,
		"DevEUI":    device.DevEui,
		"AppEUI":    device.AppEui,
		"AppID":     device.AppId,
		"DevID":     device.DevId,
	})

	if device.DisableFCntCheck {
		// TODO: Add warning to message?
	} else if device.FCntUp == 0 {

	} else if macPayload.FHDR.FCnt <= device.FCntUp || macPayload.FHDR.FCnt-device.FCntUp > maxFCntGap {
		// Replay attack or FCnt gap too big
		err = errors.NewErrNotFound("device with matching FCnt")
		return err
	}

	// Add FCnt to Metadata (because it's not marshaled in lorawan payload)
	base.ProtocolMetadata.GetLorawan().FCnt = macPayload.FHDR.FCnt

	// Collect GatewayMetadata and DownlinkOptions
	var gatewayMetadata []*gateway.RxMetadata
	var downlinkOptions []*pb.DownlinkOption
	var downlinkMessage *pb.DownlinkMessage
	for _, duplicate := range duplicates {
		gatewayMetadata = append(gatewayMetadata, duplicate.GatewayMetadata)
		downlinkOptions = append(downlinkOptions, duplicate.DownlinkOptions...)
	}

	// Select best DownlinkOption
	if len(downlinkOptions) > 0 {
		downlinkMessage = &pb.DownlinkMessage{
			DownlinkOption: selectBestDownlink(downlinkOptions),
		}
	}

	// Build Uplink
	deduplicatedUplink := &pb.DeduplicatedUplinkMessage{
		Payload:          base.Payload,
		DevEui:           device.DevEui,
		DevId:            device.DevId,
		AppEui:           device.AppEui,
		AppId:            device.AppId,
		ProtocolMetadata: base.ProtocolMetadata,
		GatewayMetadata:  gatewayMetadata,
		ServerTime:       time.UnixNano(),
		ResponseTemplate: downlinkMessage,
	}

	// Pass Uplink through NS
	deduplicatedUplink, err = b.ns.Uplink(b.Component.GetContext(b.nsToken), deduplicatedUplink)
	if err != nil {
		return errors.BuildGRPCError(errors.Wrap(errors.FromGRPCError(err), "NetworkServer did not handle uplink"))
	}

	var announcements []*pb_discovery.Announcement
	announcements, err = b.Discovery.GetAllHandlersForAppID(device.AppId)
	if err != nil {
		return err
	}
	if len(announcements) == 0 {
		err = errors.NewErrNotFound(fmt.Sprintf("Handler for AppID %s", device.AppId))
		return err
	}
	if len(announcements) > 1 {
		err = errors.NewErrInternal(fmt.Sprintf("Multiple Handlers for AppID %s", device.AppId))
		return err
	}

	var handler chan<- *pb.DeduplicatedUplinkMessage
	handler, err = b.getHandler(announcements[0].Id)
	if err != nil {
		return err
	}

	handler <- deduplicatedUplink

	return nil
}

func (b *broker) deduplicateUplink(duplicate *pb.UplinkMessage) (uplinks []*pb.UplinkMessage) {
	sum := md5.Sum(duplicate.Payload)
	key := hex.EncodeToString(sum[:])
	list := b.uplinkDeduplicator.Deduplicate(key, duplicate)
	if len(list) == 0 {
		return
	}
	for _, duplicate := range list {
		uplinks = append(uplinks, duplicate.(*pb.UplinkMessage))
	}
	return
}

func selectBestDownlink(options []*pb.DownlinkOption) *pb.DownlinkOption {
	sort.Sort(ByScore(options))
	return options[0]
}

// ByFCntUp implements sort.Interface for []*pb_lorawan.Device based on FCnt
type ByFCntUp []*pb_lorawan.Device

func (a ByFCntUp) Len() int      { return len(a) }
func (a ByFCntUp) Swap(i, j int) { a[i], a[j] = a[j], a[i] }
func (a ByFCntUp) Less(i, j int) bool {
	// Devices that disable the FCnt check have low priority
	if a[i].DisableFCntCheck {
		return 2*int(a[i].FCntUp)+100 < int(a[j].FCntUp)
	}
	return int(a[i].FCntUp) < int(a[j].FCntUp)
}
<|endoftext|>


<commit_before>package commands

import (
	"io"
	"strings"

	cmds "github.com/ipfs/go-ipfs/commands"
	unixfs "github.com/ipfs/go-ipfs/core/commands/unixfs"
	logging "github.com/ipfs/go-ipfs/vendor/QmQg1J6vikuXF9oDvm4wpdeAUvvkVEKW1EYDw9HhTMnP2b/go-log"
)

var log = logging.Logger("core/commands")

type TestOutput struct {
	Foo string
	Bar int
}

const (
	ApiOption = "api"
)

var Root = &cmds.Command{
	Helptext: cmds.HelpText{
		Tagline: "global p2p merkle-dag filesystem",
		Synopsis: `
ipfs [<flags>] <command> [<arg>] ...
`,
		ShortDescription: `
BASIC COMMANDS

    init          Initialize ipfs local configuration
    add <path>    Add an object to ipfs
    cat <ref>     Show ipfs object data
    get <ref>     Download ipfs objects
    ls <ref>      List links from an object
    refs <ref>    List hashes of links from an object

DATA STRUCTURE COMMANDS

    block         Interact with raw blocks in the datastore
    object        Interact with raw dag nodes
    file          Interact with Unix filesystem objects

ADVANCED COMMANDS

    daemon        Start a long-running daemon process
    mount         Mount an ipfs read-only mountpoint
    resolve       Resolve any type of name
    name          Publish or resolve IPNS names
    dns           Resolve DNS links
    pin           Pin objects to local storage
    repo gc       Garbage collect unpinned objects

NETWORK COMMANDS

    id            Show info about ipfs peers
    bootstrap     Add or remove bootstrap peers
    swarm         Manage connections to the p2p network
    dht           Query the dht for values or peers
    ping          Measure the latency of a connection
    diag          Print diagnostics

TOOL COMMANDS

    config        Manage configuration
    version       Show ipfs version information
    update        Download and apply go-ipfs updates
    commands      List all available commands

Use 'ipfs <command> --help' to learn more about each command.

ipfs uses a repository in the local file system. By default, the repo is located
at ~/.ipfs. To change the repo location, set the $IPFS_PATH environment variable:

    export IPFS_PATH=/path/to/ipfsrepo
`,
	},
	Options: []cmds.Option{
		cmds.StringOption("config", "c", "Path to the configuration file to use"),
		cmds.BoolOption("debug", "D", "Operate in debug mode"),
		cmds.BoolOption("help", "Show the full command help text"),
		cmds.BoolOption("h", "Show a short version of the command help text"),
		cmds.BoolOption("local", "L", "Run the command locally, instead of using the daemon"),
		cmds.StringOption(ApiOption, "Use a specific API instance (defaults to /ip4/127.0.0.1/tcp/5001)"),
	},
}

// commandsDaemonCmd is the "ipfs commands" command for daemon
var CommandsDaemonCmd = CommandsCmd(Root)

var rootSubcommands = map[string]*cmds.Command{
	"add":       AddCmd,
	"block":     BlockCmd,
	"bootstrap": BootstrapCmd,
	"cat":       CatCmd,
	"commands":  CommandsDaemonCmd,
	"config":    ConfigCmd,
	"dht":       DhtCmd,
	"diag":      DiagCmd,
	"dns":       DNSCmd,
	"get":       GetCmd,
	"id":        IDCmd,
	"log":       LogCmd,
	"ls":        LsCmd,
	"mount":     MountCmd,
	"name":      NameCmd,
	"object":    ObjectCmd,
	"pin":       PinCmd,
	"ping":      PingCmd,
	"refs":      RefsCmd,
	"repo":      RepoCmd,
	"resolve":   ResolveCmd,
	"stats":     StatsCmd,
	"swarm":     SwarmCmd,
	"tar":       TarCmd,
	"tour":      tourCmd,
	"file":      unixfs.UnixFSCmd,
	"update":    ExternalBinary(),
	"version":   VersionCmd,
	"bitswap":   BitswapCmd,
}

// RootRO is the readonly version of Root
var RootRO = &cmds.Command{}

var CommandsDaemonROCmd = CommandsCmd(RootRO)

var RefsROCmd = &cmds.Command{}

var rootROSubcommands = map[string]*cmds.Command{
	"block": &cmds.Command{
		Subcommands: map[string]*cmds.Command{
			"stat": blockStatCmd,
			"get":  blockGetCmd,
		},
	},
	"cat":      CatCmd,
	"commands": CommandsDaemonROCmd,
	"ls":       LsCmd,
	"name": &cmds.Command{
		Subcommands: map[string]*cmds.Command{
			"resolve": IpnsCmd,
		},
	},
	"object": &cmds.Command{
		Subcommands: map[string]*cmds.Command{
			"data":  objectDataCmd,
			"links": objectLinksCmd,
			"get":   objectGetCmd,
			"stat":  objectStatCmd,
		},
	},
	"refs": RefsROCmd,
	//"resolve": ResolveCmd,
	"version": VersionCmd,
}

func init() {
	*RootRO = *Root

	// sanitize readonly refs command
	*RefsROCmd = *RefsCmd
	RefsROCmd.Subcommands = map[string]*cmds.Command{}

	Root.Subcommands = rootSubcommands
	RootRO.Subcommands = rootROSubcommands
}

type MessageOutput struct {
	Message string
}

func MessageTextMarshaler(res cmds.Response) (io.Reader, error) {
	return strings.NewReader(res.Output().(*MessageOutput).Message), nil
}
<commit_msg>add 'get' to the allowed gateway commands<commit_after>package commands

import (
	"io"
	"strings"

	cmds "github.com/ipfs/go-ipfs/commands"
	unixfs "github.com/ipfs/go-ipfs/core/commands/unixfs"
	logging "github.com/ipfs/go-ipfs/vendor/QmQg1J6vikuXF9oDvm4wpdeAUvvkVEKW1EYDw9HhTMnP2b/go-log"
)

var log = logging.Logger("core/commands")

type TestOutput struct {
	Foo string
	Bar int
}

const (
	ApiOption = "api"
)

var Root = &cmds.Command{
	Helptext: cmds.HelpText{
		Tagline: "global p2p merkle-dag filesystem",
		Synopsis: `
ipfs [<flags>] <command> [<arg>] ...
`,
		ShortDescription: `
BASIC COMMANDS

    init          Initialize ipfs local configuration
    add <path>    Add an object to ipfs
    cat <ref>     Show ipfs object data
    get <ref>     Download ipfs objects
    ls <ref>      List links from an object
    refs <ref>    List hashes of links from an object

DATA STRUCTURE COMMANDS

    block         Interact with raw blocks in the datastore
    object        Interact with raw dag nodes
    file          Interact with Unix filesystem objects

ADVANCED COMMANDS

    daemon        Start a long-running daemon process
    mount         Mount an ipfs read-only mountpoint
    resolve       Resolve any type of name
    name          Publish or resolve IPNS names
    dns           Resolve DNS links
    pin           Pin objects to local storage
    repo gc       Garbage collect unpinned objects

NETWORK COMMANDS

    id            Show info about ipfs peers
    bootstrap     Add or remove bootstrap peers
    swarm         Manage connections to the p2p network
    dht           Query the dht for values or peers
    ping          Measure the latency of a connection
    diag          Print diagnostics

TOOL COMMANDS

    config        Manage configuration
    version       Show ipfs version information
    update        Download and apply go-ipfs updates
    commands      List all available commands

Use 'ipfs <command> --help' to learn more about each command.

ipfs uses a repository in the local file system. By default, the repo is located
at ~/.ipfs. To change the repo location, set the $IPFS_PATH environment variable:

    export IPFS_PATH=/path/to/ipfsrepo
`,
	},
	Options: []cmds.Option{
		cmds.StringOption("config", "c", "Path to the configuration file to use"),
		cmds.BoolOption("debug", "D", "Operate in debug mode"),
		cmds.BoolOption("help", "Show the full command help text"),
		cmds.BoolOption("h", "Show a short version of the command help text"),
		cmds.BoolOption("local", "L", "Run the command locally, instead of using the daemon"),
		cmds.StringOption(ApiOption, "Use a specific API instance (defaults to /ip4/127.0.0.1/tcp/5001)"),
	},
}

// commandsDaemonCmd is the "ipfs commands" command for daemon
var CommandsDaemonCmd = CommandsCmd(Root)

var rootSubcommands = map[string]*cmds.Command{
	"add":       AddCmd,
	"block":     BlockCmd,
	"bootstrap": BootstrapCmd,
	"cat":       CatCmd,
	"commands":  CommandsDaemonCmd,
	"config":    ConfigCmd,
	"dht":       DhtCmd,
	"diag":      DiagCmd,
	"dns":       DNSCmd,
	"get":       GetCmd,
	"id":        IDCmd,
	"log":       LogCmd,
	"ls":        LsCmd,
	"mount":     MountCmd,
	"name":      NameCmd,
	"object":    ObjectCmd,
	"pin":       PinCmd,
	"ping":      PingCmd,
	"refs":      RefsCmd,
	"repo":      RepoCmd,
	"resolve":   ResolveCmd,
	"stats":     StatsCmd,
	"swarm":     SwarmCmd,
	"tar":       TarCmd,
	"tour":      tourCmd,
	"file":      unixfs.UnixFSCmd,
	"update":    ExternalBinary(),
	"version":   VersionCmd,
	"bitswap":   BitswapCmd,
}

// RootRO is the readonly version of Root
var RootRO = &cmds.Command{}

var CommandsDaemonROCmd = CommandsCmd(RootRO)

var RefsROCmd = &cmds.Command{}

var rootROSubcommands = map[string]*cmds.Command{
	"block": &cmds.Command{
		Subcommands: map[string]*cmds.Command{
			"stat": blockStatCmd,
			"get":  blockGetCmd,
		},
	},
	"cat":      CatCmd,
	"commands": CommandsDaemonROCmd,
	"get":      GetCmd,
	"ls":       LsCmd,
	"name": &cmds.Command{
		Subcommands: map[string]*cmds.Command{
			"resolve": IpnsCmd,
		},
	},
	"object": &cmds.Command{
		Subcommands: map[string]*cmds.Command{
			"data":  objectDataCmd,
			"links": objectLinksCmd,
			"get":   objectGetCmd,
			"stat":  objectStatCmd,
		},
	},
	"refs": RefsROCmd,
	//"resolve": ResolveCmd,
	"version": VersionCmd,
}

func init() {
	*RootRO = *Root

	// sanitize readonly refs command
	*RefsROCmd = *RefsCmd
	RefsROCmd.Subcommands = map[string]*cmds.Command{}

	Root.Subcommands = rootSubcommands
	RootRO.Subcommands = rootROSubcommands
}

type MessageOutput struct {
	Message string
}

func MessageTextMarshaler(res cmds.Response) (io.Reader, error) {
	return strings.NewReader(res.Output().(*MessageOutput).Message), nil
}
<|endoftext|>


<commit_before>/*
   Copyright 2014 Outbrain Inc.

   Licensed under the Apache License, Version 2.0 (the "License");
   you may not use this file except in compliance with the License.
   You may obtain a copy of the License at

       http://www.apache.org/licenses/LICENSE-2.0

   Unless required by applicable law or agreed to in writing, software
   distributed under the License is distributed on an "AS IS" BASIS,
   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   See the License for the specific language governing permissions and
   limitations under the License.
*/

package sqlutils

import (
	"database/sql"
	"errors"
	"fmt"
	_ "github.com/go-sql-driver/mysql"
	"github.com/outbrain/golib/log"
	"strconv"
	"strings"
)

// RowMap represents one row in a result set. Its objective is to allow
// for easy, typed getters by column name.
type RowMap map[string]sql.NullString

func (this *RowMap) GetString(key string) string {
	return (*this)[key].String
}

func (this *RowMap) GetInt64(key string) int64 {
	res, _ := strconv.ParseInt(this.GetString(key), 10, 0)
	return res
}

func (this *RowMap) GetNullInt64(key string) sql.NullInt64 {
	i, err := strconv.ParseInt(this.GetString(key), 10, 0)
	if err == nil {
		return sql.NullInt64{Int64: i, Valid: true}
	} else {
		return sql.NullInt64{Valid: false}
	}
}

func (this *RowMap) GetInt(key string) int {
	res, _ := strconv.Atoi(this.GetString(key))
	return res
}

func (this *RowMap) GetIntD(key string, def int) int {
	res, err := strconv.Atoi(this.GetString(key))
	if err != nil {
		return def
	}
	return res
}

func (this *RowMap) GetUint(key string) uint {
	res, _ := strconv.Atoi(this.GetString(key))
	return uint(res)
}

func (this *RowMap) GetBool(key string) bool {
	return this.GetInt(key) != 0
}

// knownDBs is a DB cache by uri
var knownDBs map[string]*sql.DB = make(map[string]*sql.DB)

// GetDB returns a DB instance based on uri.
// bool result indicates whether the DB was returned from cache; err
func GetDB(mysql_uri string) (*sql.DB, bool, error) {

	var exists bool
	if _, exists = knownDBs[mysql_uri]; !exists {
		if db, err := sql.Open("mysql", mysql_uri); err == nil {
			knownDBs[mysql_uri] = db
		} else {
			return db, exists, err
		}
	}
	return knownDBs[mysql_uri], exists, nil
}

// RowToArray is a convenience function, typically not called directly, which maps a
// single read database row into a NullString
func RowToArray(rows *sql.Rows, columns []string) []sql.NullString {
	buff := make([]interface{}, len(columns))
	data := make([]sql.NullString, len(columns))
	for i, _ := range buff {
		buff[i] = &data[i]
	}
	rows.Scan(buff...)
	return data
}

// ScanRowsToArrays is a convenience function, typically not called directly, which maps rows
// already read from the databse into arrays of NullString
func ScanRowsToArrays(rows *sql.Rows, on_row func([]sql.NullString) error) error {
	columns, _ := rows.Columns()
	for rows.Next() {
		arr := RowToArray(rows, columns)

		err := on_row(arr)
		if err != nil {
			return err
		}
	}
	return nil
}

// ScanRowsToMaps is a convenience function, typically not called directly, which maps rows
// already read from the databse into RowMap entries.
func ScanRowsToMaps(rows *sql.Rows, on_row func(RowMap) error) error {
	columns, _ := rows.Columns()
	err := ScanRowsToArrays(rows, func(arr []sql.NullString) error {
		m := make(map[string]sql.NullString)
		for k, data_col := range arr {
			m[columns[k]] = data_col
		}
		err := on_row(m)
		if err != nil {
			return err
		}
		return nil
	})
	return err
}

// QueryRowsMap is a convenience function allowing querying a result set while poviding a callback
// function activated per read row.
func QueryRowsMap(db *sql.DB, query string, on_row func(RowMap) error) error {
	var err error
	defer func() {
		if derr := recover(); derr != nil {
			err = errors.New(fmt.Sprintf("QueryRowsMap unexpected error: %+v", derr))
		}
	}()

	rows, err := db.Query(query)
	defer rows.Close()
	if err != nil && err != sql.ErrNoRows {
		return log.Errore(err)
	}
	err = ScanRowsToMaps(rows, on_row)
	return err
}

// ExecQuery executes given query using given args on given DB. It will safele prepare, execute and close
// the statement.
func execInternal(silent bool, db *sql.DB, query string, args ...interface{}) (sql.Result, error) {
	var err error
	defer func() {
		if derr := recover(); derr != nil {
			err = errors.New(fmt.Sprintf("QueryRowsMap unexpected error: %+v", derr))
		}
	}()

	stmt, err := db.Prepare(query)
	if err != nil {
		return nil, err
	}
	defer stmt.Close()
	var res sql.Result
	res, err = stmt.Exec(args...)
	if err != nil && !silent {
		log.Errore(err)
	}
	return res, err
}

// Exec executes given query using given args on given DB. It will safele prepare, execute and close
// the statement.
func Exec(db *sql.DB, query string, args ...interface{}) (sql.Result, error) {
	return execInternal(false, db, query, args...)
}

// ExecSilently acts like Exec but does not report any error
func ExecSilently(db *sql.DB, query string, args ...interface{}) (sql.Result, error) {
	return execInternal(true, db, query, args...)
}

func InClauseStringValues(terms []string) string {
	quoted := []string{}
	for _, s := range terms {
		quoted = append(quoted, fmt.Sprintf("'%s'", strings.Replace(s, ",", "''", -1)))
	}
	return strings.Join(quoted, ", ")
}
<commit_msg>Added QueryResultData which returns raw array of rows<commit_after>/*
   Copyright 2014 Outbrain Inc.

   Licensed under the Apache License, Version 2.0 (the "License");
   you may not use this file except in compliance with the License.
   You may obtain a copy of the License at

       http://www.apache.org/licenses/LICENSE-2.0

   Unless required by applicable law or agreed to in writing, software
   distributed under the License is distributed on an "AS IS" BASIS,
   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   See the License for the specific language governing permissions and
   limitations under the License.
*/

package sqlutils

import (
	"database/sql"
	"errors"
	"fmt"
	_ "github.com/go-sql-driver/mysql"
	"github.com/outbrain/golib/log"
	"strconv"
	"strings"
)

// RowMap represents one row in a result set. Its objective is to allow
// for easy, typed getters by column name.
type RowMap map[string]sql.NullString

// RowData is the result of a single row, in positioned array format
type RowData []sql.NullString

// ResultData is an ordered row set of RowData
type ResultData []RowData

var EmptyResultData = ResultData{}

func (this *RowMap) GetString(key string) string {
	return (*this)[key].String
}

func (this *RowMap) GetInt64(key string) int64 {
	res, _ := strconv.ParseInt(this.GetString(key), 10, 0)
	return res
}

func (this *RowMap) GetNullInt64(key string) sql.NullInt64 {
	i, err := strconv.ParseInt(this.GetString(key), 10, 0)
	if err == nil {
		return sql.NullInt64{Int64: i, Valid: true}
	} else {
		return sql.NullInt64{Valid: false}
	}
}

func (this *RowMap) GetInt(key string) int {
	res, _ := strconv.Atoi(this.GetString(key))
	return res
}

func (this *RowMap) GetIntD(key string, def int) int {
	res, err := strconv.Atoi(this.GetString(key))
	if err != nil {
		return def
	}
	return res
}

func (this *RowMap) GetUint(key string) uint {
	res, _ := strconv.Atoi(this.GetString(key))
	return uint(res)
}

func (this *RowMap) GetBool(key string) bool {
	return this.GetInt(key) != 0
}

// knownDBs is a DB cache by uri
var knownDBs map[string]*sql.DB = make(map[string]*sql.DB)

// GetDB returns a DB instance based on uri.
// bool result indicates whether the DB was returned from cache; err
func GetDB(mysql_uri string) (*sql.DB, bool, error) {

	var exists bool
	if _, exists = knownDBs[mysql_uri]; !exists {
		if db, err := sql.Open("mysql", mysql_uri); err == nil {
			knownDBs[mysql_uri] = db
		} else {
			return db, exists, err
		}
	}
	return knownDBs[mysql_uri], exists, nil
}

// RowToArray is a convenience function, typically not called directly, which maps a
// single read database row into a NullString
func RowToArray(rows *sql.Rows, columns []string) []sql.NullString {
	buff := make([]interface{}, len(columns))
	data := make([]sql.NullString, len(columns))
	for i, _ := range buff {
		buff[i] = &data[i]
	}
	rows.Scan(buff...)
	return data
}

// ScanRowsToArrays is a convenience function, typically not called directly, which maps rows
// already read from the databse into arrays of NullString
func ScanRowsToArrays(rows *sql.Rows, on_row func([]sql.NullString) error) error {
	columns, _ := rows.Columns()
	for rows.Next() {
		arr := RowToArray(rows, columns)

		err := on_row(arr)
		if err != nil {
			return err
		}
	}
	return nil
}

// ScanRowsToMaps is a convenience function, typically not called directly, which maps rows
// already read from the databse into RowMap entries.
func ScanRowsToMaps(rows *sql.Rows, on_row func(RowMap) error) error {
	columns, _ := rows.Columns()
	err := ScanRowsToArrays(rows, func(arr []sql.NullString) error {
		m := make(map[string]sql.NullString)
		for k, data_col := range arr {
			m[columns[k]] = data_col
		}
		err := on_row(m)
		if err != nil {
			return err
		}
		return nil
	})
	return err
}

// QueryRowsMap is a convenience function allowing querying a result set while poviding a callback
// function activated per read row.
func QueryRowsMap(db *sql.DB, query string, on_row func(RowMap) error) error {
	var err error
	defer func() {
		if derr := recover(); derr != nil {
			err = errors.New(fmt.Sprintf("QueryRowsMap unexpected error: %+v", derr))
		}
	}()

	rows, err := db.Query(query)
	defer rows.Close()
	if err != nil && err != sql.ErrNoRows {
		return log.Errore(err)
	}
	err = ScanRowsToMaps(rows, on_row)
	return err
}

// QueryResultData returns a raw array of rows
func QueryResultData(db *sql.DB, query string) (ResultData, error) {
	var err error
	defer func() {
		if derr := recover(); derr != nil {
			err = errors.New(fmt.Sprintf("QueryRowsMap unexpected error: %+v", derr))
		}
	}()

	rows, err := db.Query(query)
	defer rows.Close()
	if err != nil && err != sql.ErrNoRows {
		return EmptyResultData, log.Errore(err)
	}
	resultData := ResultData{}
	err = ScanRowsToArrays(rows, func(rowData []sql.NullString) error {
		resultData = append(resultData, rowData)
		return nil
	})
	return resultData, err
}

// ExecQuery executes given query using given args on given DB. It will safele prepare, execute and close
// the statement.
func execInternal(silent bool, db *sql.DB, query string, args ...interface{}) (sql.Result, error) {
	var err error
	defer func() {
		if derr := recover(); derr != nil {
			err = errors.New(fmt.Sprintf("QueryRowsMap unexpected error: %+v", derr))
		}
	}()

	stmt, err := db.Prepare(query)
	if err != nil {
		return nil, err
	}
	defer stmt.Close()
	var res sql.Result
	res, err = stmt.Exec(args...)
	if err != nil && !silent {
		log.Errore(err)
	}
	return res, err
}

// Exec executes given query using given args on given DB. It will safele prepare, execute and close
// the statement.
func Exec(db *sql.DB, query string, args ...interface{}) (sql.Result, error) {
	return execInternal(false, db, query, args...)
}

// ExecSilently acts like Exec but does not report any error
func ExecSilently(db *sql.DB, query string, args ...interface{}) (sql.Result, error) {
	return execInternal(true, db, query, args...)
}

func InClauseStringValues(terms []string) string {
	quoted := []string{}
	for _, s := range terms {
		quoted = append(quoted, fmt.Sprintf("'%s'", strings.Replace(s, ",", "''", -1)))
	}
	return strings.Join(quoted, ", ")
}
<|endoftext|>


<commit_before>package core

import (
	"encoding/json"
	"fmt"
	"io/ioutil"
	"net/url"

	"github.com/FrenchBen/oracle-sdk-go/bmc"
	"github.com/Sirupsen/logrus"
)

// SecurityList contains the SecurityList reference from: https://docs.us-phoenix-1.oraclecloud.com/api/#/en/iaas/20160918/SecurityList/
type SecurityList struct {
	// The OCID of the compartment that contains the security list
	CompartmentID string `json:"compartmentId"`
	// A user-friendly name
	DisplayName string `json:"displayName"`
	// The OCID of the SecurityList
	ID string `json:"id,omitempty"`
	// Rules for allowing egress IP packets
	EgressSecurityRules *[]EgressSecurityRule `json:"egressSecurityRules"`
	// Rules for allowing ingress IP packets
	IngressSecurityRules *[]IngressSecurityRule `json:"ingressSecurityRules"`
	// The SecurityList's current state
	LifeCycleState string `json:"lifecycleState,omitempty"`
	// The date and time the instance was created (RFC3339)
	TimeCreated string `json:"timeCreated,omitempty"`
	// The OCID of the VCN
	VcnID string `json:"vcnId"`
}

// EgressSecurityRule rule for allowing outbound IP packets
type EgressSecurityRule struct {
	Destination string `json:"destination"`
	IcmpOptions string `json:"icmpOptions,omitempty"`
	IsStateless string `json:"isStateless,omitempty"`
	// Protocol values: all, ICMP ("1"), TCP ("6"), UDP ("17").
	Protocol   string      `json:"protocol"`
	TcpOptions *PortConfig `json:"tcpOptions,omitempty"`
	UdpOptions *PortConfig `json:"udpOptions,omitempty"`
}

// IngressSecurityRule rule for allowing inbound IP packets
type IngressSecurityRule struct {
	Source      string `json:"source"`
	IcmpOptions string `json:"icmpOptions,omitempty"`
	IsStateless string `json:"isStateless,omitempty"`
	// Protocol values: all, ICMP ("1"), TCP ("6"), UDP ("17").
	Protocol   string      `json:"protocol"`
	TcpOptions *PortConfig `json:"tcpOptions,omitempty"`
	UdpOptions *PortConfig `json:"udpOptions,omitempty"`
}

type PortConfig struct {
	DestinationPortRange *PortRange `json:"destinationPortRange,omitempty"`
	SourcePortRange      *PortRange `json:"sourcePortRange,omitempty"`
}

type PortRange struct {
	Min string `json:"min,omitempty"`
	Max string `json:"max,omitempty"`
}

// GetSecurityList returns a struct of a SecurityList request given an SecurityList ID
func (c *Client) GetSecurityList(securityListID string) (SecurityList, *bmc.Error) {
	securityList := SecurityList{}
	queryString := url.QueryEscape(securityListID)
	resp, err := c.Request("GET", "/securityLists/"+queryString, nil)
	if err != nil {
		logrus.Error(err)
		bmcError := bmc.Error{Code: string(resp.StatusCode), Message: err.Error()}
		return securityList, &bmcError
	}
	logrus.Debug("StatusCode: ", resp.StatusCode)
	if resp.StatusCode != 200 {
		return securityList, bmc.NewError(*resp)
	}
	defer resp.Body.Close()
	body, err := ioutil.ReadAll(resp.Body)
	logrus.Debug("Body: ", string(body))
	if err != nil {
		logrus.Fatalf("Could not read JSON response: %s", err)
	}
	if err = json.Unmarshal(body, &securityList); err != nil {
		logrus.Fatalf("Unmarshal impossible: %s", err)
	}
	return securityList, nil
}

// ListSecurityLists returns a slice struct of all securityList
func (c *Client) ListSecurityLists(vcnID string) ([]SecurityList, *bmc.Error) {
	securityLists := []SecurityList{}
	queryString := url.QueryEscape(c.CompartmentID)
	if vcnID != "" {
		queryString = queryString + "&vcnId=" + url.QueryEscape(vcnID)
	}
	resp, err := c.Request("GET", fmt.Sprintf("/securityLists?compartmentId=%s", queryString), nil)
	if err != nil {
		logrus.Error(err)
		bmcError := bmc.Error{Code: string(resp.StatusCode), Message: err.Error()}
		return securityLists, &bmcError
	}
	logrus.Debug("StatusCode: ", resp.StatusCode)
	if resp.StatusCode != 200 {
		return securityLists, bmc.NewError(*resp)
	}
	defer resp.Body.Close()
	body, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		logrus.Fatalf("Could not read JSON response: %s", err)
	}

	logrus.Debug("Body: ", string(body))
	if err = json.Unmarshal(body, &securityLists); err != nil {
		logrus.Fatalf("Unmarshal impossible: %s", err)
	}
	return securityLists, nil
}

// CreateSecurityList creates a new security list for the specified VCN
func (c *Client) CreateSecurityList(securityList *SecurityList) (bool, *bmc.Error) {
	resp, err := c.Request("POST", fmt.Sprintf("/securityLists/"), *securityList)
	if err != nil {
		logrus.Error(err)
		bmcError := bmc.Error{Code: string(resp.StatusCode), Message: err.Error()}
		return false, &bmcError
	}
	logrus.Debug("StatusCode: ", resp.StatusCode)
	if resp.StatusCode != 204 {
		return false, bmc.NewError(*resp)
	}
	return true, nil
}

// UpdateSecurityList updates a security list
func (c *Client) UpdateSecurityList(listener *SecurityList) {
	// PUT securityLists/{loadBalancerId}/listeners/{listenerName}
	logrus.Warning("Method not yet implemented")
	return
}

// DeleteSecurityList deletes the specified security list, but only if it's not associated with a subnet
func (c *Client) DeleteSecurityList(securityListID string) (bool, *bmc.Error) {
	securityListID = url.PathEscape(securityListID)
	resp, err := c.Request("DELETE", fmt.Sprintf("/securityLists/%s", securityListID), nil)
	if err != nil {
		logrus.Error(err)
		bmcError := bmc.Error{Code: string(resp.StatusCode), Message: err.Error()}
		return false, &bmcError
	}
	logrus.Debug("StatusCode: ", resp.StatusCode)
	if resp.StatusCode != 204 {
		return false, bmc.NewError(*resp)
	}
	return true, nil
}
<commit_msg>SecurityList will return content on create<commit_after>package core

import (
	"encoding/json"
	"fmt"
	"io/ioutil"
	"net/url"

	"github.com/FrenchBen/oracle-sdk-go/bmc"
	"github.com/Sirupsen/logrus"
)

// SecurityList contains the SecurityList reference from: https://docs.us-phoenix-1.oraclecloud.com/api/#/en/iaas/20160918/SecurityList/
type SecurityList struct {
	// The OCID of the compartment that contains the security list
	CompartmentID string `json:"compartmentId"`
	// A user-friendly name
	DisplayName string `json:"displayName"`
	// The OCID of the SecurityList
	ID string `json:"id,omitempty"`
	// Rules for allowing egress IP packets
	EgressSecurityRules *[]EgressSecurityRule `json:"egressSecurityRules"`
	// Rules for allowing ingress IP packets
	IngressSecurityRules *[]IngressSecurityRule `json:"ingressSecurityRules"`
	// The SecurityList's current state
	LifeCycleState string `json:"lifecycleState,omitempty"`
	// The date and time the instance was created (RFC3339)
	TimeCreated string `json:"timeCreated,omitempty"`
	// The OCID of the VCN
	VcnID string `json:"vcnId"`
}

// EgressSecurityRule rule for allowing outbound IP packets
type EgressSecurityRule struct {
	Destination string `json:"destination"`
	IcmpOptions string `json:"icmpOptions,omitempty"`
	IsStateless string `json:"isStateless,omitempty"`
	// Protocol values: all, ICMP ("1"), TCP ("6"), UDP ("17").
	Protocol   string      `json:"protocol"`
	TcpOptions *PortConfig `json:"tcpOptions,omitempty"`
	UdpOptions *PortConfig `json:"udpOptions,omitempty"`
}

// IngressSecurityRule rule for allowing inbound IP packets
type IngressSecurityRule struct {
	Source      string `json:"source"`
	IcmpOptions string `json:"icmpOptions,omitempty"`
	IsStateless string `json:"isStateless,omitempty"`
	// Protocol values: all, ICMP ("1"), TCP ("6"), UDP ("17").
	Protocol   string      `json:"protocol"`
	TcpOptions *PortConfig `json:"tcpOptions,omitempty"`
	UdpOptions *PortConfig `json:"udpOptions,omitempty"`
}

type PortConfig struct {
	DestinationPortRange *PortRange `json:"destinationPortRange,omitempty"`
	SourcePortRange      *PortRange `json:"sourcePortRange,omitempty"`
}

type PortRange struct {
	Min string `json:"min,omitempty"`
	Max string `json:"max,omitempty"`
}

// GetSecurityList returns a struct of a SecurityList request given an SecurityList ID
func (c *Client) GetSecurityList(securityListID string) (SecurityList, *bmc.Error) {
	securityList := SecurityList{}
	queryString := url.QueryEscape(securityListID)
	resp, err := c.Request("GET", "/securityLists/"+queryString, nil)
	if err != nil {
		logrus.Error(err)
		bmcError := bmc.Error{Code: string(resp.StatusCode), Message: err.Error()}
		return securityList, &bmcError
	}
	logrus.Debug("StatusCode: ", resp.StatusCode)
	if resp.StatusCode != 200 {
		return securityList, bmc.NewError(*resp)
	}
	defer resp.Body.Close()
	body, err := ioutil.ReadAll(resp.Body)
	logrus.Debug("Body: ", string(body))
	if err != nil {
		logrus.Fatalf("Could not read JSON response: %s", err)
	}
	if err = json.Unmarshal(body, &securityList); err != nil {
		logrus.Fatalf("Unmarshal impossible: %s", err)
	}
	return securityList, nil
}

// ListSecurityLists returns a slice struct of all securityList
func (c *Client) ListSecurityLists(vcnID string) ([]SecurityList, *bmc.Error) {
	securityLists := []SecurityList{}
	queryString := url.QueryEscape(c.CompartmentID)
	if vcnID != "" {
		queryString = queryString + "&vcnId=" + url.QueryEscape(vcnID)
	}
	resp, err := c.Request("GET", fmt.Sprintf("/securityLists?compartmentId=%s", queryString), nil)
	if err != nil {
		logrus.Error(err)
		bmcError := bmc.Error{Code: string(resp.StatusCode), Message: err.Error()}
		return securityLists, &bmcError
	}
	logrus.Debug("StatusCode: ", resp.StatusCode)
	if resp.StatusCode != 200 {
		return securityLists, bmc.NewError(*resp)
	}
	defer resp.Body.Close()
	body, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		logrus.Fatalf("Could not read JSON response: %s", err)
	}

	logrus.Debug("Body: ", string(body))
	if err = json.Unmarshal(body, &securityLists); err != nil {
		logrus.Fatalf("Unmarshal impossible: %s", err)
	}
	return securityLists, nil
}

// CreateSecurityList creates a new security list for the specified VCN
func (c *Client) CreateSecurityList(securityList *SecurityList) (bool, *bmc.Error) {
	resp, err := c.Request("POST", fmt.Sprintf("/securityLists/"), *securityList)
	if err != nil {
		logrus.Error(err)
		bmcError := bmc.Error{Code: string(resp.StatusCode), Message: err.Error()}
		return false, &bmcError
	}
	logrus.Debug("StatusCode: ", resp.StatusCode)
	if resp.StatusCode != 200 {
		return false, bmc.NewError(*resp)
	}
	return true, nil
}

// UpdateSecurityList updates a security list
func (c *Client) UpdateSecurityList(listener *SecurityList) {
	// PUT securityLists/{loadBalancerId}/listeners/{listenerName}
	logrus.Warning("Method not yet implemented")
	return
}

// DeleteSecurityList deletes the specified security list, but only if it's not associated with a subnet
func (c *Client) DeleteSecurityList(securityListID string) (bool, *bmc.Error) {
	securityListID = url.PathEscape(securityListID)
	resp, err := c.Request("DELETE", fmt.Sprintf("/securityLists/%s", securityListID), nil)
	if err != nil {
		logrus.Error(err)
		bmcError := bmc.Error{Code: string(resp.StatusCode), Message: err.Error()}
		return false, &bmcError
	}
	logrus.Debug("StatusCode: ", resp.StatusCode)
	if resp.StatusCode != 204 {
		return false, bmc.NewError(*resp)
	}
	return true, nil
}
<|endoftext|>


<commit_before>package handlers

import (
	"github.com/APTrust/easy-store/db/models"
	"github.com/gorilla/mux"
	_ "github.com/jinzhu/gorm/dialects/sqlite"
	_ "github.com/mattn/go-sqlite3"
	"log"
	"net/http"
	"strconv"
)

func BagsList(w http.ResponseWriter, r *http.Request) {
	data := make(map[string]interface{})
	bags := make([]models.Bag, 0)
	err := db.Find(&bags).Error
	if err != nil {
		log.Println(err.Error())
	}
	data["items"] = bags
	successMessage, ok := r.URL.Query()["success"]
	if ok {
		data["success"] = successMessage[0]
	}
	err = templates.ExecuteTemplate(w, "bag-list", data)
	if err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
		return
	}
}

func BagDetail(w http.ResponseWriter, r *http.Request) {
	data := make(map[string]interface{})
	vars := mux.Vars(r)
	id, _ := strconv.Atoi(vars["id"])
	log.Println("GET Bag", id)
	bag := models.Bag{}
	err := db.Find(&bag, id).Preload("Files").Error
	if err != nil {
		log.Println(err.Error())
	}
	data["item"] = bag
	data["items"] = bag.Files
	err = templates.ExecuteTemplate(w, "bag-detail", data)
	if err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
		return
	}
}
<commit_msg>Wrapping bag handlers<commit_after>package handlers

import (
	"github.com/APTrust/easy-store/db/models"
	"github.com/gorilla/mux"
	_ "github.com/jinzhu/gorm/dialects/sqlite"
	_ "github.com/mattn/go-sqlite3"
	"github.com/pkg/errors"
	"net/http"
	"strconv"
)

func BagsList(env *Environment, w http.ResponseWriter, r *http.Request) error {
	data := make(map[string]interface{})
	bags := make([]models.Bag, 0)
	err := env.DB.Find(&bags).Error
	if err != nil {
		return errors.WithStack(err)
	}
	data["items"] = bags
	successMessage, ok := r.URL.Query()["success"]
	if ok {
		data["success"] = successMessage[0]
	}
	return env.Templates.ExecuteTemplate(w, "bag-list", data)
}

func BagDetail(env *Environment, w http.ResponseWriter, r *http.Request) error {
	data := make(map[string]interface{})
	vars := mux.Vars(r)
	id, _ := strconv.Atoi(vars["id"])
	bag := models.Bag{}
	err := env.DB.Find(&bag, id).Preload("Files").Error
	if err != nil {
		errors.WithStack(err)
	}
	data["item"] = bag
	data["items"] = bag.Files
	return env.Templates.ExecuteTemplate(w, "bag-detail", data)
}
<|endoftext|>