Browse Source

Before Response map testing

main
Дмитрий 3 years ago
parent
commit
cb8f5fead8
  1. 55
      src/client_server/client.go
  2. 112
      src/client_server/handlers.go
  3. 7
      src/client_server/server.go
  4. 2
      src/client_server/validators.go
  5. 7
      src/main.go

55
src/client_server/client.go

@ -1,13 +1,19 @@
package clientserver package clientserver
import ( import (
"encoding/json"
"errors"
"io" "io"
"io/ioutil"
"log" "log"
"net/http" "net/http"
req_types "sample-choose-ad/src/requests_types"
"time" "time"
) )
func sendRequest(url string, body *io.Reader) { func sendRequest(url string, body *io.Reader) (req_types.SuccesResponse, error) {
var pResp req_types.SuccesResponse
c := &http.Client{ c := &http.Client{
Timeout: 200 * time.Millisecond, Timeout: 200 * time.Millisecond,
} }
@ -17,5 +23,50 @@ func sendRequest(url string, body *io.Reader) {
if err != nil { if err != nil {
log.Println(err) log.Println(err)
} }
log.Println(resp)
if resp.StatusCode == 204 {
return pResp, errors.New("No content")
}
b, _ := ioutil.ReadAll(resp.Body)
err = json.Unmarshal(b, &pResp)
if err != nil {
log.Println(err)
}
return pResp, nil
}
/*
key string
map[price]{Imp}
*/
func sendRequest2(url string, body *io.Reader) ([]req_types.RespImp, error) {
var pResp req_types.SuccesResponse
c := &http.Client{
Timeout: 200 * time.Millisecond,
}
resp, err := c.Post(url, "application/json", *body)
if err != nil {
log.Println(err)
}
if resp.StatusCode == 204 {
return pResp.Imp, errors.New("No content")
}
b, _ := ioutil.ReadAll(resp.Body)
err = json.Unmarshal(b, &pResp)
if err != nil {
log.Println(err)
}
return pResp.Imp, nil
} }

112
src/client_server/handlers.go

@ -3,78 +3,112 @@ package clientserver
import ( import (
"bytes" "bytes"
"encoding/json" "encoding/json"
"fmt"
"io" "io"
"io/ioutil" "io/ioutil"
"log" "log"
"math" "math"
"net/http" "net/http"
customtypes "sample-choose-ad/src/custom_types"
req_types "sample-choose-ad/src/requests_types" req_types "sample-choose-ad/src/requests_types"
) )
func handleRequest(w http.ResponseWriter, r *http.Request) { // Create requset body based in incoming reqest `ir` and return
// `OutgoingRequest` as bytes.Reader from marshaled JSON
func constructPartnersRequestBody(ir *req_types.IncomingRequest) io.Reader {
var outReqBody req_types.OutgoingRequest
var imps []req_types.Imp
// WARN: uint and float multiplication may cause problems
for _, tile := range ir.Tiles {
imps = append(imps, req_types.Imp{
Id: tile.Id,
Minwidth: tile.Width,
Minheight: uint(math.Floor(float64(tile.Width * uint(tile.Ratio))))})
}
outReqBody.Id = *ir.Id
outReqBody.Imp = imps
outReqBody.Context = ir.Context
t, _ := json.Marshal(outReqBody)
return bytes.NewReader(t)
}
// Parsing and checking incoming request.
func parseAndCheckIncomingRequest(w http.ResponseWriter, r *http.Request) (req_types.IncomingRequest, error) {
body, _ := ioutil.ReadAll(r.Body) body, _ := ioutil.ReadAll(r.Body)
var inpReqBody req_types.IncomingRequest var inpReqBody req_types.IncomingRequest
var err error
err := json.Unmarshal(body, &inpReqBody) if json.Unmarshal(body, &inpReqBody) != nil {
if err != nil {
throwHTTPError("WRONG_SCHEMA", 400, &w) throwHTTPError("WRONG_SCHEMA", 400, &w)
return return inpReqBody, err
} }
// Check if Id is empty // Check if Id is empty
if inpReqBody.Id == nil { if inpReqBody.Id == nil {
throwHTTPError("EMPTY_FIELD", 400, &w) throwHTTPError("EMPTY_FIELD", 400, &w)
return return inpReqBody, err
} }
// Check if tiles is empty // Check if tiles is empty
if len(inpReqBody.Tiles) == 0 { if len(inpReqBody.Tiles) == 0 {
throwHTTPError("EMPTY_TILES", 400, &w) throwHTTPError("EMPTY_TILES", 400, &w)
return return inpReqBody, err
} }
// ipv4 validation // ipv4 validation
if wrongIPAddresFormat(inpReqBody.Context.Ip) { if wrongIPAddresFormat(inpReqBody.Context.Ip) {
throwHTTPError("WRONG_SCHEMA", 400, &w) throwHTTPError("WRONG_SCHEMA", 400, &w)
return return inpReqBody, err
} }
// TODO: fix url TODO: может что то получится сделать с p_body? return inpReqBody, err
// Такие запросы надо разослать на список партнеров (-d). Из их
// ответов потом нужно выбрат
/*
Получив все ответы, ваш сервис должен для каждого элемента tiles из запроса
плейсмента выбрать среди imp с таким же id тот, у которого максимальная цена.
Одинаковых цен с одним id не будет
Если imp с каким-то id не получено, такого id не должно быть в ответе. Порядок imp в
ответе должен соответствовать порядку tiles в запросе плейсмента. Формат ответа:
*/
// Отпралять запросы как горутины!
p_body := constructPartnersRequestBody(&inpReqBody)
sendRequest("localhost:5059", &p_body)
} }
func constructPartnersRequestBody(ir *req_types.IncomingRequest) io.Reader { // Request handler with closure (make request for each partner in `[]partners`).
var outReqBody req_types.OutgoingRequest func handleRequest(partners []customtypes.PartnersAddress) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
var imps []req_types.Imp incReq, err := parseAndCheckIncomingRequest(w, r)
if err != nil {
log.Println(err)
}
// WARN: не знаю как правильно перемножать uint и float p_body := constructPartnersRequestBody(&incReq)
for _, tile := range ir.Tiles {
imps = append(imps, req_types.Imp{
Id: tile.Id,
Minwidth: tile.Width,
Minheight: uint(math.Floor(float64(tile.Width * uint(tile.Ratio))))})
}
outReqBody.Id = *ir.Id var partnersRespones []req_types.SuccesResponse
outReqBody.Imp = imps for _, p := range partners {
outReqBody.Context = ir.Context url := fmt.Sprintf("http://%v:%v", p.Ip, p.Port)
log.Println(*ir)
log.Println(outReqBody) re, err := sendRequest(url, &p_body)
t, _ := json.Marshal(outReqBody)
return bytes.NewReader(t) if err != nil {
log.Println(err)
continue
}
// adding only successful responses
partnersRespones = append(partnersRespones, re)
}
if len(partnersRespones) == 0 {
log.Println("Error: no responses from partners.")
return
}
// для каждого tile в incReq надо найти
// maxPrice := 0
// var bestOptionRespone req_types.SuccesResponse
var bestOptions []req_types.Imp
_ = bestOptions
for _, tile := range incReq.Tiles {
for _, partner := range partnersRespones {
}
}
}
} }

7
src/client_server/server.go

@ -3,11 +3,12 @@ package clientserver
import ( import (
"fmt" "fmt"
"net/http" "net/http"
customtypes "sample-choose-ad/src/custom_types"
) )
func StartServer(port string) { func StartServer(port string, partners []customtypes.PartnersAddress) {
http.HandleFunc("/placements/request", handleRequest)
http.HandleFunc("/placements/request", handleRequest(partners))
http.ListenAndServe(fmt.Sprintf(":%v", port), nil) http.ListenAndServe(fmt.Sprintf(":%v", port), nil)
} }

2
src/client_server/validators.go

@ -21,7 +21,7 @@ func wrongIPAddresFormat(ipv4 string) bool {
func throwHTTPError(err_text string, code int, w *http.ResponseWriter) { func throwHTTPError(err_text string, code int, w *http.ResponseWriter) {
http.Error(*w, err_text, code) http.Error(*w, err_text, code)
log.Printf("Error %d %v\n", code, err_text) log.Printf("Error: %d %v\n", code, err_text)
} }
func ParsePartnersAddress(ipAndPort string) (string, int64, error) { func ParsePartnersAddress(ipAndPort string) (string, int64, error) {

7
src/main.go

@ -22,14 +22,11 @@ import (
"strings" "strings"
) )
var partners []customtypes.PartnersAddress
func main() { func main() {
log.Println("Starting server") log.Println("Info: Starting server")
port := flag.String("p", "", "-p 5050") port := flag.String("p", "", "-p 5050")
addressesList := flag.String("d", "", "-d '10.10.10.10:5050,10.10.10.20:5050'") addressesList := flag.String("d", "", "-d '10.10.10.10:5050,10.10.10.20:5050'")
flag.Parse() flag.Parse()
if *port == "" { if *port == "" {
@ -41,7 +38,7 @@ func main() {
} }
// Parse first 10 ip:port pairs into `[]partners` slise // Parse first 10 ip:port pairs into `[]partners` slise
var partners []customtypes.PartnersAddress
for i, p := range strings.Split(*addressesList, ",") { for i, p := range strings.Split(*addressesList, ",") {
if i == 10 { if i == 10 {

Loading…
Cancel
Save