Skip to content

Add REST API to OpAMP Server Example#497

Open
juandemanjon wants to merge 15 commits intoopen-telemetry:mainfrom
juandemanjon:issue_474
Open

Add REST API to OpAMP Server Example#497
juandemanjon wants to merge 15 commits intoopen-telemetry:mainfrom
juandemanjon:issue_474

Conversation

@juandemanjon
Copy link
Contributor

Add REST API to OpAMP Server Example

Fixes #474

Summary

This PR introduces a REST API for the OpAMP Server example, enabling clean separation between the UI layer and server logic. The API exposes programmatic access to connected agents, allowing modern web applications, CLI tools, and third-party clients to interact seamlessly with the OpAMP server.

Changes

New Package: internal/examples/server/apisrv

Added a new apisrv package that implements a REST API server running on port 4322.

API Endpoints

  1. GET /api/v1/agents

    • Lists all agents currently connected to the OpAMP server
    • Returns agent UUIDs and full status information
  2. GET /api/v1/agents/{instanceid}

    • Retrieves detailed information about a specific agent by UUID
    • Returns 404 if agent not found, 400 for invalid UUID format
  3. POST /api/v1/agents/{instanceid}/config

    • Updates agent configuration via OpAMP protocol
    • Waits up to 5 seconds for agent acknowledgment
    • Returns 408 timeout if agent doesn't respond

Features

  • CORS Support: Middleware enables cross-origin requests for web clients
  • JSON Responses: All endpoints return properly formatted JSON
  • Error Handling: Comprehensive error responses with appropriate HTTP status codes
  • OpAMP Integration: Direct integration with existing agent management system

Documentation

  • README.md: Comprehensive API documentation with examples, endpoint details, and architecture overview
  • openapi.yaml: Complete OpenAPI 3.0 specification for tool integration and client generation
  • Godoc Comments: Detailed inline documentation for all exported types and methods

Testing

  • Comprehensive test suite covering:
    • Server lifecycle management
    • Multiple agent connections
    • Individual agent retrieval
    • Configuration updates
    • Error handling (invalid UUIDs, non-existent agents)
    • All tests passing ✅

Integration

  • API server starts automatically with the OpAMP server
  • Shares the same agent data store with the OpAMP server
  • Runs alongside existing uisrv (no breaking changes)
  • Graceful shutdown handling

Architecture

┌─────────────┐
│   Clients   │ (Web UI, CLI, etc.)
└──────┬──────┘
       │ HTTP/REST
       ▼
┌─────────────┐
│  API Server │ (Port 4322)
└──────┬──────┘
       │
       ▼
┌─────────────┐
│   Agents    │ (In-memory store)
│   Manager   │
└──────┬──────┘
       │
       ▼
┌─────────────┐
│ OpAMP Server│ (Port 4320)
└──────┬──────┘
       │ WebSocket
       ▼
┌─────────────┐
│   Agents    │
└─────────────┘

Testing Instructions

Start the Server

cd internal/examples/server
go run .

Test the API

List all agents:

curl http://localhost:4322/api/v1/agents

Get specific agent:

curl http://localhost:4322/api/v1/agents/{agent-uuid}

Update agent config:

curl -X POST http://localhost:4322/api/v1/agents/{agent-uuid}/config \
  -H "Content-Type: application/json" \
  -d '{"config": "receivers:\n  otlp:\n    protocols:\n      grpc:\n        endpoint: 0.0.0.0:4317\n"}'

Run Tests

cd internal/examples
go test -v ./server/apisrv/

Files Changed

  • internal/examples/server/apisrv/api.go - API server implementation
  • internal/examples/server/apisrv/api_test.go - Comprehensive test suite
  • internal/examples/server/apisrv/README.md - API documentation
  • internal/examples/server/apisrv/openapi.yaml - OpenAPI specification
  • internal/examples/server/main.go - Integration with main server
  • go.mod - Added github.com/madflojo/testcerts as direct dependency

Breaking Changes

None. The API server runs alongside the existing UI server without any breaking changes.

@juandemanjon juandemanjon requested a review from a team as a code owner January 16, 2026 17:09
@juandemanjon juandemanjon changed the title Add REST API to OpAMP Server Example #474 Add REST API to OpAMP Server Example Jan 16, 2026
@codecov
Copy link

codecov bot commented Jan 16, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 81.67%. Comparing base (e6d2a5f) to head (bc75068).
⚠️ Report is 18 commits behind head on main.

Additional details and impacted files
@@           Coverage Diff           @@
##             main     #497   +/-   ##
=======================================
  Coverage   81.67%   81.67%           
=======================================
  Files          27       27           
  Lines        2134     2134           
=======================================
  Hits         1743     1743           
  Misses        266      266           
  Partials      125      125           

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

Copy link
Contributor

@michel-laterman michel-laterman left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm worried that redefining the OpAMP spec directly as an OpenAPI spec here will lead to extra work when demoing features for the example server.

# Test targets
.PHONY: test
test:
$(GOCMD) test -v -p 1 ./...
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please add the -race flag

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

deploy:
replicas: 1

opamp-ui:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why do we need another UI server?

I really don't think the example compose should have these extra services.

Currently the examples dir only shows off the opamp-go library, introducing something like the otel/opentelemetry-collector-contrib image now introduces a demo for the opentelemetry-collector-contrib repo.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You're right, this was a leftover I forgot to remove. I'm working on a new responsive UI in a separate issue, but it doesn't belong yet in the example compose. Removing it now.

I am going to keep the otel-collector service because the current server/agent example leverages it and I was trying to avoid these log messages. It is still working in progress

026/01/16 21:57:43.502169 [OPAMP] Connection settings for instance 019bca87de0f7afe84fdaeed99d9915d ConnectionSettingsStatuses_APPLYING (err=) hash=1d02a705cb821d9261f1b9b7f039ef1fe4a0431bc6c204060b7365e77eb3b569
2026/01/16 21:57:43.504191 [OPAMP] Connection settings for instance 019bca87de0f7afe84fdaeed99d9915d ConnectionSettingsStatuses_APPLIED (err=) hash=1d02a705cb821d9261f1b9b7f039ef1fe4a0431bc6c204060b7365e77eb3b569
2026/01/16 21:57:48 failed to upload metrics: Post "http://localhost:4318/v1/metrics": dial tcp 127.0.0.1:4318: connect: connection refused
2026/01/16 21:57:53 failed to upload metrics: Post "http://localhost:4318/v1/metrics": dial tcp 127.0.0.1:4318: connect: connection refused
2026/01/16 21:57:58 failed to upload metrics: Post "http://localhost:4318/v1/metrics": dial tcp 127.0.0.1:4318: connect: connection refused
2026/01/16 21:58:03 failed to upload metrics: Post "http://localhost:4318/v1/metrics": dial tcp 127.0.0.1:4318: connect: connection refused

Comment on lines +311 to +315
1. Add handler method to `ApiServer` struct in `api.go`
2. Register route in `Start()` method
3. Add tests in `api_test.go`
4. Update OpenAPI spec in `openapi.yaml`
5. Update this README
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What do you think about using a tool like oapi-codegen to generate code from the spec instead of having manual updates?

I find that it's really easy for the spec to drift from the implementation over time if it needs to be manually updated.

Copy link
Contributor Author

@juandemanjon juandemanjon Jan 17, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a great integration idea after getting a working REST API

Comment on lines +164 to +184
### Capabilities Bitmask

The `capabilities` field indicates what features the agent supports:

| Value | Capability | Description |
|--------|---------------------------------------|----------------------------------------------|
| 0x1 | ReportsStatus | Agent can report status |
| 0x2 | AcceptsRemoteConfig | Agent accepts remote configuration |
| 0x4 | ReportsEffectiveConfig | Agent reports its effective config |
| 0x8 | AcceptsRestartCommand | Agent can be restarted remotely |
| 0x10 | ReportsHealth | Agent reports health status |
| 0x20 | ReportsRemoteConfig | Agent reports remote config status |
| 0x40 | AcceptsOpAMPConnectionSettings | Agent accepts OpAMP connection settings |
| 0x80 | AcceptsOtherConnectionSettings | Agent accepts other connection settings |
| 0x100 | AcceptsPackages | Agent accepts package installations |
| 0x200 | ReportsPackageStatuses | Agent reports package statuses |
| 0x400 | ReportsOwnTraces | Agent reports its own traces |
| 0x800 | ReportsOwnMetrics | Agent reports its own metrics |
| 0x1000 | ReportsOwnLogs | Agent reports its own logs |
| 0x2000 | AcceptsOpAMPConnectionSettingsRequest | Agent accepts connection settings requests |
| 0x4000 | ReportsAvailableComponents | Agent reports available components |
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we should just link to the opamp-spec here instead (also for other areas in the README that refer to things we have defined there).

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

Comment on lines +333 to +343
## Future Enhancements

Potential additions to consider:

- Pagination for agent lists
- Filtering and searching agents
- WebSocket endpoint for real-time updates
- Agent restart command endpoint
- Package management endpoints
- Metrics and health endpoints
- Authentication and authorization
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This seems like a feature set for a "real" server - is the goal to use examples/server in that manner?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Many of these are specifically useful for UI/REST integration. Features like pagination, filtering, searching, and WebSocket updates are common requirements when building a web UI to visualize and manage agents. The REST API demonstrates how to expose OpAMP server functionality in a way that's consumable by frontends or other REST clients

Comment on lines +356 to +368
PackageStatus:
type: object
properties:
name:
type: string
version:
type: string
status:
type: string
enum:
- INSTALLED
- INSTALLING
- INSTALL_FAILED
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does not have the DOWNLOADING state: https://github.com/open-telemetry/opamp-spec/blob/8aa38f81e117df586b8f641b94cb93cc6137efa2/proto/opamp.proto#L974-L998

I'm a bit worried about redefining the spec here; If we add to the opamp-spec, will we now also need to ensure that the example server API here is synchronized? It seems like additional work.

Can we instead be less prescriptive for this API? For example, just use

PackageStatus:
  type: object
  description: "See https://github.com/open-telemetry/opamp-spec/blob/main/specification.md#agenttoserverpackage_statuses"
  properties: {}

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

Configure all services to use host networking. This allows the agent to connect to the hardcoded localhost:4318 collector endpoint without connection errors.
Copy link
Member

@tigrannajaryan tigrannajaryan left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@juandemanjon thank you for the effort but I am not sure this repository is the right place for such an extensive example.

This adds 1300 lines that needs to be maintained that are only tangentially related to OpAMP.

@open-telemetry/opamp-go-approvers anyone interested in personally taking ownership and maintaining this long term?

Blocking it for now.

@juandemanjon
Copy link
Contributor Author

I understand your concerns. I will be happy to maintain the API.

I previously mentioned moving the examples out of opamp-go/internal. Maybe now is time to have opamp-go-contrib. Let's talk about it in the next sig

@github-actions
Copy link

This PR was marked stale. It will be closed in 30 days without additional activity.

@github-actions github-actions bot added Stale and removed Stale labels Feb 19, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add REST API to the OpAMP Server example

3 participants