Skip to content

Commit

Permalink
Merge pull request #1 from mollie/SF-951/move-from-personal-ns
Browse files Browse the repository at this point in the history
SF-951 Apicurio Registry SDK
  • Loading branch information
subzerobo authored Dec 11, 2024
2 parents 6936054 + 26bd3f9 commit 6e9a994
Show file tree
Hide file tree
Showing 25 changed files with 6,025 additions and 0 deletions.
86 changes: 86 additions & 0 deletions .github/workflows/tests.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
name: Go Tests

on:
push:
branches:
- main
pull_request:
branches:
- main

jobs:
unit-tests:
name: Run Tests
runs-on: ubuntu-latest

steps:
# Step 1: Check out the repository
- name: Checkout code
uses: actions/checkout@v3

# Step 2: Set up Go
- name: Set up Go
uses: actions/setup-go@v4
with:
go-version: '1.23'

# Step 3: Install dependencies
- name: Install dependencies
run: go mod tidy

# Step 4: Run tests
- name: Run tests
run: go test ./... --short -v

# Step 5: Upload test results (optional)
- name: Upload test results
if: ${{ always() }}
uses: actions/upload-artifact@v3
with:
name: test-results
path: '**/test-report.xml'

integration-tests:
name: Run Integration Tests
runs-on: ubuntu-latest

services:
apicurio:
image: apicurio/apicurio-registry:3.0.5
ports:
- 9080:8080
options: >-
--env APICURIO_REST_MUTABILITY_ARTIFACT_VERSION_CONTENT_ENABLED=true
--env APICURIO_REST_DELETION_ARTIFACT_ENABLED=true
--env APICURIO_REST_DELETION_ARTIFACT_VERSION_ENABLED=true
--env APICURIO_REST_DELETION_GROUP_ENABLED=true
steps:
# Checkout the repository
- name: Checkout code
uses: actions/checkout@v3

# Set up Go environment
- name: Set up Go
uses: actions/setup-go@v4
with:
go-version: '1.23'

# Install dependencies
- name: Install dependencies
run: go mod tidy

# Wait for Apicurio Registry to start
- name: Wait for Apicurio Registry
run: |
for i in {1..30}; do
if curl -s http://localhost:9080/health || [ $i -eq 30 ]; then
break
fi
echo "Waiting for Apicurio Registry to be ready..."
sleep 2
done
# Run integration tests
- name: Run integration tests
run: go test ./... -run Integration -v
31 changes: 31 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
# Binaries for programs and plugins
*.exe
*.dll
*.so
*.dylib

# Output of the build process
bin/
build/

# Test binaries
*.test

# Output of `go run`
*.out

# Directories for dependency management
vendor/

# IDE and editor configuration files
.idea/
*.iml
.vscode/
*.swp

# OS-specific files
.DS_Store
Thumbs.db

# Logs and debugging files
*.log
55 changes: 55 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
# Go-APICURIO-SDK

[![Go Reference](https://pkg.go.dev/badge/github.com/mollie/go-apicurio-registry.svg)](https://pkg.go.dev/github.com/mollie/go-apicurio-registry)
[![Integration Tests](https://github.com/mollie/go-apicurio-registry/actions/workflows/tests.yml/badge.svg)](https://github.com/mollie/go-apicurio-registry/actions)

**Go-APICURIO-SDK** is an open-source Go SDK for interacting with [Apicurio Schema Registry v3.0 APIs](https://www.apicur.io/). This library provides an idiomatic Go interface to manage schemas, validate data, and handle schema evolution in Go applications. It is designed to make it easy for developers to integrate the Apicurio Schema Registry into their Go-based microservices or event-driven systems.

## 🚧 Work In Progress

This SDK is currently under active development. Key features and improvements are being added incrementally. While contributions and feedback are welcome, please note that some APIs and features may change as the project evolves.

## Features

- **Schema Management**: Create, update, delete, and retrieve schemas.
- **Validation**: Validate payloads against registered schemas.
- **Schema Evolution**: Tools for managing schema compatibility and evolution.
- **Integration**: Works seamlessly with the Apicurio Schema Registry.

## Getting Started

### Prerequisites

- Go 1.18+ installed on your system.
- Access to an Apicurio Schema Registry instance.

### Installation

To use the SDK, add it to your project using `go get`:

```bash
go get github.com/mollie/go-apicurio-registry
```

### Development
Running Locally with Docker
This project includes a docker-compose.yml file for setting up a local Apicurio Schema Registry instance. Run the following command to start the registry:

```bash
docker-compose up
```

### Running Tests

The repository includes unit and integration tests. Use the following command to run all tests:

```bash
go test ./...
```

## Contribution Guidelines
Contributions are welcome! Please see the CONTRIBUTING.md (to be added) for details on the process.


## License
This project is licensed under the Apache License 2.0.
168 changes: 168 additions & 0 deletions apis/admin.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,168 @@
package apis

import (
"bytes"
"context"
"encoding/json"
"fmt"
"github.com/mollie/go-apicurio-registry/client"
"github.com/mollie/go-apicurio-registry/models"
"github.com/pkg/errors"
"net/http"
)

type AdminAPI struct {
Client *client.Client
}

func NewAdminAPI(client *client.Client) *AdminAPI {
return &AdminAPI{
Client: client,
}
}

// ListGlobalRules Gets a list of all the currently configured global rules (if any).
// GET /admin/rules
// See: https://www.apicur.io/registry/docs/apicurio-registry/3.0.x/assets-attachments/registry-rest-api.htm#tag/Global-rules/operation/listGlobalRules
func (api *AdminAPI) ListGlobalRules(ctx context.Context) ([]models.Rule, error) {
url := fmt.Sprintf("%s/admin/rules", api.Client.BaseURL)
resp, err := api.executeRequest(ctx, http.MethodGet, url, nil)
if err != nil {
return nil, err
}

var rules []models.Rule
if err := handleResponse(resp, http.StatusOK, &rules); err != nil {
return nil, err
}

return rules, nil
}

// CreateGlobalRule Creates a new global rule.
// POST /admin/rules
// See: https://www.apicur.io/registry/docs/apicurio-registry/3.0.x/assets-attachments/registry-rest-api.htm#tag/Global-rules/operation/createGlobalRule
func (api *AdminAPI) CreateGlobalRule(ctx context.Context, rule models.Rule, level models.RuleLevel) error {
url := fmt.Sprintf("%s/admin/rules", api.Client.BaseURL)

// Prepare the request body
body := models.CreateUpdateGlobalRuleRequest{
RuleType: rule,
Config: level,
}
resp, err := api.executeRequest(ctx, http.MethodPost, url, body)
if err != nil {
return err
}

return handleResponse(resp, http.StatusNoContent, nil)
}

// DeleteAllGlobalRule Adds a rule to the list of globally configured rules.
// DELETE /admin/rules
// See: https://www.apicur.io/registry/docs/apicurio-registry/3.0.x/assets-attachments/registry-rest-api.htm#tag/Global-rules/operation/deleteAllGlobalRules
func (api *AdminAPI) DeleteAllGlobalRule(ctx context.Context) error {
url := fmt.Sprintf("%s/admin/rules", api.Client.BaseURL)
resp, err := api.executeRequest(ctx, http.MethodDelete, url, nil)
if err != nil {
return err
}

return handleResponse(resp, http.StatusNoContent, nil)
}

// GetGlobalRule Returns information about the named globally configured rule.
// GET /admin/rules/{rule}
// See: https://www.apicur.io/registry/docs/apicurio-registry/3.0.x/assets-attachments/registry-rest-api.htm#tag/Global-rules/operation/getGlobalRuleConfig
func (api *AdminAPI) GetGlobalRule(ctx context.Context, rule models.Rule) (models.RuleLevel, error) {
url := fmt.Sprintf("%s/admin/rules/%s", api.Client.BaseURL, rule)
resp, err := api.executeRequest(ctx, http.MethodGet, url, nil)
if err != nil {
return "", err
}

var globalRule models.GlobalRuleResponse
if err := handleResponse(resp, http.StatusOK, &globalRule); err != nil {
return "", err
}

return globalRule.Config, nil
}

// UpdateGlobalRule Updates the configuration of the named globally configured rule.
// PUT /admin/rules/{rule}
// See https://www.apicur.io/registry/docs/apicurio-registry/3.0.x/assets-attachments/registry-rest-api.htm#tag/Global-rules/operation/updateGlobalRuleConfig
func (api *AdminAPI) UpdateGlobalRule(ctx context.Context, rule models.Rule, level models.RuleLevel) error {
url := fmt.Sprintf("%s/admin/rules/%s", api.Client.BaseURL, rule)

// Prepare the request body
body := models.CreateUpdateGlobalRuleRequest{
RuleType: rule,
Config: level,
}
resp, err := api.executeRequest(ctx, http.MethodPut, url, body)
if err != nil {
return err
}

var globalRule models.GlobalRuleResponse
if err := handleResponse(resp, http.StatusOK, &globalRule); err != nil {
return err
}

return nil
}

// DeleteGlobalRule Deletes the named globally configured rule.
// DELETE /admin/rules/{rule}
// See https://www.apicur.io/registry/docs/apicurio-registry/3.0.x/assets-attachments/registry-rest-api.htm#tag/Global-rules/operation/deleteGlobalRule
func (api *AdminAPI) DeleteGlobalRule(ctx context.Context, rule models.Rule) error {
url := fmt.Sprintf("%s/admin/rules/%s", api.Client.BaseURL, rule)
resp, err := api.executeRequest(ctx, http.MethodDelete, url, nil)
if err != nil {
return err
}

return handleResponse(resp, http.StatusNoContent, nil)
}

// executeRequest handles the creation and execution of an HTTP request.
func (api *AdminAPI) executeRequest(ctx context.Context, method, url string, body interface{}) (*http.Response, error) {
var reqBody []byte
var err error
contentType := "*/*"

switch v := body.(type) {
case string:
reqBody = []byte(v)
contentType = "*/*"
case []byte:
reqBody = v
contentType = "*/*"
default:
contentType = "application/json"
reqBody, err = json.Marshal(body)
if err != nil {
return nil, errors.Wrap(err, "failed to marshal request body as JSON")
}
}

// Create the HTTP request
req, err := http.NewRequestWithContext(ctx, method, url, bytes.NewReader(reqBody))
if err != nil {
return nil, errors.Wrap(err, "failed to create HTTP request")
}

// Set appropriate Content-Type header
if body != nil {
req.Header.Set("Content-Type", contentType)
}

// Execute the request
resp, err := api.Client.Do(req)
if err != nil {
return nil, errors.Wrap(err, "failed to execute HTTP request")
}

return resp, nil
}
Loading

0 comments on commit 6e9a994

Please sign in to comment.