Skip to content
This repository has been archived by the owner on Jul 12, 2023. It is now read-only.

Commit

Permalink
Make e2e-runner publish a real client (#1850)
Browse files Browse the repository at this point in the history
This gives us all the JSON parsing + automatic fallback and nice error messages when something fails. This commit changes the required configuration for `KEY_SERVER` from the full URL to the /publish endpoint to *just* the URL to the key server. Where previously you may have configured `KEY_SERVER=https://foo.bar/v1/publish`, please re-configure with `KEY_SERVER=https://foo.bar`. The system attempts to maintain backwards compatibility by parsing the URL, but this may be removed at a later date.
  • Loading branch information
sethvargo authored Feb 22, 2021
1 parent 3ccc3fb commit 2506813
Show file tree
Hide file tree
Showing 4 changed files with 37 additions and 37 deletions.
4 changes: 2 additions & 2 deletions cmd/e2e-runner/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -192,7 +192,7 @@ func handleEndToEnd(cfg *config.E2ERunnerConfig, h *render.Renderer) http.Handle
ctx := r.Context()

if err := clients.RunEndToEnd(ctx, cfg); err != nil {
renderJSONError(w, r, h, err)
renderJSONError(w, r, h, fmt.Errorf("failed to run end-to-end: %w", err))
return
}

Expand All @@ -213,7 +213,7 @@ func handleENXRedirect(client *clients.ENXRedirectClient, h *render.Renderer) ht
ctx := r.Context()

if err := client.RunE2E(ctx); err != nil {
renderJSONError(w, r, h, err)
renderJSONError(w, r, h, fmt.Errorf("failed to run enx-redirect: %w", err))
return
}

Expand Down
46 changes: 12 additions & 34 deletions internal/clients/e2e.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,10 @@
package clients

import (
"bytes"
"context"
"crypto/rand"
"encoding/base64"
"encoding/json"
"fmt"
"net/http"
"time"

verifyapi "github.com/google/exposure-notifications-server/pkg/api/v1"
Expand Down Expand Up @@ -87,13 +84,19 @@ func RunEndToEnd(ctx context.Context, cfg *config.E2ERunnerConfig) error {
adminAPIClient, err := NewAdminAPIServerClient(cfg.VerificationAdminAPIServer, cfg.VerificationAdminAPIKey,
WithTimeout(timeout))
if err != nil {
return err
return fmt.Errorf("failed to make adminapi server client: %w", err)
}

apiServerClient, err := NewAPIServerClient(cfg.VerificationAPIServer, cfg.VerificationAPIServerKey,
WithTimeout(timeout))
if err != nil {
return err
return fmt.Errorf("failed to make apiserver client: %w", err)
}

keyServerClient, err := NewKeyServerClient(cfg.KeyServer,
WithTimeout(timeout))
if err != nil {
return fmt.Errorf("failed to make keyserver client: %w", err)
}

testType := "confirmed"
Expand Down Expand Up @@ -256,48 +259,23 @@ func RunEndToEnd(ctx context.Context, cfg *config.E2ERunnerConfig) error {
defer recordLatency(ctx, time.Now(), "upload_to_key_server")
// Make the publish request.
logger.Infof("Publish TEKs to the key server")

publishReq := &verifyapi.Publish{
Keys: teks,
HealthAuthorityID: cfg.HealthAuthorityCode,
VerificationPayload: certificate.Certificate,
HMACKey: base64.StdEncoding.EncodeToString(hmacSecret),
RevisionToken: revisionToken,
}

client := &http.Client{
Timeout: timeout,
}

var b bytes.Buffer
if err := json.NewEncoder(&b).Encode(publishReq); err != nil {
return nil, err
}

httpReq, err := http.NewRequestWithContext(ctx, http.MethodPost, cfg.KeyServer, &b)
if err != nil {
return nil, err
}
httpReq.Header.Set("Content-Type", "application/json")

httpResp, err := client.Do(httpReq)
if err != nil {
result = enobs.ResultNotOK
return nil, fmt.Errorf("error making request to publish teks: %w", err)
}
defer httpResp.Body.Close()

var publishResp verifyapi.PublishResponse
if err := json.NewDecoder(httpResp.Body).Decode(&publishResp); err != nil {
return nil, err
}
publishResp, err := keyServerClient.Publish(ctx, publishReq)
defer logger.Debugw("publish", "request", publishReq, "response", publishResp)
if publishResp.ErrorMessage != "" {
result = enobs.ResultNotOK
logger.Infow("failed to publish teks", "error", err, "keys", teks)
logger.Errorw("failed to publish teks", "error", err, "keys", teks)
return nil, fmt.Errorf("publish API error: %+v", publishResp)
}
logger.Infof("Inserted %v exposures", publishResp.InsertedExposures)
return &publishResp, nil
return publishResp, nil
}()
if err != nil {
return err
Expand Down
22 changes: 22 additions & 0 deletions internal/clients/key_server.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import (
"context"
"fmt"
"net/http"
"strings"

keyserver "github.com/google/exposure-notifications-server/pkg/api/v1"
)
Expand All @@ -34,11 +35,32 @@ func NewKeyServerClient(base string, opts ...Option) (*KeyServerClient, error) {
return nil, err
}

// To maintain backwards-compatibility with older implementations that wanted
// KEY_SERVER as the full URL to the publish endpoint, strip off anything
// after /v1.
if idx := strings.Index(client.baseURL.Path, "/v1"); idx != -1 {
client.baseURL.Path = client.baseURL.Path[0:idx]
}

return &KeyServerClient{
client: client,
}, nil
}

// Publish uploads TEKs to the key server
func (c *KeyServerClient) Publish(ctx context.Context, in *keyserver.Publish) (*keyserver.PublishResponse, error) {
req, err := c.newRequest(ctx, http.MethodPost, "/v1/publish", in)
if err != nil {
return nil, err
}

var out keyserver.PublishResponse
if err := c.doOK(req, &out); err != nil {
return &out, err
}
return &out, nil
}

// Stats calls the /v1/stats endpoint to get key-server statistics.
func (c *KeyServerClient) Stats(ctx context.Context, in *keyserver.StatsRequest, authToken string) (*keyserver.StatsResponse, error) {
req, err := c.newRequest(ctx, http.MethodPost, "/v1/stats", in)
Expand Down
2 changes: 1 addition & 1 deletion terraform/services.tf
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ locals {

e2e_runner_config = {
HEALTH_AUTHORITY_CODE = "com.example"
KEY_SERVER = "https://example.com/v1/publish"
KEY_SERVER = "https://example.com"
VERIFICATION_ADMIN_API = local.enable_lb ? "https://${var.adminapi_hosts[0]}" : google_cloud_run_service.adminapi.status.0.url
VERIFICATION_SERVER_API = local.enable_lb ? "https://${var.apiserver_hosts[0]}" : google_cloud_run_service.apiserver.status.0.url
E2E_SKIP_SMS = var.e2e_skip_sms
Expand Down

0 comments on commit 2506813

Please sign in to comment.