<commit_before>package api

import (
	"encoding/json"
	"fmt"
	"github.com/mathcunha/CloudCapacitor/capacitor"
	"io/ioutil"
	"log"
	"math"
	"net/http"
	"net/url"
	"os"
	"strconv"
	"strings"
)

func restHandlerV1(w http.ResponseWriter, r *http.Request) {
	a_path := strings.Split(r.URL.Path, "/")
	if "POST" != r.Method {
		http.Error(w, "method not allowed, try curl -d '{\"slo\":20000, \"demand\":[100], \"wkl\":\"optimistic\", \"configuration\":\"optimistic\", \"mode\":\"Strict\"}' -X POST https://cloudcapacitor.herokuapp.com/api/v1/capacitor", http.StatusMethodNotAllowed)
		return
	}
	if "capacitor" != a_path[3] {
		http.Error(w, "no handler to path "+r.URL.Path, http.StatusNotFound)
		return
	} else {
		callCapacitorResource(w, r)
	}
}

func StartServer() {
	http.HandleFunc("/webui/", staticHandler)
	http.HandleFunc("/api/v1/", restHandlerV1)
	http.ListenAndServe(getPort(), nil)
}

func staticHandler(w http.ResponseWriter, r *http.Request) {
	//log.Printf("INFO: staticHandler:%v", r.URL.Path[1:])
	http.ServeFile(w, r, r.URL.Path[1:])
}

func getPort() string {
	var port = os.Getenv("PORT")
	// Set a default port if there is nothing in the environment
	if port == "" {
		port = "8080"
		log.Println("INFO: No PORT environment variable detected, defaulting to " + port)
	}
	return ":" + port
}

func drawDeploymentSpace(w http.ResponseWriter, r *http.Request) {
	var config struct {
		Slo      int     `json:"slo"`
		Price    float32 `json:"price"`
		Size     int     `json:"instances"`
		Mode     string  `json:"mode"`
		Category bool    `json:"category"`
		VMtype   []int   `json:"vmtype"`
	}
	err := json.NewDecoder(r.Body).Decode(&config)
	r.Body.Close()
	if err != nil {
		log.Printf("ERROR: Parsing request body drawDeploymentSpace:%v", err)
		return
	}
	file := "config/dspace.yml"
	if !config.Category {
		file = "config/dspace_nocat.yml"
	}

	vms, err := getVMTypes(file, config.VMtype)
	if err != nil {
		log.Println("ERROR: drawDeploymentSpace loanding vm types")
		return
	}
	dspace := capacitor.NewDeploymentSpace(&vms, config.Price, config.Size)

	graph := capacitor.NodesToDOT(dspace.CapacityBy(config.Mode))
	w.Header().Set("Content-Type", "text/plain")
	fmt.Fprintf(w, "%v", callGraphviz(graph))
}

func callGraphviz(graph string) string {
	resp, err := http.PostForm("http://graphviz-dev.appspot.com/create_preview", url.Values{"engine": {"dot"}, "script": {graph}})
	if err != nil {
		log.Println("ERROR: drawDeploymentSpace calling remote service: %v", err)
		return ""
	}
	defer resp.Body.Close()

	body, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		log.Println("ERROR: drawDeploymentSpace reading remote service: %v", err)
		return ""
	}
	return string(body)
}

func getVMTypes(file string, excludedVMs []int) (vms []capacitor.VM, err error) {
	vms, err = capacitor.LoadTypes(file)
	if err != nil {
		return
	}
	if len(excludedVMs) > 0 {
		localVMs := make([]capacitor.VM, len(vms)-len(excludedVMs), len(vms)-len(excludedVMs))
		j := 0
		k := 0
		for i := 0; i < len(vms); i++ {
			if j == len(excludedVMs) || i != excludedVMs[j] {
				localVMs[k] = vms[i]
				k++
			} else {
				j++
			}
		}
		vms = localVMs
	}
	for i, _ := range vms {
		vms[i].Strict = i
	}
	return
}
<commit_msg>error handling<commit_after>package api

import (
	"encoding/json"
	"fmt"
	"github.com/mathcunha/CloudCapacitor/capacitor"
	"io/ioutil"
	"log"
	"math"
	"net/http"
	"net/url"
	"os"
	"strconv"
	"strings"
)

func restHandlerV1(w http.ResponseWriter, r *http.Request) {
	a_path := strings.Split(r.URL.Path, "/")
	if "POST" != r.Method {
		http.Error(w, "method not allowed, try curl -d '{\"slo\":20000, \"demand\":[100], \"wkl\":\"optimistic\", \"configuration\":\"optimistic\", \"mode\":\"Strict\"}' -X POST https://cloudcapacitor.herokuapp.com/api/v1/capacitor", http.StatusMethodNotAllowed)
		return
	}
	if "capacitor" != a_path[3] {
		http.Error(w, "no handler to path "+r.URL.Path, http.StatusNotFound)
		return
	} else {
		callCapacitorResource(w, r)
	}
}

func StartServer() {
	http.HandleFunc("/webui/", staticHandler)
	http.HandleFunc("/api/v1/", restHandlerV1)
	http.ListenAndServe(getPort(), nil)
}

func staticHandler(w http.ResponseWriter, r *http.Request) {
	//log.Printf("INFO: staticHandler:%v", r.URL.Path[1:])
	http.ServeFile(w, r, r.URL.Path[1:])
}

func getPort() string {
	var port = os.Getenv("PORT")
	// Set a default port if there is nothing in the environment
	if port == "" {
		port = "8080"
		log.Println("INFO: No PORT environment variable detected, defaulting to " + port)
	}
	return ":" + port
}

func drawDeploymentSpace(w http.ResponseWriter, r *http.Request) {
	var config struct {
		Slo      int     `json:"slo"`
		Price    float32 `json:"price"`
		Size     int     `json:"instances"`
		Mode     string  `json:"mode"`
		Category bool    `json:"category"`
		VMtype   []int   `json:"vmtype"`
	}
	err := json.NewDecoder(r.Body).Decode(&config)
	r.Body.Close()
	if err != nil {
		log.Printf("ERROR: Parsing request body drawDeploymentSpace:%v", err)
		return
	}
	file := "config/dspace.yml"
	if !config.Category {
		file = "config/dspace_nocat.yml"
	}

	vms, err := getVMTypes(file, config.VMtype)
	if err != nil {
		log.Println("ERROR: drawDeploymentSpace loanding vm types")
		return
	}
	dspace := capacitor.NewDeploymentSpace(&vms, config.Price, config.Size)

	graph := capacitor.NodesToDOT(dspace.CapacityBy(config.Mode))
	w.Header().Set("Content-Type", "text/plain")
	fmt.Fprintf(w, "%v", callGraphviz(graph))
}

func callGraphviz(graph string) string {
	resp, err := http.PostForm("http://graphviz-dev.appspot.com/create_preview", url.Values{"engine": {"dot"}, "script": {graph}})
	if err != nil {
		log.Println("ERROR: drawDeploymentSpace calling remote service: %v", err)
		return "ERROR"
	}
	defer resp.Body.Close()

	body, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		log.Println("ERROR: drawDeploymentSpace reading remote service: %v", err)
		return "ERROR"
	}
	return string(body)
}

func getVMTypes(file string, excludedVMs []int) (vms []capacitor.VM, err error) {
	vms, err = capacitor.LoadTypes(file)
	if err != nil {
		return
	}
	if len(excludedVMs) > 0 {
		localVMs := make([]capacitor.VM, len(vms)-len(excludedVMs), len(vms)-len(excludedVMs))
		j := 0
		k := 0
		for i := 0; i < len(vms); i++ {
			if j == len(excludedVMs) || i != excludedVMs[j] {
				localVMs[k] = vms[i]
				k++
			} else {
				j++
			}
		}
		vms = localVMs
	}
	for i, _ := range vms {
		vms[i].Strict = i
	}
	return
}

{'fraction_non_alphanumeric': 0.17349621153548786, 'fraction_numerical': 0.007731560228854183, 'mean_word_length': 3.9298780487804876, 'pattern_counts': {'":': 16, '<': 5, '<?xml version=': 0, '>': 5, 'https://': 2, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2161068', 'n_tokens_mistral': 2608, 'n_tokens_neox': 2485, 'n_words': 537}