-
Notifications
You must be signed in to change notification settings - Fork 10
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
4 changed files
with
415 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,127 @@ | ||
package axiom | ||
|
||
import ( | ||
"context" | ||
"net/http" | ||
"net/url" | ||
|
||
"go.opentelemetry.io/otel/attribute" | ||
"go.opentelemetry.io/otel/trace" | ||
) | ||
|
||
type VirtualField struct { | ||
// Dataset is the dataset to which the virtual field belongs. | ||
Dataset string `json:"dataset"` | ||
// Name is the name of the virtual field. | ||
Name string `json:"name"` | ||
// Expression defines the virtual field's APL. | ||
Expression string `json:"expression"` | ||
// Description is an optional description of the virtual field. | ||
Description string `json:"description,omitempty"` | ||
// Type is the type of the virtual field. E.g. string | number | ||
Type string `json:"type,omitempty"` | ||
// Unit is the unit for the type of data returned by the virtual field. | ||
Unit string `json:"unit,omitempty"` | ||
} | ||
|
||
type VirtualFieldWithId struct { | ||
VirtualField | ||
// ID is the unique identifier of the virtual field. | ||
ID string `json:"id"` | ||
} | ||
|
||
// Axiom API Reference: /v2/vfields | ||
type VirtualFieldsService service | ||
|
||
// List all virtual fields for a given dataset. | ||
func (s *VirtualFieldsService) List(ctx context.Context, dataset string) ([]*VirtualFieldWithId, error) { | ||
ctx, span := s.client.trace(ctx, "VirtualFields.List", trace.WithAttributes( | ||
attribute.String("axiom.param.dataset", dataset), | ||
)) | ||
defer span.End() | ||
|
||
params := url.Values{} | ||
params.Set("dataset", dataset) | ||
|
||
var res []*VirtualFieldWithId | ||
if err := s.client.Call(ctx, http.MethodGet, s.basePath+"?"+params.Encode(), nil, &res); err != nil { | ||
return nil, spanError(span, err) | ||
} | ||
|
||
return res, nil | ||
} | ||
|
||
// Get a virtual field by id. | ||
func (s *VirtualFieldsService) Get(ctx context.Context, id string) (*VirtualFieldWithId, error) { | ||
ctx, span := s.client.trace(ctx, "VirtualFields.Get", trace.WithAttributes( | ||
attribute.String("axiom.virtual_field_id", id), | ||
)) | ||
defer span.End() | ||
|
||
path, err := url.JoinPath(s.basePath, id) | ||
if err != nil { | ||
return nil, spanError(span, err) | ||
} | ||
|
||
var res VirtualFieldWithId | ||
if err := s.client.Call(ctx, http.MethodGet, path, nil, &res); err != nil { | ||
return nil, spanError(span, err) | ||
} | ||
|
||
return &res, nil | ||
} | ||
|
||
// Create a virtual field with the given properties. | ||
func (s *VirtualFieldsService) Create(ctx context.Context, req VirtualField) (*VirtualFieldWithId, error) { | ||
ctx, span := s.client.trace(ctx, "VirtualFields.Create", trace.WithAttributes( | ||
attribute.String("axiom.param.dataset", req.Dataset), | ||
attribute.String("axiom.param.name", req.Name), | ||
)) | ||
defer span.End() | ||
|
||
var res VirtualFieldWithId | ||
if err := s.client.Call(ctx, http.MethodPost, s.basePath, req, &res); err != nil { | ||
return nil, spanError(span, err) | ||
} | ||
|
||
return &res, nil | ||
} | ||
|
||
// Update the virtual field identified by the given id with the given properties. | ||
func (s *VirtualFieldsService) Update(ctx context.Context, id string, req VirtualField) (*VirtualFieldWithId, error) { | ||
ctx, span := s.client.trace(ctx, "VirtualFields.Update", trace.WithAttributes( | ||
attribute.String("axiom.virtual_field_id", id), | ||
)) | ||
defer span.End() | ||
|
||
path, err := url.JoinPath(s.basePath, id) | ||
if err != nil { | ||
return nil, spanError(span, err) | ||
} | ||
|
||
var res VirtualFieldWithId | ||
if err := s.client.Call(ctx, http.MethodPut, path, req, &res); err != nil { | ||
return nil, spanError(span, err) | ||
} | ||
|
||
return &res, nil | ||
} | ||
|
||
// Delete the virtual field identified by the given id. | ||
func (s *VirtualFieldsService) Delete(ctx context.Context, id string) error { | ||
ctx, span := s.client.trace(ctx, "VirtualFields.Delete", trace.WithAttributes( | ||
attribute.String("axiom.virtual_field_id", id), | ||
)) | ||
defer span.End() | ||
|
||
path, err := url.JoinPath(s.basePath, id) | ||
if err != nil { | ||
return spanError(span, err) | ||
} | ||
|
||
if err := s.client.Call(ctx, http.MethodDelete, path, nil, nil); err != nil { | ||
return spanError(span, err) | ||
} | ||
|
||
return nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,121 @@ | ||
package axiom_test | ||
|
||
import ( | ||
"context" | ||
"testing" | ||
"time" | ||
|
||
"github.com/stretchr/testify/suite" | ||
|
||
"github.com/axiomhq/axiom-go/axiom" | ||
) | ||
|
||
// VirtualFieldsTestSuite tests all methods of the Axiom Virtual Fields API | ||
// against a live deployment. | ||
type VirtualFieldsTestSuite struct { | ||
IntegrationTestSuite | ||
|
||
// Setup once per test. | ||
vfield *axiom.VirtualFieldWithId | ||
} | ||
|
||
func TestVirtualFieldsTestSuite(t *testing.T) { | ||
suite.Run(t, new(VirtualFieldsTestSuite)) | ||
} | ||
|
||
func (s *VirtualFieldsTestSuite) SetupSuite() { | ||
s.IntegrationTestSuite.SetupSuite() | ||
} | ||
|
||
func (s *VirtualFieldsTestSuite) TearDownSuite() { | ||
s.IntegrationTestSuite.TearDownSuite() | ||
} | ||
|
||
func (s *VirtualFieldsTestSuite) SetupTest() { | ||
s.IntegrationTestSuite.SetupTest() | ||
|
||
var err error | ||
s.vfield, err = s.client.VirtualFields.Create(s.ctx, axiom.VirtualField{ | ||
Dataset: "test-dataset", | ||
Name: "Test Field", | ||
Expression: "a + b", | ||
Type: "number", | ||
}) | ||
s.Require().NoError(err) | ||
s.Require().NotNil(s.vfield) | ||
} | ||
|
||
func (s *VirtualFieldsTestSuite) TearDownTest() { | ||
// Teardown routines use their own context to avoid not being run at all | ||
// when the suite gets cancelled or times out. | ||
ctx, cancel := context.WithTimeout(context.WithoutCancel(s.ctx), time.Second*15) | ||
defer cancel() | ||
|
||
err := s.client.VirtualFields.Delete(ctx, s.vfield.ID) | ||
s.NoError(err) | ||
|
||
s.IntegrationTestSuite.TearDownTest() | ||
} | ||
|
||
func (s *VirtualFieldsTestSuite) Test() { | ||
// Update the virtual field. | ||
vfield, err := s.client.VirtualFields.Update(s.ctx, s.vfield.ID, axiom.VirtualField{ | ||
Dataset: "test-dataset", | ||
Name: "Updated Test Field", | ||
Expression: "a - b", | ||
Type: "number", | ||
}) | ||
s.Require().NoError(err) | ||
s.Require().NotNil(vfield) | ||
|
||
s.vfield = vfield | ||
|
||
// Get the virtual field and make sure it matches the updated values. | ||
vfield, err = s.client.VirtualFields.Get(s.ctx, s.vfield.ID) | ||
s.Require().NoError(err) | ||
s.Require().NotNil(vfield) | ||
|
||
s.Equal(s.vfield, vfield) | ||
|
||
// List all virtual fields for the dataset and ensure the created field is part of the list. | ||
vfields, err := s.client.VirtualFields.List(s.ctx, "test-dataset") | ||
s.Require().NoError(err) | ||
s.Require().NotEmpty(vfields) | ||
|
||
s.Contains(vfields, s.vfield) | ||
} | ||
|
||
func (s *VirtualFieldsTestSuite) TestCreateAndDeleteVirtualField() { | ||
// Create a new virtual field. | ||
vfield, err := s.client.VirtualFields.Create(s.ctx, axiom.VirtualField{ | ||
Dataset: "test-dataset", | ||
Name: "New Test Field", | ||
Expression: "x * y", | ||
Type: "number", | ||
}) | ||
s.Require().NoError(err) | ||
s.Require().NotNil(vfield) | ||
|
||
// Get the virtual field and ensure it matches what was created. | ||
fetchedField, err := s.client.VirtualFields.Get(s.ctx, vfield.ID) | ||
s.Require().NoError(err) | ||
s.Require().NotNil(fetchedField) | ||
s.Equal(vfield, fetchedField) | ||
|
||
// Delete the virtual field. | ||
err = s.client.VirtualFields.Delete(s.ctx, vfield.ID) | ||
s.Require().NoError(err) | ||
|
||
// Ensure the virtual field no longer exists. | ||
_, err = s.client.VirtualFields.Get(s.ctx, vfield.ID) | ||
s.Error(err) | ||
} | ||
|
||
func (s *VirtualFieldsTestSuite) TestListVirtualFields() { | ||
// List all virtual fields for the dataset and ensure the created field is part of the list. | ||
vfields, err := s.client.VirtualFields.List(s.ctx, "test-dataset") | ||
s.Require().NoError(err) | ||
s.Require().NotEmpty(vfields) | ||
|
||
s.Contains(vfields, s.vfield) | ||
} |
Oops, something went wrong.