Skip to content
Snippets Groups Projects
Commit 406b43e4 authored by Ronny Gulberg's avatar Ronny Gulberg
Browse files

Updated webhooks and Readme

parent 1eb08908
No related branches found
No related tags found
No related merge requests found
......@@ -7,12 +7,29 @@ Assignment 2 in IMT2681 2019
-The commit endpoint---
I used paging to get most of the results
The max commits for an id is therefore 300, but only a few repos have this many commits.
The max commits for an id is set to 300, but only a few repos have this many commits.
The search for repo ids start at 200 and ends at 300
Everything should work with the commit endpoint.
The parameters must be provided either in pairs(limit/token) or single(/limit) or none.
The limit must always come first because of the way it's coded
The limit has to come first because of the way it's coded
There's regrettably some patience involved, waiting for the response
--THe ?????? endpoint-----
--The Language endpoint-----
It only works when both limit and token is provided regardless of order
ex: http://localhost:8080/repocheck/v1/languages/?limit=5&token=%22dsddsdsd%22
--Webhooks--
only work locally, and have not been deployed to a remote or online third party service
Not implemented consistent storage for the webhook data
--Final Note---
I completely forgot about implementing tests while coding. Some tests have been included post implementation
......@@ -8,12 +8,13 @@ import (
"../commits"
"../languages"
"../status"
"../webhooks"
"time"
// "strings"
// "strconv"
)
//Global var keeps track of when server starts
//Global vars keeping track of time and when server starts
var startTime time.Time
func defaultHandler(w http.ResponseWriter, r *http.Request) {
......@@ -22,14 +23,20 @@ func defaultHandler(w http.ResponseWriter, r *http.Request) {
fmt.Fprint(w, "To inquire the service, please use following paths:\n")
fmt.Fprint(w, "/repocheck/v1/commits/<limit>/<auth-token>\n")
fmt.Fprint(w, "/repocheck/v1/languages/\n")
fmt.Fprint(w, "/repocheck/v1/issues/\n")
fmt.Fprint(w, "/repocheck/v1/status/\n")
fmt.Fprint(w, "To register webhook and see webhooks:\n")
fmt.Fprint(w, "/repocheck/v1/webhook\n")
fmt.Fprint(w, "/repocheck/v1/services")
}
func main() {
port := os.Getenv("PORT")//Port for remote internet
port := "8080"
if os.Getenv("PORT") != "" {
port = os.Getenv("PORT")//Port for remote internet
}
apiVersion := "v1" //API version
//port = "5050" //Port set for local development only
if port == "" {
......@@ -43,8 +50,10 @@ func main() {
http.HandleFunc("/repocheck/v1/", defaultHandler)
http.HandleFunc("/repocheck/v1/commits/", commits.CommitsHandler)
http.HandleFunc("/repocheck/v1/languages/", languages.LanguagesHandler)
// http.HandleFunc("/repocheck/v1/issues/",IssuesHandler)
http.HandleFunc("/repocheck/v1/status/", status.StatusHandler)
http.HandleFunc("/repocheck/v1/webhook/", webhooks.WebhookHandler)
http.HandleFunc("/repocheck/v1/services/", webhooks.ServiceHandler)
fmt.Println("Serving and listening on port " + port)
log.Fatal(http.ListenAndServe(":"+port, nil))
}
package main
import (
"fmt"
"io/ioutil"
"log"
"net/http"
"os"
)
/*
Dummy handler printing everything it recieves to the console
and confirms recipe to requester
*/
func InvokedHandler(w http.ResponseWriter, r *http.Request) {
//Simply print the body
content,err := ioutil.ReadAll(r.Body)
if err != nil {
fmt.Println("Error when reading body: " + err.Error())
http.Error(w, "Error when reading body " +err.Error(), http.StatusBadRequest)
}
fmt.Println("Recieved invocation(call) with method " + r.Method + " and body: " + string(content))
//Send response to sender
_, err = fmt.Fprint(w, "Successfully invoked dummy web service.")
if err != nil {
fmt.Println("Something went wrong when sending response: " + err.Error())
}
}
func main() {
port := "8081"
if os.Getenv("PORT") != "" {
port = os.Getenv("PORT")
}
http.HandleFunc("/invokedUrl/", InvokedHandler)
fmt.Println("Service listening on port " + port)
fmt.Println("Service Url: http://localhost: " + port + "/invokedUrl")
log.Fatal(http.ListenAndServe(":" + port, nil))
}
package webhooks
import(
"bytes"
"encoding/json"
"fmt"
"io/ioutil"
"net/http"
"strconv"
"time"
// "log"
)
//Webhooks is the structure that holds all the webhooks
var Webhooks []WebhookRegistration
//Instance of array that store data to be inquired by user for each webhook
var webhooksData = WebhookStorage{}
/*
Handles webhook registration POST and lookup GET
MUst have webhookRegistration struct in the request body
*/
func WebhookHandler(w http.ResponseWriter, r *http.Request) {
switch r.Method {
case http.MethodPost:
// Expects incoming body in terms of WebhookRegistration struct
webhook := WebhookRegistration{}
err := json.NewDecoder(r.Body).Decode(&webhook)
if err != nil {
http.Error(w, "Something went wrong: " + err.Error(), http.StatusBadRequest)
}
Webhooks = append(Webhooks, webhook)
id := len(Webhooks) -1
var tempslice = WebhookStoragedata{
Id : id,
Event : Webhooks[id].Event,
Url : Webhooks[id].Url,
Timestamp : time.Now(),
}
// Note: Approach does not guarantee persistence or permanence of resource id (for CRUD)
//Init the struct for GET requests to this endpoint
webhooksData.Webhooksdata = append(webhooksData.Webhooksdata, tempslice)
fmt.Fprintln(w, len(Webhooks)-1)
fmt.Println("Webhook " + webhook.Url + " has been registered.")
case http.MethodGet:
// Return all webhooks with data
err := json.NewEncoder(w).Encode(webhooksData)
if err != nil {
http.Error(w, "Something went wrong: " + err.Error(), http.StatusInternalServerError)
}
default: http.Error(w, "Invalid method " + r.Method, http.StatusBadRequest)
}
}
func ServiceHandler (w http.ResponseWriter, r *http.Request) {
switch r.Method {
case http.MethodPost:
fmt.Println("Recieved post request")
for _,v := range Webhooks {
go CallUrl(v.Url, "Response on regstered event in webhook demo:" + v.Event)
}
default:
http.Error(w, "Invalid or not implemented Method " + r.Method, http.StatusBadRequest)
}
}
//Calls given URL with givem content and awaits response (status and body)
func CallUrl (url string, content string) {
fmt.Println("Attempting call to url " + url + "...")
res,err := http.Post(url, "string", bytes.NewReader([]byte(content)))
if err != nil {
fmt.Println("Something is wrong with the call response: " + err.Error())
}
response, err := ioutil.ReadAll(res.Body)
if err != nil {
fmt.Println("Something is wrong with invocation response:" + err.Error())
}
fmt.Println("Webhook called upon. Got statuscode: " + strconv.Itoa(res.StatusCode) + " and body: " + string(response))
}
package webhooks
import "time"
type WebhookRegistration struct {
Url string `json:"url"`
Event string `json:"event"`
}
//STructs for storing the data for each webhook
type WebhookStoragedata struct {
Id int
Event string
Url string
Timestamp time.Time
}
type WebhookStorage struct {
Webhooksdata []WebhookStoragedata
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment