Example #1
0
/* test cases */
func Test_WebPipeEndToEndRequestsShouldSucceed(t *testing.T) {
	/* server side logic */
	itemsMap := make(map[string]string)
	createItemApi := func(request *webpipe.Request, response *webpipe.Response, _ webpipe.Context) error {
		id := uuid.NewV4().String()
		if data, err := request.Payload.Bytes(); err != nil {
			return err
		} else {
			itemsMap[id] = string(data)
		}

		response.Payload = webpipe.CreateBytesPayload([]byte(id))
		return nil
	}

	getItemApi := func(request *webpipe.Request, response *webpipe.Response, _ webpipe.Context) error {
		id := request.Params.Get("item_id")
		if item, ok := itemsMap[id]; ok {
			response.Payload = webpipe.CreateBytesPayload([]byte(item))
		}
		return nil
	}

	/* prepare server pipe */
	serverHandlers := []webpipe.DelegatingHandler{
		func(request *webpipe.Request, response *webpipe.Response, context webpipe.Context) {
			startTime := time.Now()                                  /* get start timestamp */
			context.Next(request, response)                          /* invoke the remaining part in the stack */
			duration := time.Now().Sub(startTime)                    /* calculate elapsed duration */
			response.Header.Set("X-API-DURATION", duration.String()) /* fill the duration header */
		},

		func(request *webpipe.Request, response *webpipe.Response, context webpipe.Context) {
			authHeader, found := request.Header["Authorization"] /* check auth header */
			if !found || len(authHeader) == 0 {
				response.StatusCode = http.StatusForbidden /* forbid calling without auth header */
			} else {
				if authHeader[0] != "Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==" {
					response.StatusCode = http.StatusUnauthorized /* do authorization */
				} else {
					context.Next(request, response) /* invoke the remaining part in the stack */
				}
			}
		},
	}

	server := webpipe.CreateServer(serverHandlers)
	server.Register("POST", "/items", nil, createItemApi)
	server.Register("GET", "/items/:item_id", nil, getItemApi)
	go server.Listen(8082)

	/* prepare client pipe */
	invokePerfLog := []string{}
	clientHandlers := []webpipe.DelegatingHandler{
		func(request *webpipe.Request, response *webpipe.Response, context webpipe.Context) {
			request.Header.Set("Authorization", "Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==") /* set auth header */
			context.Next(request, response)                                           /* invoke the remaining part in the stack */
		},

		func(request *webpipe.Request, response *webpipe.Response, context webpipe.Context) {
			context.Next(request, response) /* invoke the rpc first */
			duration := response.Header.Get("X-API-DURATION")
			invokePerfLog = append(invokePerfLog, duration)
		},
	}

	/* client side invocations */
	client := webpipe.CreateClient("http://localhost:8082", clientHandlers)
	req := client.NewRequest("POST")
	req.Payload = webpipe.CreateBytesPayload([]byte("bytes payload for item"))
	resp, err := client.Invoke("/items", req)

	/* assertion 1 */
	Nil(t, err)
	Equal(t, http.StatusCreated, resp.StatusCode)
	Equal(t, 1, len(invokePerfLog))
	Equal(t, 1, len(itemsMap))
	id, err := resp.Payload.Bytes()
	Nil(t, err)
	False(t, len(id) == 0)

	req = client.NewRequest("GET")
	req.Params.Set("item_id", string(id))
	resp, err = client.Invoke("/items/:item_id", req)

	/* assertion 2 */
	Nil(t, err)
	Equal(t, http.StatusOK, resp.StatusCode)
	Equal(t, 2, len(invokePerfLog))
	body, err := resp.Payload.Bytes()
	Nil(t, err)
	Equal(t, "bytes payload for item", string(body))
}
Example #2
0
func Test_InvokeHttpBasicRequestsShouldSucceed(t *testing.T) {
	/* prepare http router */
	router := httprouter.New()
	var itemsGetReq *http.Request = nil
	var itemsGetPar httprouter.Params
	router.GET("/items", func(w http.ResponseWriter, r *http.Request, p httprouter.Params) {
		itemsGetReq = r
		itemsGetPar = p
		io.WriteString(w, "ACK")
	})

	router.GET("/items/:item_id", func(w http.ResponseWriter, r *http.Request, p httprouter.Params) {
		itemsGetReq = r
		itemsGetPar = p
		io.WriteString(w, "ACK")
	})

	var itemsPatchReq *http.Request = nil
	var itemsPatchPar httprouter.Params
	var itemsPatchBody []byte
	router.PATCH("/items/:item_id", func(w http.ResponseWriter, r *http.Request, p httprouter.Params) {
		itemsPatchReq = r
		itemsPatchPar = p
		itemsPatchBody = make([]byte, r.ContentLength)
		io.ReadAtLeast(r.Body, itemsPatchBody, int(r.ContentLength))
		io.WriteString(w, "PATCHED")
	})

	go http.ListenAndServe(":8081", router)

	/* invoke get items API */
	client := webpipe.CreateClient("http://localhost:8081", nil)
	request := client.NewRequest("GET")
	request.Queries.Add("id", "123")
	response, err := client.Invoke("/items", request)
	Nil(t, err)

	/* assertions */
	Equal(t, "/items?id=123", itemsGetReq.URL.String())
	payload, err := response.Payload.Bytes()
	Nil(t, err)
	Equal(t, "ACK", string(payload))
	Equal(t, 0, len(itemsGetPar))

	/* invoke again without queries */
	request = client.NewRequest("GET")
	request.Params.Set("item_id", "100")
	response, err = client.Invoke("/items/:item_id", request)
	Nil(t, err)
	Equal(t, "/items/100", itemsGetReq.URL.String())
	payload, err = response.Payload.Bytes()
	Nil(t, err)
	Equal(t, "ACK", string(payload))
	Equal(t, 1, len(itemsGetPar))
	Equal(t, "100", itemsGetPar.ByName("item_id"))

	/* now patch with some data */
	data := make(map[string]interface{})
	data["key1"] = "hello"
	data["key2"] = 100
	request = client.NewRequest("PATCH")
	request.Params.Set("item_id", "500")
	request.Queries.Set("method", "full_update")
	request.Payload, err = webpipe.CreateJSONPayload(data)
	Nil(t, err)
	response, err = client.Invoke("items/:item_id", request)
	Nil(t, err)
	Equal(t, "/items/500?method=full_update", itemsPatchReq.URL.String())
	Equal(t, 1, len(itemsPatchPar))
	Equal(t, "500", itemsPatchPar.ByName("item_id"))
	Equal(t, "{\"key1\":\"hello\",\"key2\":100}", string(itemsPatchBody))
}