Move code from our old branch to this one.
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..921dbe8
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,8 @@
+bazel-bin
+bazel-genfiles
+bazel-istioApigeeAdapter
+bazel-out
+bazel-testlogs
+*.pb.go
+
+
diff --git a/BUILD b/BUILD
new file mode 100644
index 0000000..0aa7eec
--- /dev/null
+++ b/BUILD
@@ -0,0 +1,7 @@
+package(default_visibility = ["//visibility:public"])
+
+licenses(["notice"])
+
+load("@io_bazel_rules_go//go:def.bzl", "go_prefix")
+
+go_prefix("github.com/apid/istioApigeeAdapter")
diff --git a/WORKSPACE b/WORKSPACE
new file mode 100644
index 0000000..9f076a0
--- /dev/null
+++ b/WORKSPACE
@@ -0,0 +1,60 @@
+workspace(name = "com_github_apid_apigeeIstioAdapter")
+
+git_repository(
+ name = "io_bazel_rules_go",
+ commit = "87cdda3fc0fd65c63ef0316533be03ea4956f809",
+ remote = "https://github.com/bazelbuild/rules_go.git",
+)
+
+load("@io_bazel_rules_go//go:def.bzl", "go_repositories", "new_go_repository")
+go_repositories()
+
+git_repository(
+ name = "io_istio_mixer",
+ commit = "5bae502af7492b59d0a59d7f2e89bd95d1088efe",
+ remote = "https://github.com/istio/mixer.git",
+)
+
+# Replace the above with the below to build with your own local copy of mixer
+#local_repository(
+# name = "io_istio_mixer",
+# path = "PATH_TO_MIXER_CODE_ON_YOUR_BOX",
+#)
+
+git_repository(
+ name = "org_pubref_rules_protobuf",
+ commit = "9ede1dbc38f0b89ae6cd8e206a22dd93cc1d5637",
+ remote = "https://github.com/pubref/rules_protobuf",
+)
+load("@org_pubref_rules_protobuf//protobuf:rules.bzl", "proto_repositories")
+
+proto_repositories()
+
+load("@org_pubref_rules_protobuf//gogo:rules.bzl", "gogo_proto_repositories")
+
+gogo_proto_repositories()
+
+new_go_repository(
+ name = "com_github_golang_protobuf",
+ commit = "8ee79997227bf9b34611aee7946ae64735e6fd93",
+ importpath = "github.com/golang/protobuf",
+)
+
+new_go_repository(
+ name = "com_github_hashicorp_go_multierror",
+ commit = "ed905158d87462226a13fe39ddf685ea65f1c11f",
+ importpath = "github.com/hashicorp/go-multierror",
+)
+
+new_go_repository(
+ name = "com_github_hashicorp_errwrap",
+ commit = "7554cd9344cec97297fa6649b055a8c98c2a1e55",
+ importpath = "github.com/hashicorp/errwrap",
+)
+
+new_git_repository(
+ name = "com_github_googleapis_googleapis",
+ build_file = "bazel/BUILD.googleapis",
+ commit = "13ac2436c5e3d568bd0e938f6ed58b77a48aba15",
+ remote = "https://github.com/googleapis/googleapis.git",
+)
\ No newline at end of file
diff --git a/adapter/BUILD b/adapter/BUILD
new file mode 100644
index 0000000..cde5ace
--- /dev/null
+++ b/adapter/BUILD
@@ -0,0 +1,25 @@
+package(default_visibility = ["//visibility:public"])
+
+load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test")
+
+go_library(
+ name = "go_default_library",
+ srcs = [
+ "apigee.go",
+ "apigeeKeyChecker.go",
+ "apigeeReport.go",
+ ],
+ deps = [
+ "//adapter/config:go_default_library",
+ "@com_github_hashicorp_go_multierror//:go_default_library",
+ "@io_istio_mixer//pkg/adapter:go_default_library",
+ ],
+)
+
+go_test(
+ name = "small_tests",
+ size = "small",
+ srcs = ["apigeeKeyChecker_test.go"],
+ library = ":go_default_library",
+ deps = [],
+)
diff --git a/adapter/apigee.go b/adapter/apigee.go
new file mode 100644
index 0000000..cddcfb1
--- /dev/null
+++ b/adapter/apigee.go
@@ -0,0 +1,27 @@
+// Copyright 2017 Istio Authors
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package apigee
+
+import (
+ "istio.io/mixer/pkg/adapter"
+)
+
+// Register records the builders exposed by this adapter.
+// For the apigee adapter, we will eventually expose multiple builders, each for a different
+// aspect of the Apigee functionality.
+func Register(r adapter.Registrar) {
+ r.RegisterListsBuilder(newKeyCheckBuilder())
+ r.RegisterAccessLogsBuilder(newReportBuilder())
+}
diff --git a/adapter/apigeeKeyChecker.go b/adapter/apigeeKeyChecker.go
new file mode 100644
index 0000000..3aeeaf8
--- /dev/null
+++ b/adapter/apigeeKeyChecker.go
@@ -0,0 +1,100 @@
+// Copyright 2017 Istio Authors
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package apigee
+
+import (
+ "bytes"
+ "encoding/json"
+ "fmt"
+ "net/http"
+
+ "github.com/apid/istioApigeeAdapter/adapter/config"
+ "istio.io/mixer/pkg/adapter"
+)
+
+const (
+ checkName = "apigeeKeyChecker"
+ checkDesc = "Verify an API key from a parameter"
+)
+
+var checkConf = &config.VerifyKeyParams{}
+
+type keyCheckBuilder struct {
+ adapter.DefaultBuilder
+}
+
+type keyChecker struct {
+ keyParam string
+ organization string
+ environment string
+}
+
+type APIKeyBody struct {
+ APIKey string `json:"apiKey"`
+}
+
+func newKeyCheckBuilder() keyCheckBuilder {
+ return keyCheckBuilder{
+ adapter.NewDefaultBuilder(checkName, checkDesc, checkConf),
+ }
+}
+
+func (keyCheckBuilder) NewListsAspect(env adapter.Env, c adapter.Config) (adapter.ListsAspect, error) {
+ return newKeyChecker(c.(*config.VerifyKeyParams))
+}
+
+func newKeyChecker(c *config.VerifyKeyParams) (*keyChecker, error) {
+ return &keyChecker{
+ keyParam: c.KeyParameter,
+ organization: c.Organization,
+ environment: c.Environment,
+ }, nil
+}
+
+func (l *keyChecker) Close() error {
+ return nil
+}
+
+// CheckList is part of the interface for a "list checker" adapter. It's the part that
+// gets whatever the value is (we want it to be the API key in our case) and checks it.
+
+// Test command ./bazel-bin/cmd/client/mixc check -a target.service=f.default.svc.cluster.local --stringmap_attributes request.headers=x-api-key:1tu9pl04Srua2MtsAGtu6ViPxSYSSX2I
+
+func (l *keyChecker) CheckList(symbol string) (bool, error) {
+ fmt.Printf("*** Going to check \"%s\" against \"%s\"\n", symbol, l.organization)
+
+ edge_url := "https://" + l.organization + "-" + l.environment + ".apigee.net/edgemicro-auth/verifyApiKey"
+
+ fmt.Printf("*** edge_url \"%s\"\n", edge_url)
+
+ return verifyApiKey(symbol, edge_url), nil
+}
+
+func verifyApiKey(apiKey string, uri string) bool {
+ apiKeyBody := APIKeyBody{
+ APIKey: apiKey,
+ }
+ serializedBody, _ := json.Marshal(&apiKeyBody)
+ req, _ := http.NewRequest("POST", uri, bytes.NewBuffer(serializedBody))
+ req.Header.Add("x-dna-api-key", apiKey)
+ req.Header.Add("content-type", "application/json")
+ client := &http.Client{}
+ resp, _ := client.Do(req)
+ if resp.StatusCode != 200 {
+ return false
+ } else {
+ return true
+ }
+}
diff --git a/adapter/apigeeKeyChecker_test.go b/adapter/apigeeKeyChecker_test.go
new file mode 100644
index 0000000..b4a2f26
--- /dev/null
+++ b/adapter/apigeeKeyChecker_test.go
@@ -0,0 +1,2 @@
+package apigee
+
diff --git a/adapter/apigeeReport.go b/adapter/apigeeReport.go
new file mode 100644
index 0000000..7caa87c
--- /dev/null
+++ b/adapter/apigeeReport.go
@@ -0,0 +1,131 @@
+package apigee
+
+import (
+ "bytes"
+ "encoding/json"
+ "fmt"
+ "io"
+ "net/http"
+ "os"
+
+ "github.com/apid/istioApigeeAdapter/adapter/config"
+ me "github.com/hashicorp/go-multierror"
+ "istio.io/mixer/pkg/adapter"
+)
+
+type (
+ builder struct{ adapter.DefaultBuilder }
+
+ logger struct{ logStream io.Writer }
+
+ analyticsRecord struct {
+ ClientReceivedStartTimestamp int `json:"client_received_start_timestamp"`
+ ClientReceivedEndTimestamp int `json:"client_received_end_timestamp"`
+ RecordType string `json:"recordType"`
+ ApiProxy string `json:"apiproxy"`
+ RequestUri string `json:"request_uri"`
+ RequestPath string `json:"request_path"`
+ RequestVerb string `json:"request_verb"`
+ ClientIp string `json:"request_path"`
+ UserAgent string `json:"useragent"`
+ ApiProxyRevision string `json:"apiproxy_revision"`
+ ResponseStatusCode int `json:"response_status_code"`
+ ClientSentStartTimestamp int `json:"client_sent_start_timestamp"`
+ ClientSentEndTimestamp int `json:"client_sent_end_timestamp"`
+ DeveloperEmail string `json:"developer_email,omitempty"`
+ DeveloperApp string `json:"developer_app"`
+ AccessToken string `json:"access_token,omitempty"`
+ ClientId string `json:"client_id,omitempty"`
+ ApiProduct string `json:"api_product"`
+ }
+
+ analyticsRecordCollection struct {
+ Records []analyticsRecord `json:"records"`
+ }
+
+ edgemicroKeys struct {
+ Key string
+ Secret string
+ }
+)
+
+func newReportBuilder() builder {
+ return builder{adapter.NewDefaultBuilder(
+ "apigeeReport",
+ "Report logs to apigee",
+ &config.ReportParams{},
+ )}
+}
+
+func (builder) NewApplicationLogsAspect(env adapter.Env, cfg adapter.Config) (adapter.ApplicationLogsAspect, error) {
+ return newLogger(cfg)
+}
+
+func (builder) NewAccessLogsAspect(env adapter.Env, cfg adapter.Config) (adapter.AccessLogsAspect, error) {
+ return newLogger(cfg)
+}
+
+func newLogger(cfg adapter.Config) (*logger, error) {
+ c := cfg.(*config.ReportParams)
+
+ w := os.Stderr
+ if c.LogStream == config.STDOUT {
+ w = os.Stdout
+ }
+
+ return &logger{w}, nil
+}
+
+func (l *logger) Log(entries []adapter.LogEntry) error {
+ return l.log(entries)
+}
+
+func (l *logger) LogAccess(entries []adapter.LogEntry) error {
+ fmt.Println("*** here")
+ return l.log(entries)
+}
+
+func (l *logger) log(entries []adapter.LogEntry) error {
+ var recordsCollection []analyticsRecord
+
+ var errors *me.Error
+ for _, entry := range entries {
+
+ if err := writeJSON(l.logStream, entry); err != nil {
+ errors = me.Append(errors, err)
+ }
+
+ ax_data := analyticsRecord{
+ ClientReceivedStartTimestamp: 33,
+ DeveloperApp: "microgateway-demo",
+ }
+
+ recordsCollection = append(recordsCollection, ax_data)
+
+ }
+
+ res2B, _ := json.Marshal(recordsCollection)
+ fmt.Println(string(res2B))
+
+ return errors.ErrorOrNil()
+}
+
+func (l *logger) Close() error { return nil }
+
+func writeJSON(w io.Writer, le interface{}) error {
+ return json.NewEncoder(w).Encode(le)
+}
+
+func sendAnalyticsRecords(collection analyticsRecordCollection, keys edgemicroKeys, uri string) bool {
+ serializedBody, _ := json.Marshal(&collection)
+ req, _ := http.NewRequest("POST", uri, bytes.NewBuffer(serializedBody))
+ req.SetBasicAuth(keys.Key, keys.Secret)
+ req.Header.Add("content-type", "application/json")
+ client := &http.Client{}
+ resp, _ := client.Do(req)
+ if resp.StatusCode != 200 {
+ return false
+ } else {
+ return true
+ }
+}
diff --git a/adapter/config/BUILD b/adapter/config/BUILD
new file mode 100644
index 0000000..cdde8c7
--- /dev/null
+++ b/adapter/config/BUILD
@@ -0,0 +1,26 @@
+package(default_visibility = ["//visibility:public"])
+
+load("@org_pubref_rules_protobuf//gogo:rules.bzl", "gogoslick_proto_library")
+
+gogoslick_proto_library(
+ name = "go_default_library",
+ importmap = {
+ "gogoproto/gogo.proto": "github.com/gogo/protobuf/gogoproto",
+ },
+ imports = [
+ "external/com_github_gogo_protobuf",
+ "external/com_github_google_protobuf/src",
+ ],
+ inputs = [
+ "@com_github_google_protobuf//:well_known_protos",
+ "@com_github_gogo_protobuf//gogoproto:go_default_library_protos",
+ ],
+ protos = [
+ "config.proto",
+ ],
+ verbose = 0,
+ visibility = ["//adapter:__pkg__"],
+ deps = [
+ "@com_github_gogo_protobuf//gogoproto:go_default_library",
+ ],
+)
diff --git a/adapter/config/config.proto b/adapter/config/config.proto
new file mode 100644
index 0000000..6c3c680
--- /dev/null
+++ b/adapter/config/config.proto
@@ -0,0 +1,56 @@
+// Copyright 2017 Istio Authors
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+syntax = "proto3";
+
+package adapter.apigee.config;
+
+import "gogoproto/gogo.proto";
+
+option go_package="config";
+option (gogoproto.goproto_getters_all) = false;
+option (gogoproto.equal_all) = false;
+option (gogoproto.gostring_all) = false;
+
+message VerifyKeyParams {
+ // The name of the parameter where the API key is stored.
+ string key_parameter = 1;
+
+ string organization = 2;
+
+ string environment = 3;
+}
+
+message ReportParams {
+
+ // Stream is used to select between different logs output sinks.
+ enum Stream {
+ // STDERR refers to os.Stderr.
+ STDERR = 0;
+ // STDOUT refers to os.Stdout.
+ STDOUT = 1;
+ }
+
+ // Selects which standard stream to write to for log entries.
+ // STDERR is the default Stream.
+ Stream log_stream = 1;
+
+ string organization = 2;
+
+ string environment = 3;
+
+ string key = 4;
+
+ string secret = 5;
+}
diff --git a/bazel/BUILD.googleapis b/bazel/BUILD.googleapis
new file mode 100644
index 0000000..bf13dbe
--- /dev/null
+++ b/bazel/BUILD.googleapis
@@ -0,0 +1,52 @@
+package(default_visibility = ["//visibility:public"])
+
+load("@io_bazel_rules_go//go:def.bzl", "go_prefix")
+go_prefix("github.com/googleapis/googleapis")
+
+load("@org_pubref_rules_protobuf//gogo:rules.bzl", "gogoslick_proto_library")
+
+gogoslick_proto_library(
+ name = "google/rpc",
+ protos = [
+ "google/rpc/code.proto",
+ "google/rpc/error_details.proto",
+ "google/rpc/status.proto",
+ ],
+ importmap = {
+ "google/protobuf/any.proto": "github.com/gogo/protobuf/types",
+ "google/protobuf/duration.proto": "github.com/gogo/protobuf/types",
+ },
+ imports = [
+ "../../external/com_github_google_protobuf/src",
+ ],
+ inputs = [
+ "@com_github_google_protobuf//:well_known_protos",
+ ],
+ deps = [
+ "@com_github_gogo_protobuf//types:go_default_library",
+ ],
+ verbose = 0,
+)
+
+load("@org_pubref_rules_protobuf//cpp:rules.bzl", "cc_proto_library")
+
+cc_proto_library(
+ name = "cc_status_proto",
+ protos = [
+ "google/rpc/status.proto",
+ ],
+ imports = [
+ "../../external/com_github_google_protobuf/src",
+ ],
+ verbose = 0,
+)
+
+filegroup(
+ name = "status_proto",
+ srcs = [ "google/rpc/status.proto" ],
+)
+
+filegroup(
+ name = "code_proto",
+ srcs = [ "google/rpc/code.proto" ],
+)