Added x509 and jwt rapps

Change-Id: Ic384fcad11dcb63fe4265d3dbcff5ea17f933cfc
diff --git a/rapps/rapps-rapp-jwt-invoker.go b/rapps/rapps-rapp-jwt-invoker.go
new file mode 100644
index 0000000..de806ca
--- /dev/null
+++ b/rapps/rapps-rapp-jwt-invoker.go
@@ -0,0 +1,174 @@
+package main
+
+import (
+	"bytes"
+	"encoding/json"
+	"flag"
+	"fmt"
+	"io/ioutil"
+	"net/http"
+	"net/url"
+	"strings"
+	"time"
+	"rapps/utils/generatejwt"
+)
+
+type Jwttoken struct {
+	Access_token       string
+	Expires_in         int
+	Refresh_expires_in int
+	Refresh_token      string
+	Token_type         string
+	Not_before_policy  int
+	Session_state      string
+	Scope              string
+}
+
+var gatewayHost string
+var gatewayPort string
+var keycloakHost string
+var keycloakPort string
+var keycloakAlias string
+var securityEnabled string
+var useGateway string
+var role string
+var rapp string
+var methods string
+var realmName string
+var clientId string
+var healthy bool = true
+var ttime time.Time
+var jwt Jwttoken
+
+const (
+	namespace = "istio-nonrtric"
+	scope     = "email"
+	client_assertion_type = "urn:ietf:params:oauth:client-assertion-type:jwt-bearer"
+)
+
+func getToken() string {
+	if ttime.Before(time.Now()) {
+		client_assertion := getClientAssertion()
+		keycloakUrl := "http://" + keycloakHost + ":" + keycloakPort + "/auth/realms/" + realmName + "/protocol/openid-connect/token"
+		resp, err := http.PostForm(keycloakUrl, url.Values{"client_assertion_type": {client_assertion_type}, 
+		             "client_assertion": {client_assertion}, "grant_type": {"client_credentials"}, "client_id": {clientId}, 
+			     "scope": {scope}})
+		if err != nil {
+			fmt.Println(err)
+			panic("Something wrong with the credentials or url ")
+		}
+		defer resp.Body.Close()
+		body, err := ioutil.ReadAll(resp.Body)
+		json.Unmarshal([]byte(body), &jwt)
+		ttime = time.Now()
+		ttime = ttime.Add(time.Second * time.Duration(jwt.Expires_in))
+	}
+	return jwt.Access_token
+}
+
+func getClientAssertion() string {
+	realm := "http://" + keycloakHost + ":" + keycloakPort + "/auth/realms/" + realmName
+        clientAssertion := generatejwt.CreateJWT("/certs/client.key", "/certs/client_pub.key", "", clientId, realm)	
+        return clientAssertion 
+}
+
+func MakeRequest(client *http.Client, prefix string, method string, ch chan string) {
+	var service = strings.Split(prefix, "/")[1]
+	var gatewayUrl = "http://" + gatewayHost + ":" + gatewayPort
+	var token = ""
+	var jsonValue []byte = []byte{}
+	var restUrl string = ""
+
+	if securityEnabled == "true" {
+		token = getToken()
+	} else {
+		useGateway = "N"
+	}
+
+	if strings.ToUpper(useGateway) != "Y" {
+		gatewayUrl = "http://" + service + "." + namespace + ":80"
+		prefix = ""
+	}
+
+	restUrl = gatewayUrl + prefix
+
+	req, err := http.NewRequest(method, restUrl, bytes.NewBuffer(jsonValue))
+	if err != nil {
+		fmt.Printf("Got error %s", err.Error())
+	}
+	req.Header.Set("Content-type", "application/json")
+	req.Header.Set("Authorization", "Bearer "+token)
+
+	resp, err := client.Do(req)
+	if err != nil {
+		fmt.Printf("Got error %s", err.Error())
+	}
+	defer resp.Body.Close()
+	body, _ := ioutil.ReadAll(resp.Body)
+
+	respString := string(body[:])
+	if respString == "RBAC: access denied" {
+		respString += " for " + service + " " + strings.ToLower(method) + " request"
+	}
+	fmt.Printf("Received response for %s %s request - %s\n", service, strings.ToLower(method), respString)
+	ch <- prefix + "," + method
+}
+
+func health(res http.ResponseWriter, req *http.Request) {
+	if healthy {
+		res.WriteHeader(http.StatusOK)
+		res.Write([]byte("healthy"))
+	} else {
+		res.WriteHeader(http.StatusInternalServerError)
+		res.Write([]byte("unhealthy"))
+	}
+}
+
+func main() {
+	ttime = time.Now()
+	time.Sleep(1 * time.Second)
+	flag.StringVar(&gatewayHost, "gatewayHost", "istio-ingressgateway.istio-system", "Gateway Host")
+	flag.StringVar(&gatewayPort, "gatewayPort", "80", "Gateway Port")
+	flag.StringVar(&keycloakHost, "keycloakHost", "istio-ingressgateway.istio-system", "Keycloak Host")
+	flag.StringVar(&keycloakPort, "keycloakPort", "80", "Keycloak Port")
+	flag.StringVar(&useGateway, "useGateway", "Y", "Connect to services through API gateway")
+	flag.StringVar(&securityEnabled, "securityEnabled", "true", "Security is required to use this application")
+	flag.StringVar(&realmName, "realm", "jwt", "Keycloak realm")
+	flag.StringVar(&clientId, "client", "jwtprovider-cli", "Keycloak client")
+	flag.StringVar(&role, "role", "provider-viewer", "Role granted to application")
+	flag.StringVar(&rapp, "rapp", "rapp-jwt-provider", "Name of rapp to invoke")
+	flag.StringVar(&methods, "methods", "GET", "Methods to access application")
+	flag.Parse()
+
+	healthHandler := http.HandlerFunc(health)
+	http.Handle("/health", healthHandler)
+	go func() {
+		http.ListenAndServe(":9000", nil)
+	}()
+
+	client := &http.Client{
+		Timeout: time.Second * 10,
+	}
+
+	ch := make(chan string)
+	var prefixArray []string = []string{"/" + rapp}
+	var methodArray []string = []string{methods}
+	for _, prefix := range prefixArray {
+		for _, method := range methodArray {
+			go MakeRequest(client, prefix, method, ch)
+		}
+	}
+
+	ioutil.WriteFile("init.txt", []byte("Initialization done."), 0644)
+
+	for r := range ch {
+		go func(resp string) {
+			time.Sleep(10 * time.Second)
+			elements := strings.Split(resp, ",")
+			prefix := elements[0]
+			method := elements[1]
+			MakeRequest(client, prefix, method, ch)
+		}(r)
+	}
+
+}