diff --git a/cmd/mock_server.go b/cmd/mock_server.go
index fb84e62..fbfe1c0 100644
--- a/cmd/mock_server.go
+++ b/cmd/mock_server.go
@@ -24,7 +24,7 @@ import (
"syscall"
mocktrace "github.com/googleinterns/cloud-operations-api-mock/api"
-
+ "github.com/googleinterns/cloud-operations-api-mock/internal/validation"
"github.com/googleinterns/cloud-operations-api-mock/server/metric"
"github.com/googleinterns/cloud-operations-api-mock/server/trace"
"google.golang.org/genproto/googleapis/devtools/cloudtrace/v2"
@@ -43,6 +43,13 @@ var (
"If flag is set, a summary page HTML file will be generated")
)
+// summaryTable wraps the summaries for both trace and metrics,
+// and is used to pass data to the HTML template.
+type summaryTable struct {
+ Spans []*cloudtrace.Span
+ MetricDescriptors []*validation.DescriptorStatus
+}
+
func main() {
flag.Parse()
startStandaloneServer()
@@ -60,10 +67,13 @@ func startStandaloneServer() {
}
grpcServer := grpc.NewServer()
+
mockTraceServer := trace.NewMockTraceServer()
cloudtrace.RegisterTraceServiceServer(grpcServer, mockTraceServer)
mocktrace.RegisterMockTraceServiceServer(grpcServer, mockTraceServer)
- monitoring.RegisterMetricServiceServer(grpcServer, metric.NewMockMetricServer())
+
+ mockMetricServer := metric.NewMockMetricServer()
+ monitoring.RegisterMetricServiceServer(grpcServer, mockMetricServer)
log.Printf("Listening on %s\n", lis.Addr().String())
@@ -77,7 +87,8 @@ func startStandaloneServer() {
<-sig
grpcServer.GracefulStop()
if *summary {
- writeSummaryPage(mockTraceServer.ResultTable())
+ summaryTable := createSummaryTable(mockTraceServer.SpansSummary(), mockMetricServer.MetricDescriptorSummary())
+ writeSummaryPage(summaryTable)
}
finish <- true
}()
@@ -88,14 +99,21 @@ func startStandaloneServer() {
<-finish
}
+func createSummaryTable(spans []*cloudtrace.Span, descriptors []*validation.DescriptorStatus) summaryTable {
+ return summaryTable{
+ Spans: spans,
+ MetricDescriptors: descriptors,
+ }
+}
+
// writeSummaryPage creates summary.html from the results and the template HTML.
-func writeSummaryPage(results []*cloudtrace.Span) {
+func writeSummaryPage(table summaryTable) {
outputFile, err := os.Create("../static/summary.html")
if err != nil {
panic(err)
}
t := template.Must(template.ParseFiles("../static/summary_template.html"))
- err = t.Execute(outputFile, results)
+ err = t.Execute(outputFile, table)
if err != nil {
panic(err)
}
diff --git a/internal/validation/mock_metric_validation.go b/internal/validation/mock_metric_validation.go
index b3d824f..904d9cc 100644
--- a/internal/validation/mock_metric_validation.go
+++ b/internal/validation/mock_metric_validation.go
@@ -19,6 +19,7 @@ import (
"reflect"
"regexp"
"strings"
+ "sync"
"time"
"github.com/golang/protobuf/ptypes"
@@ -42,11 +43,26 @@ const (
// Service name regex sourced from https://github.com/asaskevich/govalidator/blob/master/patterns.go#L33
var (
labelKeyRegex = regexp.MustCompile("[a-z][a-zA0-9_-]*")
- serviceNameRegex = regexp.MustCompile(`^([a-zA-Z0-9_]{1}[a-zA-Z0-9_-]{0,62}){1}(\.[a-zA-Z0-9_]{1}[a-zA-Z0-9_-]{0,62})*[\._]?$`)
+ serviceNameRegex = regexp.MustCompile(`^([a-zA-Z0-9_]{1}[a-zA-Z0-9_-]{0,62}){1}(\.[a-zA-Z0-9_]{1}[a-zA-Z0-9_-]{0,62})*[._]?$`)
relativeMetricNameRegex = regexp.MustCompile("[A-Za-z0-9_/]{1,100}")
- diplayNameRegex = regexp.MustCompile(`opentelemetry\/.*`)
+ displayNameRegex = regexp.MustCompile(`opentelemetry/.*`)
)
+// MetricDescriptorStatus wraps a MetricDescriptor with the status of its creation.
+// Used in the MetricDescriptor summary table.
+type DescriptorStatus struct {
+ MetricDescriptor *metric.MetricDescriptor
+ Status string
+}
+
+// MetricDescriptorData is a wrapper struct for all the data that the server
+// keeps with respect to metric descriptors.
+type MetricDescriptorData struct {
+ UploadedMetricDescriptors map[string]*metric.MetricDescriptor
+ MetricDescriptorSummary []*DescriptorStatus
+ MetricDescriptorsLock sync.Mutex
+}
+
// PreviousPoint contains information about the most recently uploaded
// point for a time series.
type PreviousPoint struct {
@@ -142,7 +158,7 @@ func validateLabels(labels []*lbl.LabelDescriptor) error {
}
func validateMetricDisplayName(displayName string) error {
- if !diplayNameRegex.MatchString(displayName) {
+ if !displayNameRegex.MatchString(displayName) {
return statusInvalidDisplayName
}
diff --git a/server/metric/mock_metric.go b/server/metric/mock_metric.go
index 4714b17..7d4d33a 100644
--- a/server/metric/mock_metric.go
+++ b/server/metric/mock_metric.go
@@ -31,19 +31,21 @@ import (
// uploaded data.
type MockMetricServer struct {
monitoring.UnimplementedMetricServiceServer
- uploadedMetricDescriptors map[string]*metric.MetricDescriptor
- uploadedMetricDescriptorsLock sync.Mutex
- uploadedPoints map[string]*validation.PreviousPoint
- uploadedPointsLock sync.Mutex
+ metricDescriptorData *validation.MetricDescriptorData
+ uploadedPoints map[string]*validation.PreviousPoint
+ uploadedPointsLock sync.Mutex
}
// NewMockMetricServer creates a new MockMetricServer and returns a pointer to it.
func NewMockMetricServer() *MockMetricServer {
uploadedMetricDescriptors := make(map[string]*metric.MetricDescriptor)
+ metricDescriptorData := &validation.MetricDescriptorData{
+ UploadedMetricDescriptors: uploadedMetricDescriptors,
+ }
uploadedPoints := make(map[string]*validation.PreviousPoint)
return &MockMetricServer{
- uploadedMetricDescriptors: uploadedMetricDescriptors,
- uploadedPoints: uploadedPoints,
+ metricDescriptorData: metricDescriptorData,
+ uploadedPoints: uploadedPoints,
}
}
@@ -77,9 +79,9 @@ func (s *MockMetricServer) GetMetricDescriptor(ctx context.Context, req *monitor
return nil, err
}
- s.uploadedMetricDescriptorsLock.Lock()
- defer s.uploadedMetricDescriptorsLock.Unlock()
- metricDescriptor, err := validation.AccessMetricDescriptor(s.uploadedMetricDescriptors, req.Name)
+ s.metricDescriptorData.MetricDescriptorsLock.Lock()
+ defer s.metricDescriptorData.MetricDescriptorsLock.Unlock()
+ metricDescriptor, err := validation.AccessMetricDescriptor(s.metricDescriptorData.UploadedMetricDescriptors, req.Name)
if err != nil {
return nil, err
}
@@ -92,23 +94,28 @@ func (s *MockMetricServer) GetMetricDescriptor(ctx context.Context, req *monitor
func (s *MockMetricServer) CreateMetricDescriptor(ctx context.Context, req *monitoring.CreateMetricDescriptorRequest,
) (*metric.MetricDescriptor, error) {
if err := validation.ValidateRequiredFields(req); err != nil {
+ addMetricDescriptorToSummary(&s.metricDescriptorData.MetricDescriptorSummary, req.MetricDescriptor, err.Error())
return nil, err
}
if err := validation.ValidateProjectName(req.Name); err != nil {
+ addMetricDescriptorToSummary(&s.metricDescriptorData.MetricDescriptorSummary, req.MetricDescriptor, err.Error())
return nil, err
}
if err := validation.ValidateCreateMetricDescriptor(req.MetricDescriptor); err != nil {
+ addMetricDescriptorToSummary(&s.metricDescriptorData.MetricDescriptorSummary, req.MetricDescriptor, err.Error())
return nil, err
}
- s.uploadedMetricDescriptorsLock.Lock()
- defer s.uploadedMetricDescriptorsLock.Unlock()
- if err := validation.AddMetricDescriptor(s.uploadedMetricDescriptors, req.MetricDescriptor.Type, req.MetricDescriptor); err != nil {
+ s.metricDescriptorData.MetricDescriptorsLock.Lock()
+ defer s.metricDescriptorData.MetricDescriptorsLock.Unlock()
+ if err := validation.AddMetricDescriptor(s.metricDescriptorData.UploadedMetricDescriptors, req.MetricDescriptor.Type, req.MetricDescriptor); err != nil {
+ addMetricDescriptorToSummary(&s.metricDescriptorData.MetricDescriptorSummary, req.MetricDescriptor, err.Error())
return nil, err
}
+ addMetricDescriptorToSummary(&s.metricDescriptorData.MetricDescriptorSummary, req.MetricDescriptor, "OK")
return req.MetricDescriptor, nil
}
@@ -120,9 +127,9 @@ func (s *MockMetricServer) DeleteMetricDescriptor(ctx context.Context, req *moni
return nil, err
}
- s.uploadedMetricDescriptorsLock.Lock()
- defer s.uploadedMetricDescriptorsLock.Unlock()
- if err := validation.RemoveMetricDescriptor(s.uploadedMetricDescriptors, req.Name); err != nil {
+ s.metricDescriptorData.MetricDescriptorsLock.Lock()
+ defer s.metricDescriptorData.MetricDescriptorsLock.Unlock()
+ if err := validation.RemoveMetricDescriptor(s.metricDescriptorData.UploadedMetricDescriptors, req.Name); err != nil {
return nil, err
}
@@ -157,7 +164,7 @@ func (s *MockMetricServer) CreateTimeSeries(ctx context.Context, req *monitoring
if err := validation.ValidateProjectName(req.Name); err != nil {
return nil, err
}
- if err := validation.ValidateCreateTimeSeries(req.TimeSeries, s.uploadedMetricDescriptors, s.uploadedPoints); err != nil {
+ if err := validation.ValidateCreateTimeSeries(req.TimeSeries, s.metricDescriptorData.UploadedMetricDescriptors, s.uploadedPoints); err != nil {
return nil, err
}
s.uploadedPointsLock.Lock()
@@ -178,3 +185,17 @@ func (s *MockMetricServer) ListTimeSeries(ctx context.Context, req *monitoring.L
ExecutionErrors: []*status.Status{},
}, nil
}
+
+// addMetricDescriptorToSummary adds the given metric descriptor and status to the summary.
+func addMetricDescriptorToSummary(summary *[]*validation.DescriptorStatus, metricDescriptor *metric.MetricDescriptor, err string) {
+ metricDescriptorStatus := &validation.DescriptorStatus{
+ MetricDescriptor: metricDescriptor,
+ Status: err,
+ }
+ *summary = append(*summary, metricDescriptorStatus)
+}
+
+// MetricDescriptorSummary returns the metric descriptor data to display in the summary page.
+func (s *MockMetricServer) MetricDescriptorSummary() []*validation.DescriptorStatus {
+ return s.metricDescriptorData.MetricDescriptorSummary
+}
diff --git a/server/trace/mock_trace.go b/server/trace/mock_trace.go
index 2d7d62c..ecb508b 100644
--- a/server/trace/mock_trace.go
+++ b/server/trace/mock_trace.go
@@ -123,6 +123,6 @@ func (s *MockTraceServer) SetOnUpload(onUpload func(ctx context.Context, spans [
s.onUpload = onUpload
}
-func (s *MockTraceServer) ResultTable() []*cloudtrace.Span {
+func (s *MockTraceServer) SpansSummary() []*cloudtrace.Span {
return s.spanData.SpansSummary
}
diff --git a/static/summary_template.html b/static/summary_template.html
index 2988e19..b1f5d7b 100755
--- a/static/summary_template.html
+++ b/static/summary_template.html
@@ -8,6 +8,9 @@
+
+
+
Trace Summary
-
- {{ range $index, $span := . }}
+ {{ range $index, $span := .Spans }}
{{ if eq $span.Status.Message "OK" }}
{{ else }}
@@ -39,6 +41,40 @@
+
+
+
Metric Descriptors Summary
+
+
+
+
+
+ Metric Descriptor Name |
+ Metric Descriptor Type |
+ Status |
+
+
+
+
+
+
+
+
+ {{ range $index, $md := .MetricDescriptors }}
+ {{ if eq $md.Status "OK" }}
+
+ {{ else }}
+
+ {{ end }}
+ {{ $md.MetricDescriptor.Name }} |
+ {{ $md.MetricDescriptor.Type }} |
+ {{ $md.Status }} |
+
+ {{ end }}
+
+
+
+