TUN-8052: Update go to 1.21.5

Also update golang.org/x/net and google.golang.org/grpc to fix vulnerabilities,
although cloudflared is using them in a way that is not exposed to those risks
This commit is contained in:
Chung-Ting
2023-12-11 11:58:19 +00:00
parent b901d73d9b
commit 12dd91ada1
974 changed files with 28780 additions and 25799 deletions

View File

@@ -25,6 +25,7 @@ type TracerConfig struct {
instrumentationVersion string
// Schema URL of the telemetry emitted by the Tracer.
schemaURL string
attrs attribute.Set
}
// InstrumentationVersion returns the version of the library providing instrumentation.
@@ -32,6 +33,12 @@ func (t *TracerConfig) InstrumentationVersion() string {
return t.instrumentationVersion
}
// InstrumentationAttributes returns the attributes associated with the library
// providing instrumentation.
func (t *TracerConfig) InstrumentationAttributes() attribute.Set {
return t.attrs
}
// SchemaURL returns the Schema URL of the telemetry emitted by the Tracer.
func (t *TracerConfig) SchemaURL() string {
return t.schemaURL
@@ -124,7 +131,7 @@ func NewSpanEndConfig(options ...SpanEndOption) SpanConfig {
}
// SpanStartOption applies an option to a SpanConfig. These options are applicable
// only when the span is created
// only when the span is created.
type SpanStartOption interface {
applySpanStart(SpanConfig) SpanConfig
}
@@ -261,6 +268,7 @@ func (o stackTraceOption) applyEvent(c EventConfig) EventConfig {
c.stackTrace = bool(o)
return c
}
func (o stackTraceOption) applySpan(c SpanConfig) SpanConfig {
c.stackTrace = bool(o)
return c
@@ -307,6 +315,16 @@ func WithInstrumentationVersion(version string) TracerOption {
})
}
// WithInstrumentationAttributes sets the instrumentation attributes.
//
// The passed attributes will be de-duplicated.
func WithInstrumentationAttributes(attr ...attribute.KeyValue) TracerOption {
return tracerOptionFunc(func(config TracerConfig) TracerConfig {
config.attrs = attribute.NewSet(attr...)
return config
})
}
// WithSchemaURL sets the schema URL for the Tracer.
func WithSchemaURL(schemaURL string) TracerOption {
return tracerOptionFunc(func(cfg TracerConfig) TracerConfig {

View File

@@ -17,7 +17,7 @@ Package trace provides an implementation of the tracing part of the
OpenTelemetry API.
To participate in distributed traces a Span needs to be created for the
operation being performed as part of a traced workflow. It its simplest form:
operation being performed as part of a traced workflow. In its simplest form:
var tracer trace.Tracer
@@ -62,5 +62,69 @@ a default.
defer span.End()
// ...
}
# API Implementations
This package does not conform to the standard Go versioning policy; all of its
interfaces may have methods added to them without a package major version bump.
This non-standard API evolution could surprise an uninformed implementation
author. They could unknowingly build their implementation in a way that would
result in a runtime panic for their users that update to the new API.
The API is designed to help inform an instrumentation author about this
non-standard API evolution. It requires them to choose a default behavior for
unimplemented interface methods. There are three behavior choices they can
make:
- Compilation failure
- Panic
- Default to another implementation
All interfaces in this API embed a corresponding interface from
[go.opentelemetry.io/otel/trace/embedded]. If an author wants the default
behavior of their implementations to be a compilation failure, signaling to
their users they need to update to the latest version of that implementation,
they need to embed the corresponding interface from
[go.opentelemetry.io/otel/trace/embedded] in their implementation. For
example,
import "go.opentelemetry.io/otel/trace/embedded"
type TracerProvider struct {
embedded.TracerProvider
// ...
}
If an author wants the default behavior of their implementations to panic, they
can embed the API interface directly.
import "go.opentelemetry.io/otel/trace"
type TracerProvider struct {
trace.TracerProvider
// ...
}
This option is not recommended. It will lead to publishing packages that
contain runtime panics when users update to newer versions of
[go.opentelemetry.io/otel/trace], which may be done with a trasitive
dependency.
Finally, an author can embed another implementation in theirs. The embedded
implementation will be used for methods not defined by the author. For example,
an author who wants to default to silently dropping the call can use
[go.opentelemetry.io/otel/trace/noop]:
import "go.opentelemetry.io/otel/trace/noop"
type TracerProvider struct {
noop.TracerProvider
// ...
}
It is strongly recommended that authors only embed
[go.opentelemetry.io/otel/trace/noop] if they choose this default behavior.
That implementation is the only one OpenTelemetry authors can guarantee will
fully implement all the API interfaces when a user updates their API.
*/
package trace // import "go.opentelemetry.io/otel/trace"

View File

@@ -0,0 +1,56 @@
// Copyright The OpenTelemetry 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 embedded provides interfaces embedded within the [OpenTelemetry
// trace API].
//
// Implementers of the [OpenTelemetry trace API] can embed the relevant type
// from this package into their implementation directly. Doing so will result
// in a compilation error for users when the [OpenTelemetry trace API] is
// extended (which is something that can happen without a major version bump of
// the API package).
//
// [OpenTelemetry trace API]: https://pkg.go.dev/go.opentelemetry.io/otel/trace
package embedded // import "go.opentelemetry.io/otel/trace/embedded"
// TracerProvider is embedded in
// [go.opentelemetry.io/otel/trace.TracerProvider].
//
// Embed this interface in your implementation of the
// [go.opentelemetry.io/otel/trace.TracerProvider] if you want users to
// experience a compilation error, signaling they need to update to your latest
// implementation, when the [go.opentelemetry.io/otel/trace.TracerProvider]
// interface is extended (which is something that can happen without a major
// version bump of the API package).
type TracerProvider interface{ tracerProvider() }
// Tracer is embedded in [go.opentelemetry.io/otel/trace.Tracer].
//
// Embed this interface in your implementation of the
// [go.opentelemetry.io/otel/trace.Tracer] if you want users to experience a
// compilation error, signaling they need to update to your latest
// implementation, when the [go.opentelemetry.io/otel/trace.Tracer] interface
// is extended (which is something that can happen without a major version bump
// of the API package).
type Tracer interface{ tracer() }
// Span is embedded in [go.opentelemetry.io/otel/trace.Span].
//
// Embed this interface in your implementation of the
// [go.opentelemetry.io/otel/trace.Span] if you want users to experience a
// compilation error, signaling they need to update to your latest
// implementation, when the [go.opentelemetry.io/otel/trace.Span] interface is
// extended (which is something that can happen without a major version bump of
// the API package).
type Span interface{ span() }

View File

@@ -19,16 +19,20 @@ import (
"go.opentelemetry.io/otel/attribute"
"go.opentelemetry.io/otel/codes"
"go.opentelemetry.io/otel/trace/embedded"
)
// NewNoopTracerProvider returns an implementation of TracerProvider that
// performs no operations. The Tracer and Spans created from the returned
// TracerProvider also perform no operations.
//
// Deprecated: Use [go.opentelemetry.io/otel/trace/noop.NewTracerProvider]
// instead.
func NewNoopTracerProvider() TracerProvider {
return noopTracerProvider{}
}
type noopTracerProvider struct{}
type noopTracerProvider struct{ embedded.TracerProvider }
var _ TracerProvider = noopTracerProvider{}
@@ -37,8 +41,8 @@ func (p noopTracerProvider) Tracer(string, ...TracerOption) Tracer {
return noopTracer{}
}
// noopTracer is an implementation of Tracer that preforms no operations.
type noopTracer struct{}
// noopTracer is an implementation of Tracer that performs no operations.
type noopTracer struct{ embedded.Tracer }
var _ Tracer = noopTracer{}
@@ -53,8 +57,8 @@ func (t noopTracer) Start(ctx context.Context, name string, _ ...SpanStartOption
return ContextWithSpan(ctx, span), span
}
// noopSpan is an implementation of Span that preforms no operations.
type noopSpan struct{}
// noopSpan is an implementation of Span that performs no operations.
type noopSpan struct{ embedded.Span }
var _ Span = noopSpan{}
@@ -85,5 +89,5 @@ func (noopSpan) AddEvent(string, ...EventOption) {}
// SetName does nothing.
func (noopSpan) SetName(string) {}
// TracerProvider returns a no-op TracerProvider
// TracerProvider returns a no-op TracerProvider.
func (noopSpan) TracerProvider() TracerProvider { return noopTracerProvider{} }

118
vendor/go.opentelemetry.io/otel/trace/noop/noop.go generated vendored Normal file
View File

@@ -0,0 +1,118 @@
// Copyright The OpenTelemetry 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 noop provides an implementation of the OpenTelemetry trace API that
// produces no telemetry and minimizes used computation resources.
//
// Using this package to implement the OpenTelemetry trace API will effectively
// disable OpenTelemetry.
//
// This implementation can be embedded in other implementations of the
// OpenTelemetry trace API. Doing so will mean the implementation defaults to
// no operation for methods it does not implement.
package noop // import "go.opentelemetry.io/otel/trace/noop"
import (
"context"
"go.opentelemetry.io/otel/attribute"
"go.opentelemetry.io/otel/codes"
"go.opentelemetry.io/otel/trace"
"go.opentelemetry.io/otel/trace/embedded"
)
var (
// Compile-time check this implements the OpenTelemetry API.
_ trace.TracerProvider = TracerProvider{}
_ trace.Tracer = Tracer{}
_ trace.Span = Span{}
)
// TracerProvider is an OpenTelemetry No-Op TracerProvider.
type TracerProvider struct{ embedded.TracerProvider }
// NewTracerProvider returns a TracerProvider that does not record any telemetry.
func NewTracerProvider() TracerProvider {
return TracerProvider{}
}
// Tracer returns an OpenTelemetry Tracer that does not record any telemetry.
func (TracerProvider) Tracer(string, ...trace.TracerOption) trace.Tracer {
return Tracer{}
}
// Tracer is an OpenTelemetry No-Op Tracer.
type Tracer struct{ embedded.Tracer }
// Start creates a span. The created span will be set in a child context of ctx
// and returned with the span.
//
// If ctx contains a span context, the returned span will also contain that
// span context. If the span context in ctx is for a non-recording span, that
// span instance will be returned directly.
func (t Tracer) Start(ctx context.Context, _ string, _ ...trace.SpanStartOption) (context.Context, trace.Span) {
span := trace.SpanFromContext(ctx)
// If the parent context contains a non-zero span context, that span
// context needs to be returned as a non-recording span
// (https://github.com/open-telemetry/opentelemetry-specification/blob/3a1dde966a4ce87cce5adf464359fe369741bbea/specification/trace/api.md#behavior-of-the-api-in-the-absence-of-an-installed-sdk).
var zeroSC trace.SpanContext
if sc := span.SpanContext(); !sc.Equal(zeroSC) {
if !span.IsRecording() {
// If the span is not recording return it directly.
return ctx, span
}
// Otherwise, return the span context needs in a non-recording span.
span = Span{sc: sc}
} else {
// No parent, return a No-Op span with an empty span context.
span = Span{}
}
return trace.ContextWithSpan(ctx, span), span
}
// Span is an OpenTelemetry No-Op Span.
type Span struct {
embedded.Span
sc trace.SpanContext
}
// SpanContext returns an empty span context.
func (s Span) SpanContext() trace.SpanContext { return s.sc }
// IsRecording always returns false.
func (Span) IsRecording() bool { return false }
// SetStatus does nothing.
func (Span) SetStatus(codes.Code, string) {}
// SetAttributes does nothing.
func (Span) SetAttributes(...attribute.KeyValue) {}
// End does nothing.
func (Span) End(...trace.SpanEndOption) {}
// RecordError does nothing.
func (Span) RecordError(error, ...trace.EventOption) {}
// AddEvent does nothing.
func (Span) AddEvent(string, ...trace.EventOption) {}
// SetName does nothing.
func (Span) SetName(string) {}
// TracerProvider returns a No-Op TracerProvider.
func (Span) TracerProvider() trace.TracerProvider { return TracerProvider{} }

View File

@@ -22,6 +22,7 @@ import (
"go.opentelemetry.io/otel/attribute"
"go.opentelemetry.io/otel/codes"
"go.opentelemetry.io/otel/trace/embedded"
)
const (
@@ -48,8 +49,10 @@ func (e errorConst) Error() string {
// nolint:revive // revive complains about stutter of `trace.TraceID`.
type TraceID [16]byte
var nilTraceID TraceID
var _ json.Marshaler = nilTraceID
var (
nilTraceID TraceID
_ json.Marshaler = nilTraceID
)
// IsValid checks whether the trace TraceID is valid. A valid trace ID does
// not consist of zeros only.
@@ -63,7 +66,7 @@ func (t TraceID) MarshalJSON() ([]byte, error) {
return json.Marshal(t.String())
}
// String returns the hex string representation form of a TraceID
// String returns the hex string representation form of a TraceID.
func (t TraceID) String() string {
return hex.EncodeToString(t[:])
}
@@ -71,8 +74,10 @@ func (t TraceID) String() string {
// SpanID is a unique identity of a span in a trace.
type SpanID [8]byte
var nilSpanID SpanID
var _ json.Marshaler = nilSpanID
var (
nilSpanID SpanID
_ json.Marshaler = nilSpanID
)
// IsValid checks whether the SpanID is valid. A valid SpanID does not consist
// of zeros only.
@@ -86,7 +91,7 @@ func (s SpanID) MarshalJSON() ([]byte, error) {
return json.Marshal(s.String())
}
// String returns the hex string representation form of a SpanID
// String returns the hex string representation form of a SpanID.
func (s SpanID) String() string {
return hex.EncodeToString(s[:])
}
@@ -151,7 +156,7 @@ func decodeHex(h string, b []byte) error {
return nil
}
// TraceFlags contains flags that can be set on a SpanContext
// TraceFlags contains flags that can be set on a SpanContext.
type TraceFlags byte //nolint:revive // revive complains about stutter of `trace.TraceFlags`.
// IsSampled returns if the sampling bit is set in the TraceFlags.
@@ -160,7 +165,7 @@ func (tf TraceFlags) IsSampled() bool {
}
// WithSampled sets the sampling bit in a new copy of the TraceFlags.
func (tf TraceFlags) WithSampled(sampled bool) TraceFlags {
func (tf TraceFlags) WithSampled(sampled bool) TraceFlags { // nolint:revive // sampled is not a control flag.
if sampled {
return tf | FlagsSampled
}
@@ -174,7 +179,7 @@ func (tf TraceFlags) MarshalJSON() ([]byte, error) {
return json.Marshal(tf.String())
}
// String returns the hex string representation form of TraceFlags
// String returns the hex string representation form of TraceFlags.
func (tf TraceFlags) String() string {
return hex.EncodeToString([]byte{byte(tf)}[:])
}
@@ -338,8 +343,15 @@ func (sc SpanContext) MarshalJSON() ([]byte, error) {
// create a Span and it is then up to the operation the Span represents to
// properly end the Span when the operation itself ends.
//
// Warning: methods may be added to this interface in minor releases.
// Warning: Methods may be added to this interface in minor releases. See
// package documentation on API implementation for information on how to set
// default behavior for unimplemented methods.
type Span interface {
// Users of the interface can ignore this. This embedded type is only used
// by implementations of this interface. See the "API Implementations"
// section of the package documentation for more information.
embedded.Span
// End completes the Span. The Span is considered complete and ready to be
// delivered through the rest of the telemetry pipeline after this method
// is called. Therefore, updates to the Span are not allowed after this
@@ -364,8 +376,9 @@ type Span interface {
SpanContext() SpanContext
// SetStatus sets the status of the Span in the form of a code and a
// description, overriding previous values set. The description is only
// included in a status when the code is for an error.
// description, provided the status hasn't already been set to a higher
// value before (OK > Error > Unset). The description is only included in a
// status when the code is for an error.
SetStatus(code codes.Code, description string)
// SetName sets the Span name.
@@ -386,16 +399,16 @@ type Span interface {
//
// For example, a Link is used in the following situations:
//
// 1. Batch Processing: A batch of operations may contain operations
// associated with one or more traces/spans. Since there can only be one
// parent SpanContext, a Link is used to keep reference to the
// SpanContext of all operations in the batch.
// 2. Public Endpoint: A SpanContext for an in incoming client request on a
// public endpoint should be considered untrusted. In such a case, a new
// trace with its own identity and sampling decision needs to be created,
// but this new trace needs to be related to the original trace in some
// form. A Link is used to keep reference to the original SpanContext and
// track the relationship.
// 1. Batch Processing: A batch of operations may contain operations
// associated with one or more traces/spans. Since there can only be one
// parent SpanContext, a Link is used to keep reference to the
// SpanContext of all operations in the batch.
// 2. Public Endpoint: A SpanContext for an in incoming client request on a
// public endpoint should be considered untrusted. In such a case, a new
// trace with its own identity and sampling decision needs to be created,
// but this new trace needs to be related to the original trace in some
// form. A Link is used to keep reference to the original SpanContext and
// track the relationship.
type Link struct {
// SpanContext of the linked Span.
SpanContext SpanContext
@@ -485,8 +498,15 @@ func (sk SpanKind) String() string {
// Tracer is the creator of Spans.
//
// Warning: methods may be added to this interface in minor releases.
// Warning: Methods may be added to this interface in minor releases. See
// package documentation on API implementation for information on how to set
// default behavior for unimplemented methods.
type Tracer interface {
// Users of the interface can ignore this. This embedded type is only used
// by implementations of this interface. See the "API Implementations"
// section of the package documentation for more information.
embedded.Tracer
// Start creates a span and a context.Context containing the newly-created span.
//
// If the context.Context provided in `ctx` contains a Span then the newly-created
@@ -503,17 +523,55 @@ type Tracer interface {
Start(ctx context.Context, spanName string, opts ...SpanStartOption) (context.Context, Span)
}
// TracerProvider provides access to instrumentation Tracers.
// TracerProvider provides Tracers that are used by instrumentation code to
// trace computational workflows.
//
// Warning: methods may be added to this interface in minor releases.
// A TracerProvider is the collection destination of all Spans from Tracers it
// provides, it represents a unique telemetry collection pipeline. How that
// pipeline is defined, meaning how those Spans are collected, processed, and
// where they are exported, depends on its implementation. Instrumentation
// authors do not need to define this implementation, rather just use the
// provided Tracers to instrument code.
//
// Commonly, instrumentation code will accept a TracerProvider implementation
// at runtime from its users or it can simply use the globally registered one
// (see https://pkg.go.dev/go.opentelemetry.io/otel#GetTracerProvider).
//
// Warning: Methods may be added to this interface in minor releases. See
// package documentation on API implementation for information on how to set
// default behavior for unimplemented methods.
type TracerProvider interface {
// Tracer creates an implementation of the Tracer interface.
// The instrumentationName must be the name of the library providing
// instrumentation. This name may be the same as the instrumented code
// only if that code provides built-in instrumentation. If the
// instrumentationName is empty, then a implementation defined default
// name will be used instead.
// Users of the interface can ignore this. This embedded type is only used
// by implementations of this interface. See the "API Implementations"
// section of the package documentation for more information.
embedded.TracerProvider
// Tracer returns a unique Tracer scoped to be used by instrumentation code
// to trace computational workflows. The scope and identity of that
// instrumentation code is uniquely defined by the name and options passed.
//
// This method must be concurrency safe.
Tracer(instrumentationName string, opts ...TracerOption) Tracer
// The passed name needs to uniquely identify instrumentation code.
// Therefore, it is recommended that name is the Go package name of the
// library providing instrumentation (note: not the code being
// instrumented). Instrumentation libraries can have multiple versions,
// therefore, the WithInstrumentationVersion option should be used to
// distinguish these different codebases. Additionally, instrumentation
// libraries may sometimes use traces to communicate different domains of
// workflow data (i.e. using spans to communicate workflow events only). If
// this is the case, the WithScopeAttributes option should be used to
// uniquely identify Tracers that handle the different domains of workflow
// data.
//
// If the same name and options are passed multiple times, the same Tracer
// will be returned (it is up to the implementation if this will be the
// same underlying instance of that Tracer or not). It is not necessary to
// call this multiple times with the same name and options to get an
// up-to-date Tracer. All implementations will ensure any TracerProvider
// configuration changes are propagated to all provided Tracers.
//
// If name is empty, then an implementation defined default name will be
// used instead.
//
// This method is safe to call concurrently.
Tracer(name string, options ...TracerOption) Tracer
}

View File

@@ -21,20 +21,16 @@ import (
"strings"
)
var (
const (
maxListMembers = 32
listDelimiter = ","
// based on the W3C Trace Context specification, see
// https://www.w3.org/TR/trace-context-1/#tracestate-header
noTenantKeyFormat = `[a-z][_0-9a-z\-\*\/]{0,255}`
withTenantKeyFormat = `[a-z0-9][_0-9a-z\-\*\/]{0,240}@[a-z][_0-9a-z\-\*\/]{0,13}`
valueFormat = `[\x20-\x2b\x2d-\x3c\x3e-\x7e]{0,255}[\x21-\x2b\x2d-\x3c\x3e-\x7e]`
keyRe = regexp.MustCompile(`^((` + noTenantKeyFormat + `)|(` + withTenantKeyFormat + `))$`)
valueRe = regexp.MustCompile(`^(` + valueFormat + `)$`)
memberRe = regexp.MustCompile(`^\s*((` + noTenantKeyFormat + `)|(` + withTenantKeyFormat + `))=(` + valueFormat + `)\s*$`)
noTenantKeyFormat = `[a-z][_0-9a-z\-\*\/]*`
withTenantKeyFormat = `[a-z0-9][_0-9a-z\-\*\/]*@[a-z][_0-9a-z\-\*\/]*`
valueFormat = `[\x20-\x2b\x2d-\x3c\x3e-\x7e]*[\x21-\x2b\x2d-\x3c\x3e-\x7e]`
errInvalidKey errorConst = "invalid tracestate key"
errInvalidValue errorConst = "invalid tracestate value"
@@ -43,16 +39,32 @@ var (
errDuplicate errorConst = "duplicate list-member in tracestate"
)
var (
noTenantKeyRe = regexp.MustCompile(`^` + noTenantKeyFormat + `$`)
withTenantKeyRe = regexp.MustCompile(`^` + withTenantKeyFormat + `$`)
valueRe = regexp.MustCompile(`^` + valueFormat + `$`)
memberRe = regexp.MustCompile(`^\s*((?:` + noTenantKeyFormat + `)|(?:` + withTenantKeyFormat + `))=(` + valueFormat + `)\s*$`)
)
type member struct {
Key string
Value string
}
func newMember(key, value string) (member, error) {
if !keyRe.MatchString(key) {
if len(key) > 256 {
return member{}, fmt.Errorf("%w: %s", errInvalidKey, key)
}
if !valueRe.MatchString(value) {
if !noTenantKeyRe.MatchString(key) {
if !withTenantKeyRe.MatchString(key) {
return member{}, fmt.Errorf("%w: %s", errInvalidKey, key)
}
atIndex := strings.LastIndex(key, "@")
if atIndex > 241 || len(key)-1-atIndex > 14 {
return member{}, fmt.Errorf("%w: %s", errInvalidKey, key)
}
}
if len(value) > 256 || !valueRe.MatchString(value) {
return member{}, fmt.Errorf("%w: %s", errInvalidValue, value)
}
return member{Key: key, Value: value}, nil
@@ -60,15 +72,14 @@ func newMember(key, value string) (member, error) {
func parseMember(m string) (member, error) {
matches := memberRe.FindStringSubmatch(m)
if len(matches) != 5 {
if len(matches) != 3 {
return member{}, fmt.Errorf("%w: %s", errInvalidMember, m)
}
return member{
Key: matches[1],
Value: matches[4],
}, nil
result, e := newMember(matches[1], matches[2])
if e != nil {
return member{}, fmt.Errorf("%w: %s", errInvalidMember, m)
}
return result, nil
}
// String encodes member into a string compliant with the W3C Trace Context