Showing preview only (2,870K chars total). Download the full file or copy to clipboard to get everything.
Repository: micro/go-micro
Branch: master
Commit: 7b785df30271
Files: 676
Total size: 2.6 MB
Directory structure:
gitextract_cdtwe_82/
├── .editorconfig
├── .github/
│ ├── FUNDING.yml
│ ├── ISSUE_TEMPLATE/
│ │ ├── bug_report.md
│ │ ├── feature_request.md
│ │ ├── performance.md
│ │ └── question.md
│ └── workflows/
│ ├── release.yml
│ ├── tests.yaml
│ └── website.yml
├── .gitignore
├── .golangci.yaml
├── .goreleaser.yaml
├── .vscode/
│ └── settings.json
├── CHANGELOG.md
├── CLAUDE.md
├── CONTRIBUTING.md
├── Dockerfile
├── LICENSE
├── Makefile
├── README.md
├── ROADMAP.md
├── SECURITY.md
├── ai/
│ ├── README.md
│ ├── anthropic/
│ │ ├── anthropic.go
│ │ └── anthropic_test.go
│ ├── model.go
│ ├── openai/
│ │ ├── openai.go
│ │ └── openai_test.go
│ └── options.go
├── auth/
│ ├── ANALYSIS.md
│ ├── auth.go
│ ├── jwt/
│ │ ├── jwt.go
│ │ └── token/
│ │ ├── jwt.go
│ │ ├── jwt_test.go
│ │ ├── options.go
│ │ ├── test/
│ │ │ ├── sample_key
│ │ │ ├── sample_key 2
│ │ │ └── sample_key.pub
│ │ └── token.go
│ ├── noop/
│ │ └── noop.go
│ ├── noop.go
│ ├── options.go
│ ├── rules.go
│ └── rules_test.go
├── broker/
│ ├── broker.go
│ ├── http.go
│ ├── http_test.go
│ ├── memory.go
│ ├── memory_test.go
│ ├── nats/
│ │ ├── context.go
│ │ ├── nats.go
│ │ ├── nats_test.go
│ │ ├── options.go
│ │ ├── pool.go
│ │ └── pool_test.go
│ ├── options.go
│ └── rabbitmq/
│ ├── auth.go
│ ├── channel.go
│ ├── connection.go
│ ├── connection_test.go
│ ├── context.go
│ ├── options.go
│ ├── rabbitmq.go
│ └── rabbitmq_test.go
├── cache/
│ ├── cache.go
│ ├── memory.go
│ ├── memory_test.go
│ ├── options.go
│ ├── options_test.go
│ └── redis/
│ ├── options.go
│ ├── options_test.go
│ ├── redis.go
│ └── redis_test.go
├── client/
│ ├── backoff.go
│ ├── backoff_test.go
│ ├── cache.go
│ ├── cache_test.go
│ ├── client.go
│ ├── common_test.go
│ ├── context.go
│ ├── grpc/
│ │ ├── codec.go
│ │ ├── error.go
│ │ ├── grpc.go
│ │ ├── grpc_pool.go
│ │ ├── grpc_pool_test.go
│ │ ├── grpc_test.go
│ │ ├── message.go
│ │ ├── options.go
│ │ ├── request.go
│ │ ├── request_test.go
│ │ ├── response.go
│ │ └── stream.go
│ ├── options.go
│ ├── options_test.go
│ ├── retry.go
│ ├── rpc_client.go
│ ├── rpc_client_test.go
│ ├── rpc_codec.go
│ ├── rpc_message.go
│ ├── rpc_request.go
│ ├── rpc_request_test.go
│ ├── rpc_response.go
│ ├── rpc_stream.go
│ └── wrapper.go
├── cmd/
│ ├── cmd.go
│ ├── micro/
│ │ ├── README.md
│ │ ├── cli/
│ │ │ ├── README.md
│ │ │ ├── build/
│ │ │ │ └── build.go
│ │ │ ├── cli.go
│ │ │ ├── deploy/
│ │ │ │ └── deploy.go
│ │ │ ├── gen/
│ │ │ │ └── generate.go
│ │ │ ├── init/
│ │ │ │ └── init.go
│ │ │ ├── new/
│ │ │ │ ├── new.go
│ │ │ │ └── template/
│ │ │ │ ├── handler.go
│ │ │ │ ├── ignore.go
│ │ │ │ ├── main.go
│ │ │ │ ├── makefile.go
│ │ │ │ ├── module.go
│ │ │ │ ├── proto.go
│ │ │ │ └── readme.go
│ │ │ ├── remote/
│ │ │ │ └── remote.go
│ │ │ └── util/
│ │ │ ├── dynamic.go
│ │ │ ├── dynamic_test.go
│ │ │ └── util.go
│ │ ├── main.go
│ │ ├── mcp/
│ │ │ ├── EXAMPLES.md
│ │ │ ├── mcp.go
│ │ │ └── mcp_test.go
│ │ ├── run/
│ │ │ ├── config/
│ │ │ │ ├── config.go
│ │ │ │ └── config_test.go
│ │ │ ├── run.go
│ │ │ └── watcher/
│ │ │ └── watcher.go
│ │ ├── server/
│ │ │ ├── gateway.go
│ │ │ ├── server.go
│ │ │ └── util_jwt.go
│ │ └── web/
│ │ ├── main.js
│ │ ├── styles.css
│ │ └── templates/
│ │ ├── api.html
│ │ ├── auth_login.html
│ │ ├── auth_tokens.html
│ │ ├── auth_users.html
│ │ ├── base.html
│ │ ├── form.html
│ │ ├── home.html
│ │ ├── log.html
│ │ ├── logs.html
│ │ ├── playground.html
│ │ ├── scopes.html
│ │ ├── service.html
│ │ └── status.html
│ ├── micro-mcp-gateway/
│ │ ├── Dockerfile
│ │ └── main.go
│ ├── options.go
│ └── protoc-gen-micro/
│ ├── README.md
│ ├── examples/
│ │ ├── greeter/
│ │ │ ├── greeter.pb.go
│ │ │ ├── greeter.pb.micro.go
│ │ │ └── greeter.proto
│ │ └── user/
│ │ ├── user.pb.micro.go.example
│ │ └── user.proto
│ ├── generator/
│ │ ├── Makefile
│ │ ├── generator.go
│ │ └── name_test.go
│ ├── main.go
│ └── plugin/
│ └── micro/
│ ├── micro.go
│ └── micro_test.go
├── codec/
│ ├── bytes/
│ │ ├── bytes.go
│ │ └── marshaler.go
│ ├── codec.go
│ ├── grpc/
│ │ ├── grpc.go
│ │ └── util.go
│ ├── json/
│ │ ├── any_test.go
│ │ ├── codec_test.go
│ │ ├── json.go
│ │ └── marshaler.go
│ ├── jsonrpc/
│ │ ├── client.go
│ │ ├── jsonrpc.go
│ │ └── server.go
│ ├── proto/
│ │ ├── marshaler.go
│ │ ├── message.go
│ │ └── proto.go
│ ├── protorpc/
│ │ ├── envelope.pb.go
│ │ ├── envelope.pb.micro.go
│ │ ├── envelope.proto
│ │ ├── netstring.go
│ │ └── protorpc.go
│ └── text/
│ └── text.go
├── config/
│ ├── README.md
│ ├── config.go
│ ├── default.go
│ ├── default_test.go
│ ├── encoder/
│ │ ├── encoder.go
│ │ └── json/
│ │ └── json.go
│ ├── loader/
│ │ ├── loader.go
│ │ └── memory/
│ │ ├── memory.go
│ │ └── options.go
│ ├── options.go
│ ├── reader/
│ │ ├── json/
│ │ │ ├── json.go
│ │ │ ├── json_test.go
│ │ │ ├── values.go
│ │ │ └── values_test.go
│ │ ├── options.go
│ │ ├── preprocessor.go
│ │ ├── preprocessor_test.go
│ │ └── reader.go
│ ├── secrets/
│ │ ├── box/
│ │ │ ├── box.go
│ │ │ └── box_test.go
│ │ ├── secretbox/
│ │ │ ├── secretbox.go
│ │ │ └── secretbox_test.go
│ │ └── secrets.go
│ ├── source/
│ │ ├── changeset.go
│ │ ├── cli/
│ │ │ ├── README.md
│ │ │ ├── cli.go
│ │ │ ├── cli_test.go
│ │ │ ├── options.go
│ │ │ └── util.go
│ │ ├── env/
│ │ │ ├── README.md
│ │ │ ├── env.go
│ │ │ ├── env_test.go
│ │ │ ├── options.go
│ │ │ └── watcher.go
│ │ ├── file/
│ │ │ ├── README.md
│ │ │ ├── file.go
│ │ │ ├── file_test.go
│ │ │ ├── format.go
│ │ │ ├── format_test.go
│ │ │ ├── options.go
│ │ │ ├── watcher.go
│ │ │ ├── watcher_linux.go
│ │ │ └── watcher_test.go
│ │ ├── flag/
│ │ │ ├── README.md
│ │ │ ├── flag.go
│ │ │ ├── flag_test.go
│ │ │ └── options.go
│ │ ├── memory/
│ │ │ ├── README.md
│ │ │ ├── memory.go
│ │ │ ├── options.go
│ │ │ └── watcher.go
│ │ ├── nats/
│ │ │ ├── README.md
│ │ │ ├── nats.go
│ │ │ ├── options.go
│ │ │ └── watcher.go
│ │ ├── noop.go
│ │ ├── options.go
│ │ └── source.go
│ └── value.go
├── contrib/
│ ├── go-micro-llamaindex/
│ │ ├── .gitignore
│ │ ├── README.md
│ │ ├── examples/
│ │ │ ├── basic_agent.py
│ │ │ └── rag_with_services.py
│ │ ├── go_micro_llamaindex/
│ │ │ ├── __init__.py
│ │ │ ├── exceptions.py
│ │ │ └── toolkit.py
│ │ ├── pyproject.toml
│ │ └── tests/
│ │ ├── __init__.py
│ │ └── test_toolkit.py
│ └── langchain-go-micro/
│ ├── .gitignore
│ ├── CONTRIBUTING.md
│ ├── README.md
│ ├── examples/
│ │ ├── basic_agent.py
│ │ └── multi_agent.py
│ ├── langchain_go_micro/
│ │ ├── __init__.py
│ │ ├── exceptions.py
│ │ └── toolkit.py
│ ├── pyproject.toml
│ └── tests/
│ └── test_toolkit.py
├── debug/
│ ├── handler/
│ │ └── debug.go
│ ├── log/
│ │ ├── log.go
│ │ ├── memory/
│ │ │ ├── memory.go
│ │ │ ├── memory_test.go
│ │ │ └── stream.go
│ │ ├── noop/
│ │ │ └── noop.go
│ │ ├── options.go
│ │ └── os.go
│ ├── profile/
│ │ ├── http/
│ │ │ └── http.go
│ │ ├── pprof/
│ │ │ └── pprof.go
│ │ └── profile.go
│ ├── proto/
│ │ ├── debug.pb.go
│ │ ├── debug.pb.micro.go
│ │ └── debug.proto
│ ├── stats/
│ │ ├── default.go
│ │ └── stats.go
│ └── trace/
│ ├── default.go
│ ├── noop.go
│ ├── options.go
│ └── trace.go
├── errors/
│ ├── errors.go
│ ├── errors.pb.go
│ ├── errors.pb.micro.go
│ ├── errors.proto
│ └── errors_test.go
├── event.go
├── events/
│ ├── events.go
│ ├── memory.go
│ ├── natsjs/
│ │ ├── README.md
│ │ ├── helpers_test.go
│ │ ├── nats.go
│ │ ├── nats_test.go
│ │ └── options.go
│ ├── options.go
│ ├── store.go
│ ├── store_test.go
│ └── stream_test.go
├── examples/
│ ├── README.md
│ ├── agent-demo/
│ │ ├── README.md
│ │ └── main.go
│ ├── auth/
│ │ ├── .gitignore
│ │ ├── README.md
│ │ ├── client/
│ │ │ └── main.go
│ │ ├── proto/
│ │ │ ├── greeter.pb.go
│ │ │ └── greeter.proto
│ │ └── server/
│ │ └── main.go
│ ├── deployment/
│ │ ├── Dockerfile
│ │ ├── Dockerfile.gateway
│ │ ├── README.md
│ │ └── docker-compose.yml
│ ├── hello-world/
│ │ ├── README.md
│ │ ├── go.mod
│ │ ├── go.sum
│ │ └── main.go
│ ├── mcp/
│ │ ├── README.md
│ │ ├── crud/
│ │ │ ├── README.md
│ │ │ └── main.go
│ │ ├── documented/
│ │ │ ├── README.md
│ │ │ └── main.go
│ │ ├── hello/
│ │ │ ├── README.md
│ │ │ └── main.go
│ │ ├── platform/
│ │ │ ├── README.md
│ │ │ └── main.go
│ │ └── workflow/
│ │ ├── README.md
│ │ └── main.go
│ ├── multi-service/
│ │ └── main.go
│ └── web-service/
│ ├── README.md
│ ├── go.mod
│ ├── go.sum
│ └── main.go
├── gateway/
│ ├── api/
│ │ ├── README.md
│ │ └── gateway.go
│ └── mcp/
│ ├── DOCUMENTATION.md
│ ├── benchmark_test.go
│ ├── circuitbreaker.go
│ ├── circuitbreaker_test.go
│ ├── deploy/
│ │ └── helm/
│ │ └── mcp-gateway/
│ │ ├── Chart.yaml
│ │ ├── README.md
│ │ ├── templates/
│ │ │ ├── NOTES.txt
│ │ │ ├── _helpers.tpl
│ │ │ ├── deployment.yaml
│ │ │ ├── hpa.yaml
│ │ │ ├── ingress.yaml
│ │ │ ├── service.yaml
│ │ │ └── serviceaccount.yaml
│ │ └── values.yaml
│ ├── example_test.go
│ ├── mcp.go
│ ├── mcp_test.go
│ ├── option.go
│ ├── otel.go
│ ├── otel_test.go
│ ├── parser.go
│ ├── ratelimit.go
│ ├── stdio.go
│ ├── websocket.go
│ └── websocket_test.go
├── go.mod
├── go.sum
├── health/
│ ├── health.go
│ └── health_test.go
├── internal/
│ ├── README.md
│ ├── docs/
│ │ ├── CURRENT_STATUS_SUMMARY.md
│ │ ├── IMPLEMENTATION_SUMMARY.md
│ │ ├── PROJECT_STATUS_2026.md
│ │ └── ROADMAP_2026.md
│ ├── scripts/
│ │ └── install.sh
│ ├── test/
│ │ ├── service.go
│ │ ├── testing.go
│ │ └── testing_test.go
│ ├── util/
│ │ ├── addr/
│ │ │ ├── addr.go
│ │ │ └── addr_test.go
│ │ ├── backoff/
│ │ │ └── backoff.go
│ │ ├── buf/
│ │ │ └── buf.go
│ │ ├── grpc/
│ │ │ ├── grpc.go
│ │ │ └── grpc_test.go
│ │ ├── http/
│ │ │ ├── http.go
│ │ │ ├── http_test.go
│ │ │ ├── options.go
│ │ │ └── roundtripper.go
│ │ ├── jitter/
│ │ │ └── jitter.go
│ │ ├── mdns/
│ │ │ ├── .gitignore
│ │ │ ├── client.go
│ │ │ ├── dns_sd.go
│ │ │ ├── dns_sd_test.go
│ │ │ ├── server.go
│ │ │ ├── server_test.go
│ │ │ ├── zone.go
│ │ │ └── zone_test.go
│ │ ├── net/
│ │ │ ├── net.go
│ │ │ └── net_test.go
│ │ ├── pool/
│ │ │ ├── default.go
│ │ │ ├── default_test.go
│ │ │ ├── options.go
│ │ │ └── pool.go
│ │ ├── registry/
│ │ │ ├── util.go
│ │ │ └── util_test.go
│ │ ├── ring/
│ │ │ ├── buffer.go
│ │ │ └── buffer_test.go
│ │ ├── signal/
│ │ │ └── signal.go
│ │ ├── socket/
│ │ │ ├── pool.go
│ │ │ └── socket.go
│ │ ├── test/
│ │ │ └── test.go
│ │ ├── tls/
│ │ │ ├── tls.go
│ │ │ └── tls_test.go
│ │ └── wrapper/
│ │ ├── wrapper.go
│ │ └── wrapper_test.go
│ └── website/
│ ├── .gitignore
│ ├── Gemfile
│ ├── README.md
│ ├── _config.yml
│ ├── _data/
│ │ └── navigation.yml
│ ├── _layouts/
│ │ ├── blog.html
│ │ └── default.html
│ ├── badge.html
│ ├── blog/
│ │ ├── 1.md
│ │ ├── 2.md
│ │ ├── 3.md
│ │ ├── 4.md
│ │ ├── 5.md
│ │ ├── 6.md
│ │ ├── 7.md
│ │ ├── 8.md
│ │ └── index.html
│ ├── docs/
│ │ ├── REFLECTION-EVALUATION-SUMMARY.md
│ │ ├── SECURITY_MIGRATION.md
│ │ ├── TLS_SECURITY_UPDATE.md
│ │ ├── architecture/
│ │ │ ├── adr-001-plugin-architecture.md
│ │ │ ├── adr-004-mdns-default-registry.md
│ │ │ ├── adr-009-progressive-configuration.md
│ │ │ ├── adr-010-unified-gateway.md
│ │ │ ├── adr-template.md
│ │ │ └── index.md
│ │ ├── architecture.md
│ │ ├── broker.md
│ │ ├── client-server.md
│ │ ├── config.md
│ │ ├── contributing.md
│ │ ├── deployment.md
│ │ ├── examples/
│ │ │ ├── hello-service.md
│ │ │ ├── index.md
│ │ │ ├── pubsub-nats.md
│ │ │ ├── realworld/
│ │ │ │ ├── api-gateway.md
│ │ │ │ ├── graceful-shutdown.md
│ │ │ │ └── index.md
│ │ │ ├── registry-consul.md
│ │ │ ├── rpc-client.md
│ │ │ ├── store-postgres.md
│ │ │ └── transport-nats.md
│ │ ├── getting-started.md
│ │ ├── guides/
│ │ │ ├── agent-patterns.md
│ │ │ ├── ai-native-services.md
│ │ │ ├── cli-gateway.md
│ │ │ ├── comparison.md
│ │ │ ├── deployment.md
│ │ │ ├── error-handling.md
│ │ │ ├── grpc-compatibility.md
│ │ │ ├── health.md
│ │ │ ├── mcp-security.md
│ │ │ ├── micro-run.md
│ │ │ ├── migration/
│ │ │ │ ├── add-mcp.md
│ │ │ │ ├── from-grpc.md
│ │ │ │ └── index.md
│ │ │ ├── testing.md
│ │ │ ├── tool-descriptions.md
│ │ │ └── troubleshooting.md
│ │ ├── hosting.md
│ │ ├── index.md
│ │ ├── mcp.md
│ │ ├── model.md
│ │ ├── observability.md
│ │ ├── performance.md
│ │ ├── plugins.md
│ │ ├── quickstart.md
│ │ ├── reflection-removal-analysis.md
│ │ ├── registry.md
│ │ ├── roadmap-2026.md
│ │ ├── roadmap.md
│ │ ├── search.md
│ │ ├── server.md
│ │ ├── store.md
│ │ └── transport.md
│ ├── index.html
│ └── install.sh
├── logger/
│ ├── context.go
│ ├── debug_handler.go
│ ├── debug_test.go
│ ├── default.go
│ ├── helper.go
│ ├── level.go
│ ├── logger.go
│ ├── logger_test.go
│ └── options.go
├── metadata/
│ ├── metadata.go
│ └── metadata_test.go
├── micro.go
├── model/
│ ├── README.md
│ ├── memory/
│ │ ├── memory.go
│ │ └── memory_test.go
│ ├── memory.go
│ ├── model.go
│ ├── model_test.go
│ ├── options.go
│ ├── postgres/
│ │ └── postgres.go
│ ├── query.go
│ ├── schema.go
│ └── sqlite/
│ ├── sqlite.go
│ └── sqlite_test.go
├── options.go
├── registry/
│ ├── cache/
│ │ ├── README.md
│ │ ├── cache.go
│ │ ├── cache_test.go
│ │ └── options.go
│ ├── consul/
│ │ ├── consul.go
│ │ ├── encoding.go
│ │ ├── encoding_test.go
│ │ ├── options.go
│ │ ├── registry_test.go
│ │ ├── watcher.go
│ │ └── watcher_test.go
│ ├── etcd/
│ │ ├── PERFORMANCE.md
│ │ ├── etcd.go
│ │ ├── etcd_test.go
│ │ ├── options.go
│ │ └── watcher.go
│ ├── mdns_registry.go
│ ├── mdns_test.go
│ ├── memory.go
│ ├── memory_test.go
│ ├── memory_util.go
│ ├── memory_watcher.go
│ ├── nats/
│ │ ├── nats.go
│ │ ├── nats_assert_test.go
│ │ ├── nats_environment_test.go
│ │ ├── nats_options.go
│ │ ├── nats_registry.go
│ │ ├── nats_test.go
│ │ ├── nats_util.go
│ │ └── nats_watcher.go
│ ├── options.go
│ ├── options_test.go
│ ├── registry.go
│ └── watcher.go
├── selector/
│ ├── common_test.go
│ ├── default.go
│ ├── default_test.go
│ ├── filter.go
│ ├── filter_test.go
│ ├── options.go
│ ├── selector.go
│ ├── strategy.go
│ └── strategy_test.go
├── server/
│ ├── comments.go
│ ├── comments_test.go
│ ├── context.go
│ ├── doc.go
│ ├── extractor.go
│ ├── extractor_test.go
│ ├── grpc/
│ │ ├── codec.go
│ │ ├── context.go
│ │ ├── error.go
│ │ ├── extractor.go
│ │ ├── extractor_test.go
│ │ ├── grpc.go
│ │ ├── handler.go
│ │ ├── options.go
│ │ ├── request.go
│ │ ├── response.go
│ │ ├── server.go
│ │ ├── stream.go
│ │ ├── subscriber.go
│ │ └── util.go
│ ├── handler.go
│ ├── mock/
│ │ ├── mock.go
│ │ ├── mock_handler.go
│ │ ├── mock_subscriber.go
│ │ └── mock_test.go
│ ├── options.go
│ ├── proto/
│ │ ├── server.pb.go
│ │ ├── server.pb.micro.go
│ │ └── server.proto
│ ├── rpc_codec.go
│ ├── rpc_codec_test.go
│ ├── rpc_event.go
│ ├── rpc_events.go
│ ├── rpc_events_test.go
│ ├── rpc_handler.go
│ ├── rpc_helper.go
│ ├── rpc_request.go
│ ├── rpc_response.go
│ ├── rpc_router.go
│ ├── rpc_server.go
│ ├── rpc_stream.go
│ ├── rpc_stream_test.go
│ ├── rpc_util.go
│ ├── server.go
│ ├── subscriber.go
│ └── wrapper.go
├── service/
│ ├── group.go
│ ├── options.go
│ ├── profile/
│ │ └── profile.go
│ └── service.go
├── store/
│ ├── file.go
│ ├── file_test.go
│ ├── memory.go
│ ├── mysql/
│ │ ├── mysql.go
│ │ └── mysql_test.go
│ ├── nats-js-kv/
│ │ ├── README.md
│ │ ├── context.go
│ │ ├── helpers_test.go
│ │ ├── keys.go
│ │ ├── nats.go
│ │ ├── nats_test.go
│ │ ├── options.go
│ │ └── test_data.go
│ ├── noop.go
│ ├── options.go
│ ├── postgres/
│ │ ├── README.md
│ │ ├── metadata.go
│ │ ├── pgx/
│ │ │ ├── README.md
│ │ │ ├── db.go
│ │ │ ├── metadata.go
│ │ │ ├── pgx.go
│ │ │ ├── pgx_test.go
│ │ │ ├── queries.go
│ │ │ └── templates.go
│ │ ├── postgres.go
│ │ └── postgres_test.go
│ └── store.go
├── transport/
│ ├── context.go
│ ├── grpc/
│ │ ├── grpc.go
│ │ ├── grpc_test.go
│ │ ├── handler.go
│ │ ├── proto/
│ │ │ ├── transport.pb.go
│ │ │ ├── transport.pb.micro.go
│ │ │ ├── transport.proto
│ │ │ └── transport_grpc.pb.go
│ │ └── socket.go
│ ├── headers/
│ │ └── headers.go
│ ├── http2_buf_pool.go
│ ├── http_client.go
│ ├── http_client_test.go
│ ├── http_listener.go
│ ├── http_proxy.go
│ ├── http_socket.go
│ ├── http_transport.go
│ ├── http_transport_test.go
│ ├── memory.go
│ ├── memory_test.go
│ ├── nats/
│ │ ├── nats.go
│ │ ├── nats_test.go
│ │ ├── options.go
│ │ ├── pool.go
│ │ └── pool_test.go
│ ├── options.go
│ └── transport.go
├── web/
│ ├── options.go
│ ├── service.go
│ ├── service_test.go
│ ├── sse.go
│ ├── sse_test.go
│ ├── web.go
│ └── web_test.go
└── wrapper/
├── auth/
│ ├── README.md
│ ├── client.go
│ ├── metadata.go
│ └── server.go
└── trace/
└── opentelemetry/
├── README.md
├── opentelemetry.go
├── options.go
└── wrapper.go
================================================
FILE CONTENTS
================================================
================================================
FILE: .editorconfig
================================================
# EditorConfig for go-micro
# https://editorconfig.org
root = true
[*]
charset = utf-8
end_of_line = lf
insert_final_newline = true
trim_trailing_whitespace = true
[*.go]
indent_style = tab
indent_size = 4
[*.{yml,yaml}]
indent_style = space
indent_size = 2
[*.{json,proto}]
indent_style = space
indent_size = 2
[*.md]
trim_trailing_whitespace = false
indent_style = space
indent_size = 2
[Makefile]
indent_style = tab
================================================
FILE: .github/FUNDING.yml
================================================
github: asim
================================================
FILE: .github/ISSUE_TEMPLATE/bug_report.md
================================================
---
name: Bug report
about: Create a report to help us improve
title: '[BUG] '
labels: bug
assignees: ''
---
## Describe the bug
A clear and concise description of what the bug is.
## To Reproduce
Steps to reproduce the behavior:
1. Create service with '...'
2. Configure plugin '...'
3. Run command '...'
4. See error
## Expected behavior
A clear and concise description of what you expected to happen.
## Code sample
```go
// Minimal reproducible code
```
## Environment
- Go Micro version: [e.g. v5.3.0]
- Go version: [run `go version`]
- OS/Platform: [e.g. Ubuntu 22.04, macOS 14, Docker]
- Plugins/Integrations: [e.g. consul registry, nats broker, redis cache]
## Logs
```
Paste relevant logs here (use -v flag for verbose output)
```
## Checklist
- [ ] I've searched existing issues and this is not a duplicate
- [ ] I've provided a minimal code sample that reproduces the issue
- [ ] I've included my environment details
- [ ] I've checked the documentation
## Additional context
Add any other context about the problem here.
## Helpful Resources
- [Troubleshooting Guide](https://github.com/micro/go-micro/tree/master/internal/website/docs/getting-started.md)
- [Examples](https://github.com/micro/go-micro/tree/master/examples)
- [API Reference](https://pkg.go.dev/go-micro.dev/v5)
- [Discord Community](https://discord.gg/jwTYuUVAGh)
================================================
FILE: .github/ISSUE_TEMPLATE/feature_request.md
================================================
---
name: Feature request
about: Suggest an idea for this project
title: '[FEATURE] '
labels: enhancement
assignees: ''
---
## Is your feature request related to a problem?
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
## Describe the solution you'd like
A clear and concise description of what you want to happen.
## Describe alternatives you've considered
A clear and concise description of any alternative solutions or features you've considered.
## Use case
Describe how this feature would be used in practice. What problem does it solve?
**Example:**
```go
// Show how the feature would be used
```
## Implementation ideas (optional)
If you have thoughts on how this could be implemented, share them here.
## Additional context
Add any other context, code examples, or screenshots about the feature request here.
## Checklist
- [ ] I've searched existing issues and this is not a duplicate
- [ ] I've checked the roadmap and this isn't already planned
- [ ] I've provided a clear use case
- [ ] I'd be willing to submit a PR for this feature (optional)
## Helpful Resources
- [Roadmap](https://github.com/micro/go-micro/blob/master/ROADMAP.md)
- [Contributing Guide](https://github.com/micro/go-micro/blob/master/CONTRIBUTING.md)
- [Architecture Docs](https://github.com/micro/go-micro/tree/master/internal/website/docs/architecture.md)
- [Discord Community](https://discord.gg/jwTYuUVAGh)
================================================
FILE: .github/ISSUE_TEMPLATE/performance.md
================================================
---
name: Performance issue
about: Report a performance problem or regression
title: '[PERFORMANCE] '
labels: performance
assignees: ''
---
## Performance Issue
**Symptom:**
Describe the performance problem (e.g., high latency, memory leak, CPU usage)
**Expected Performance:**
What performance did you expect?
## Benchmarks
Please provide benchmarks or profiling data:
```bash
# CPU profiling
go test -cpuprofile=cpu.prof -bench=.
# Memory profiling
go test -memprofile=mem.prof -bench=.
# Results
```
**Before/After comparison (if applicable):**
- Before: X req/sec, Y ms latency
- After: X req/sec, Y ms latency
## Code Sample
```go
// Minimal code that demonstrates the performance issue
```
## Environment
- Go Micro version: [e.g. v5.3.0]
- Go version: [run `go version`]
- Hardware: [e.g. 4 CPU, 8GB RAM]
- OS: [e.g. Ubuntu 22.04]
- Load: [e.g. 1000 req/sec, 100 concurrent connections]
## Profiling Data
Attach pprof profiles if available:
- CPU profile
- Memory profile
- Goroutine dump
## Additional Context
Add any other context about the performance issue.
## Resources
- [Performance Guide](https://github.com/micro/go-micro/tree/master/internal/website/docs/performance.md)
- [Benchmarking](https://pkg.go.dev/testing#hdr-Benchmarks)
================================================
FILE: .github/ISSUE_TEMPLATE/question.md
================================================
---
name: Question
about: Ask a question about using Go Micro
title: '[QUESTION] '
labels: question
assignees: ''
---
## Your question
A clear and concise question about Go Micro usage.
## What have you tried?
Describe what you've already attempted or researched.
## Code sample (if applicable)
```go
// Your code here
```
## Context
Provide any additional context that might help answer your question.
## Resources you've checked
- [ ] [Getting Started Guide](https://github.com/micro/go-micro/tree/master/internal/website/docs/getting-started.md)
- [ ] [Examples](https://github.com/micro/go-micro/tree/master/internal/website/docs/examples)
- [ ] [API Documentation](https://pkg.go.dev/go-micro.dev/v5)
- [ ] Searched existing issues
## Helpful links
- [Documentation](https://github.com/micro/go-micro/tree/master/internal/website/docs)
- [Plugins Guide](https://github.com/micro/go-micro/tree/master/internal/website/docs/plugins.md)
================================================
FILE: .github/workflows/release.yml
================================================
name: goreleaser
on:
push:
tags:
- 'v*.*.*'
permissions:
contents: write
id-token: write
packages: write
attestations: write
jobs:
goreleaser:
runs-on: ubuntu-latest
steps:
-
name: Checkout
uses: actions/checkout@v4
with:
fetch-depth: 0
-
name: Set up Go
uses: actions/setup-go@v5
with:
go-version: stable
-
name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
-
name: Login to Docker Hub
uses: docker/login-action@v3
with:
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_PASSWORD }}
-
name: Login to GitHub Container Registry
uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.repository_owner }}
password: ${{ secrets.GITHUB_TOKEN }}
-
name: Run GoReleaser
uses: goreleaser/goreleaser-action@v7
with:
distribution: goreleaser
version: '~> v2'
args: release --clean
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
================================================
FILE: .github/workflows/tests.yaml
================================================
name: Run Tests
on:
push:
branches:
- "**"
pull_request:
types:
- opened
- reopened
branches:
- "**"
jobs:
unittests:
name: Unit Tests
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Set up Go
uses: actions/setup-go@v3
with:
go-version: 1.24
check-latest: true
cache: true
- name: Get dependencies
run: |
go install github.com/kyoh86/richgo@latest
go get -v -t -d ./...
- name: Run tests
id: tests
run: richgo test -v -race -cover ./...
env:
IN_TRAVIS_CI: yes
RICHGO_FORCE_COLOR: 1
etcd-integration:
name: Etcd Integration Tests
runs-on: ubuntu-latest
permissions:
contents: read
services:
etcd:
image: quay.io/coreos/etcd:v3.5.2
env:
ETCD_LISTEN_CLIENT_URLS: http://0.0.0.0:2379
ETCD_ADVERTISE_CLIENT_URLS: http://0.0.0.0:2379
ports:
- 2379:2379
options: >-
--health-cmd "etcdctl endpoint health"
--health-interval 10s
--health-timeout 5s
--health-retries 5
steps:
- uses: actions/checkout@v3
- name: Set up Go
uses: actions/setup-go@v3
with:
go-version: 1.24
check-latest: true
cache: true
- name: Get dependencies
run: |
go install github.com/kyoh86/richgo@latest
go get -v -t -d ./...
- name: Wait for etcd
run: |
timeout 30 bash -c 'until curl -s http://localhost:2379/health; do sleep 1; done'
- name: Run etcd integration tests
run: richgo test -v -race ./registry/etcd/...
env:
ETCD_ADDRESS: localhost:2379
IN_TRAVIS_CI: yes
RICHGO_FORCE_COLOR: 1
================================================
FILE: .github/workflows/website.yml
================================================
# Sample workflow for building and deploying a Jekyll site to GitHub Pages
name: Deploy Jekyll with GitHub Pages dependencies preinstalled
on:
# Runs on pushes targeting the default branch
push:
branches: ["master"]
# Allows you to run this workflow manually from the Actions tab
workflow_dispatch:
# Sets permissions of the GITHUB_TOKEN to allow deployment to GitHub Pages
permissions:
contents: read
pages: write
id-token: write
# Allow only one concurrent deployment, skipping runs queued between the run in-progress and latest queued.
# However, do NOT cancel in-progress runs as we want to allow these production deployments to complete.
concurrency:
group: "pages"
cancel-in-progress: false
jobs:
# Build job
build:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Setup Pages
uses: actions/configure-pages@v5
- name: Build with Jekyll
uses: actions/jekyll-build-pages@v1
with:
source: ./internal/website
destination: ./_site
- name: Upload artifact
uses: actions/upload-pages-artifact@v3
# Deployment job
deploy:
environment:
name: github-pages
url: ${{ steps.deployment.outputs.page_url }}
runs-on: ubuntu-latest
needs: build
steps:
- name: Deploy to GitHub Pages
id: deployment
uses: actions/deploy-pages@v4
================================================
FILE: .gitignore
================================================
# Develop tools
/.idea/
/.trunk
# VS Code workspace files (keep settings for consistency)
/.vscode/*
!/.vscode/settings.json
# Binaries for programs and plugins
*.exe
*.exe~
*.dll
*.so
*.dylib
# Folders
_obj
_test
_build
# Architecture specific extensions/prefixes
*.[568vq]
[568vq].out
*.cgo1.go
*.cgo2.c
_cgo_defun.c
_cgo_gotypes.go
_cgo_export.*
# Test binary, build with `go test -c`
*.test
# Output of the go coverage tool, specifically when used with LiteIDE
*.out
coverage.html
# vim temp files
*~
*.swp
*.swo
# go work files
go.work
go.work.sum
# Build artifacts
dist/
bin/
# Example binaries (go build in examples/)
examples/**/server/server
examples/**/client/client
examples/mcp/documented/documented
examples/mcp/hello/hello
# IDE-specific files
.DS_Store
/micro
================================================
FILE: .golangci.yaml
================================================
# This file contains all available configuration options
# with their default values.
# options for analysis running
run:
# go: '1.18'
# default concurrency is a available CPU number
# concurrency: 4
# timeout for analysis, e.g. 30s, 5m, default is 1m
deadline: 10m
# exit code when at least one issue was found, default is 1
issues-exit-code: 1
# include test files or not, default is true
tests: true
# which files to skip: they will be analyzed, but issues from them
# won't be reported. Default value is empty list, but there is
# no need to include all autogenerated files, we confidently recognize
# autogenerated files. If it's not please let us know.
skip-files:
[]
# - .*\\.pb\\.go$
allow-parallel-runners: true
# list of build tags, all linters use it. Default is empty list.
build-tags: []
# output configuration options
output:
# Format: colored-line-number|line-number|json|tab|checkstyle|code-climate|junit-xml|github-actions
#
# Multiple can be specified by separating them by comma, output can be provided
# for each of them by separating format name and path by colon symbol.
# Output path can be either `stdout`, `stderr` or path to the file to write to.
# Example: "checkstyle:report.json,colored-line-number"
#
# Default: colored-line-number
format: colored-line-number
# Print lines of code with issue.
# Default: true
print-issued-lines: true
# Print linter name in the end of issue text.
# Default: true
print-linter-name: true
# Make issues output unique by line.
# Default: true
uniq-by-line: true
# Add a prefix to the output file references.
# Default is no prefix.
path-prefix: ""
# Sort results by: filepath, line and column.
sort-results: true
# all available settings of specific linters
linters-settings:
wsl:
allow-cuddle-with-calls: ["Lock", "RLock", "defer"]
funlen:
lines: 80
statements: 60
varnamelen:
# The longest distance, in source lines, that is being considered a "small scope".
# Variables used in at most this many lines will be ignored.
# Default: 5
max-distance: 26
ignore-names:
- err
- id
- ch
- wg
- mu
ignore-decls:
- c echo.Context
- t testing.T
- f *foo.Bar
- e error
- i int
- const C
- T any
- m map[string]int
errcheck:
# report about not checking of errors in type assetions: `a := b.(MyStruct)`;
# default is false: such cases aren't reported by default.
check-type-assertions: true
# report about assignment of errors to blank identifier: `num, _ := strconv.Atoi(numStr)`;
# default is false: such cases aren't reported by default.
check-blank: true
govet:
# report about shadowed variables
check-shadowing: false
gofmt:
# simplify code: gofmt with `-s` option, true by default
simplify: true
gocyclo:
# minimal code complexity to report, 30 by default (but we recommend 10-20)
min-complexity: 15
maligned:
# print struct with more effective memory layout or not, false by default
suggest-new: true
dupl:
# tokens count to trigger issue, 150 by default
threshold: 100
goconst:
# minimal length of string constant, 3 by default
min-len: 3
# minimal occurrences count to trigger, 3 by default
min-occurrences: 3
depguard:
list-type: blacklist
# Packages listed here will reported as error if imported
packages:
- github.com/golang/protobuf/proto
misspell:
# Correct spellings using locale preferences for US or UK.
# Default is to use a neutral variety of English.
# Setting locale to US will correct the British spelling of 'colour' to 'color'.
locale: US
lll:
# max line length, lines longer will be reported. Default is 120.
# '\t' is counted as 1 character by default, and can be changed with the tab-width option
line-length: 120
# tab width in spaces. Default to 1.
tab-width: 1
unused:
# treat code as a program (not a library) and report unused exported identifiers; default is false.
# XXX: if you enable this setting, unused will report a lot of false-positives in text editors:
# if it's called for subdir of a project it can't find funcs usages. All text editor integrations
# with golangci-lint call it on a directory with the changed file.
check-exported: false
unparam:
# call graph construction algorithm (cha, rta). In general, use cha for libraries,
# and rta for programs with main packages. Default is cha.
algo: cha
# Inspect exported functions, default is false. Set to true if no external program/library imports your code.
# XXX: if you enable this setting, unparam will report a lot of false-positives in text editors:
# if it's called for subdir of a project it can't find external interfaces. All text editor integrations
# with golangci-lint call it on a directory with the changed file.
check-exported: false
nakedret:
# make an issue if func has more lines of code than this setting and it has naked returns; default is 30
max-func-lines: 60
nolintlint:
allow-unused: false
allow-leading-space: false
allow-no-explanation: []
require-explanation: false
require-specific: true
prealloc:
# XXX: we don't recommend using this linter before doing performance profiling.
# For most programs usage of prealloc will be a premature optimization.
# Report preallocation suggestions only on simple loops that have no returns/breaks/continues/gotos in them.
# True by default.
simple: true
range-loops: true # Report preallocation suggestions on range loops, true by default
for-loops: false # Report preallocation suggestions on for loops, false by default
cyclop:
# the maximal code complexity to report
max-complexity: 20
gomoddirectives:
replace-local: true
retract-allow-no-explanation: false
exclude-forbidden: true
linters:
enable-all: true
disable-all: false
fast: false
disable:
- golint
- varcheck
- ifshort
- structcheck
- deadcode
# - nosnakecase
- interfacer
- maligned
- scopelint
- exhaustivestruct
- testpackage
- promlinter
- nonamedreturns
- makezero
- gofumpt
- nlreturn
- thelper
# Can be considered to be enabled
- gochecknoinits
- gochecknoglobals # RIP
- dogsled
- wrapcheck
- paralleltest
- ireturn
- gomnd
- goerr113
- exhaustruct
- containedctx
- godox
- forcetypeassert
- gci
- lll
issues:
# List of regexps of issue texts to exclude, empty list by default.
# But independently from this option we use default exclude patterns,
# it can be disabled by `exclude-use-default: false`. To list all
# excluded by default patterns execute `golangci-lint run --help`
# exclude:
# - package comment should be of the form "Package services ..." # revive
# - ^ST1000 # ST1000: at least one file in a package should have a package comment (stylecheck)
# exclude-rules:
# - path: internal/app/machined/pkg/system/services
# linters:
# - dupl
exclude-rules:
- path: _test\.go
linters:
- gocyclo
- dupl
- gosec
- funlen
- varnamelen
- wsl
# Independently from option `exclude` we use default exclude patterns,
# it can be disabled by this option. To list all
# excluded by default patterns execute `golangci-lint run --help`.
# Default value for this option is true.
exclude-use-default: false
# Maximum issues count per one linter. Set to 0 to disable. Default is 50.
max-issues-per-linter: 0
# Maximum count of issues with the same text. Set to 0 to disable. Default is 3.
max-same-issues: 0
# Show only new issues: if there are unstaged changes or untracked files,
# only those changes are analyzed, else only changes in HEAD~ are analyzed.
# It's a super-useful option for integration of golangci-lint into existing
# large codebase. It's not practical to fix all existing issues at the moment
# of integration: much better don't allow issues in new code.
# Default is false.
new: false
================================================
FILE: .goreleaser.yaml
================================================
# yaml-language-server: $schema=https://goreleaser.com/static/schema.json
# vim: set ts=2 sw=2 tw=0 fo=cnqoj
version: 2
before:
hooks:
- go mod tidy
builds:
- main: ./cmd/micro
id: micro
binary: micro
env:
- CGO_ENABLED=0
- >-
{{- if eq .Os "darwin" }}
{{- if eq .Arch "amd64"}}CC=o64-clang{{- end }}
{{- if eq .Arch "arm64"}}CC=aarch64-apple-darwin20.2-clang{{- end }}
{{- end }}
{{- if eq .Os "windows" }}
{{- if eq .Arch "amd64" }}CC=x86_64-w64-mingw32-gcc{{- end }}
{{- end }}
goos:
- linux
- windows
- darwin
goarch:
- amd64
- arm
- arm64
goarm:
- 7
ignore:
- goos: windows
goarch: arm
- main: ./cmd/protoc-gen-micro
id: protoc-gen-micro
binary: protoc-gen-micro
env:
- CGO_ENABLED=0
- >-
{{- if eq .Os "darwin" }}
{{- if eq .Arch "amd64"}}CC=o64-clang{{- end }}
{{- if eq .Arch "arm64"}}CC=aarch64-apple-darwin20.2-clang{{- end }}
{{- end }}
{{- if eq .Os "windows" }}
{{- if eq .Arch "amd64" }}CC=x86_64-w64-mingw32-gcc{{- end }}
{{- end }}
goos:
- linux
- windows
- darwin
goarch:
- amd64
- arm
- arm64
goarm:
- 7
ignore:
- goos: windows
goarch: arm
archives:
- id: micro
ids:
- micro
formats: [tar.gz]
name_template: >-
{{ .Binary }}_
{{- .Os }}_
{{- .Arch }}
{{- if .Arm }}v{{ .Arm }}{{ end }}
files:
- none*
format_overrides:
- goos: windows
formats: [zip]
- id: protoc-gen-micro
ids:
- protoc-gen-micro
formats: [tar.gz]
name_template: >-
{{ .Binary }}_
{{- .Os }}_
{{- .Arch }}
{{- if .Arm }}v{{ .Arm }}{{ end }}
files:
- none*
format_overrides:
- goos: windows
formats: [zip]
report_sizes: true
changelog:
sort: asc
filters:
exclude:
- "^docs:"
- "^test:"
dockers_v2:
-
ids:
- micro
- protoc-gen-micro
images:
- "micro/micro"
- "ghcr.io/micro/go-micro"
tags:
- "v{{ .Version }}"
- "{{ if .IsNightly }}nightly{{ end }}"
- "{{ if not .IsNightly }}latest{{ end }}"
labels:
"io.artifacthub.package.readme-url": "https://raw.githubusercontent.com/micro/go-micro/refs/heads/master/README.md"
"io.artifacthub.package.logo-url": "https://www.gravatar.com/avatar/09d1da3ea9ee61753219a19016d6a672?s=120&r=g&d=404"
"org.opencontainers.image.description": "A Go Platform built for Developers"
"org.opencontainers.image.created": "{{.Date}}"
"org.opencontainers.image.title": "{{.ProjectName}}"
"org.opencontainers.image.revision": "{{.FullCommit}}"
"org.opencontainers.image.version": "{{.Version}}"
"org.opencontainers.image.source": "{{.GitURL}}"
"org.opencontainers.image.url": "{{.GitURL}}"
"org.opencontainers.image.licenses": "MIT"
platforms:
- linux/amd64
- linux/arm64
retry:
attempts: 5
delay: 5s
max_delay: 2m
================================================
FILE: .vscode/settings.json
================================================
{
"folders": [
{
"path": "."
}
],
"settings": {
"go.toolsManagement.autoUpdate": true,
"go.useLanguageServer": true,
"go.lintOnSave": "workspace",
"go.lintTool": "golangci-lint",
"go.lintFlags": [
"--fast"
],
"go.formatTool": "goimports",
"go.formatFlags": [],
"go.buildOnSave": "workspace",
"go.testOnSave": false,
"go.coverOnSave": false,
"go.testFlags": ["-v", "-race"],
"go.testTimeout": "60s",
"go.gopath": "",
"go.goroot": "",
"editor.formatOnSave": true,
"editor.codeActionsOnSave": {
"source.organizeImports": "explicit"
},
"files.exclude": {
"**/.git": true,
"**/.DS_Store": true,
"**/node_modules": true,
"**/*.test": true,
"**/coverage.out": true,
"**/coverage.html": true
},
"files.watcherExclude": {
"**/.git/objects/**": true,
"**/.git/subtree-cache/**": true,
"**/node_modules/**": true,
"**/.vscode/**": true
},
"search.exclude": {
"**/node_modules": true,
"**/bower_components": true,
"**/*.code-search": true,
"**/vendor": true,
"**/.git": true
},
"[go]": {
"editor.tabSize": 4,
"editor.insertSpaces": false,
"editor.formatOnSave": true,
"editor.defaultFormatter": "golang.go"
},
"[go.mod]": {
"editor.formatOnSave": true,
"editor.defaultFormatter": "golang.go"
},
"[markdown]": {
"editor.formatOnSave": false,
"editor.wordWrap": "on"
},
"gopls": {
"ui.semanticTokens": true,
"ui.completion.usePlaceholders": true,
"formatting.gofumpt": false,
"analyses": {
"unusedparams": true,
"shadow": true,
"fieldalignment": false
}
}
},
"extensions": {
"recommendations": [
"golang.go",
"editorconfig.editorconfig",
"redhat.vscode-yaml",
"ms-vscode.makefile-tools"
]
},
"tasks": {
"version": "2.0.0",
"tasks": [
{
"label": "Run Tests",
"type": "shell",
"command": "make test",
"group": {
"kind": "test",
"isDefault": true
},
"presentation": {
"reveal": "always",
"panel": "new"
}
},
{
"label": "Run Tests with Coverage",
"type": "shell",
"command": "make test-coverage",
"group": "test"
},
{
"label": "Run Linter",
"type": "shell",
"command": "make lint",
"group": "build"
},
{
"label": "Format Code",
"type": "shell",
"command": "make fmt",
"group": "build"
}
]
},
"launch": {
"version": "0.2.0",
"configurations": [
{
"name": "Debug Current File",
"type": "go",
"request": "launch",
"mode": "debug",
"program": "${file}"
},
{
"name": "Debug Test",
"type": "go",
"request": "launch",
"mode": "test",
"program": "${workspaceFolder}"
}
]
}
}
================================================
FILE: CHANGELOG.md
================================================
# Changelog
All notable changes to Go Micro are documented here.
Format follows [Keep a Changelog](https://keepachangelog.com/). Go Micro uses
calendar-based versions (YYYY.MM) for the AI-native era.
---
## [Unreleased]
### Added
- **Agent platform showcase** — full platform example (Users, Posts, Comments, Mail) mirroring [micro/blog](https://github.com/micro/blog), demonstrating how existing microservices become agent-accessible with zero code changes (`examples/mcp/platform/`).
- **Blog post: "Your Microservices Are Already an AI Platform"** — walkthrough of agent-service interaction patterns using real-world services (`internal/website/blog/7.md`).
- **Circuit breakers for MCP gateway** — per-tool circuit breakers protect downstream services from cascading failures. Configurable max failures, open-state timeout, and half-open probing. Available via `Options.CircuitBreaker` and `--circuit-breaker` CLI flag (`gateway/mcp/circuitbreaker.go`).
- **Helm chart for MCP gateway** — official Helm chart at `deploy/helm/mcp-gateway/` with Deployment, Service, ServiceAccount, HPA, and Ingress templates. Supports Consul/etcd/mDNS registries, JWT auth, rate limiting, audit logging, per-tool scopes, TLS ingress, and auto-scaling.
- **MCP gateway benchmarks** — comprehensive benchmark suite for tool listing, lookup, auth, rate limiting, and JSON serialization (`gateway/mcp/benchmark_test.go`)
- **Workflow example** — cross-service orchestration demo with Inventory, Orders, and Notifications services showing agents chaining multi-step workflows from natural language (`examples/mcp/workflow/`)
- **Docker Compose deployment** — production-like setup with Consul registry, standalone MCP gateway, and Jaeger tracing in one `docker-compose up` (`examples/deployment/`)
---
## [2026.03] - March 2026
### Added
#### Developer Experience
- **`micro new` MCP templates** — `micro new myservice` generates MCP-enabled services with doc comments, `@example` tags, and `WithMCP()` wired in. Use `--no-mcp` to opt out.
- **`micro.New("name")` unified API** — single way to create services: `micro.New("greeter")` or `micro.New("greeter", micro.Address(":8080"))`. Replaces `micro.NewService()` + `service.New()` dual API.
- **`service.Handle()` simplified registration** — register handlers with `service.Handle(new(Greeter))` instead of manual `server.NewHandler` + `server.Handle`.
- **`micro.NewGroup()` modular monoliths** — run multiple services in one binary with shared lifecycle: `micro.NewGroup(users, orders).Run()`.
- **`mcp.WithMCP()` one-liner** — add MCP to any service with a single option: `micro.New("name", mcp.WithMCP(":3001"))`.
- **CRUD example** — contact book service with 6 operations, rich agent docs, and validation patterns (`examples/mcp/crud/`).
#### MCP Gateway
- **WebSocket transport** — bidirectional JSON-RPC 2.0 streaming over WebSocket for real-time agent communication (`gateway/mcp/websocket.go`).
- **OpenTelemetry integration** — full span instrumentation across HTTP, stdio, and WebSocket transports with W3C trace context propagation (`gateway/mcp/otel.go`).
- **Standalone gateway binary** — `micro-mcp-gateway` with Docker support for running the MCP gateway independently of services.
- **Per-tool auth scopes** — service-level (`server.WithEndpointScopes()`) and gateway-level (`Options.Scopes`) scope enforcement with bearer token auth.
- **Rate limiting** — per-tool token bucket rate limiting (`Options.RateLimit`).
- **Audit logging** — immutable audit records per tool call with trace ID, account, scopes, duration, and errors (`Options.AuditFunc`).
#### AI Model Package
- **`model.Model` interface** — unified AI provider abstraction with `Generate()` and `Stream()` methods.
- **Anthropic Claude provider** — `model/anthropic` with tool execution and auto-calling.
- **OpenAI GPT provider** — `model/openai` with provider auto-detection from base URL.
#### Agent SDKs
- **LangChain SDK** — `contrib/langchain-go-micro/` Python package with auto-discovery, tool generation, and multi-agent workflow examples.
- **LlamaIndex SDK** — `contrib/go-micro-llamaindex/` Python package with RAG integration examples.
#### Documentation
- **AI-native services guide** — building services for AI agents from scratch
- **MCP security guide** — auth, scopes, and audit logging
- **Tool descriptions guide** — writing doc comments that improve agent performance
- **Agent patterns guide** — architecture patterns for agent integration
- **Error handling guide** — writing agent-friendly error responses with typed errors
- **Troubleshooting guide** — common MCP issues and solutions
- **Migration guide** — add MCP to existing services in 5 minutes
#### CLI
- **`micro mcp serve`** — start MCP server (stdio for Claude Code, HTTP for web agents)
- **`micro mcp list`** — list available tools (human-readable or JSON)
- **`micro mcp test`** — test tools with JSON input
- **`micro mcp docs`** — generate tool documentation
- **`micro mcp export`** — export to LangChain, OpenAPI, or JSON formats
#### Agent Playground
- **Chat-focused UI** — redesigned playground with collapsible tool calls, real-time status, and thinking indicators
- **Provider settings** — configurable OpenAI/Anthropic provider, model, and API key
### Changed
- Service interface moved to `service.Service` with `micro.Service` as a type alias for backward compatibility.
- `service.New()` returns `service.Service` interface (was `*ServiceImpl`).
- `service.NewGroup()` accepts `service.Service` interface (was `*ServiceImpl`).
- `go.mod` template in `micro new` updated to Go 1.22.
### Fixed
- Handler `Handle()` method accepts variadic `server.HandlerOption` for scopes and metadata.
- Store initialization uses service name as table automatically.
- Service `Stop()` properly aggregates errors from lifecycle hooks.
---
## [2026.02] - February 2026
### Added
- **MCP gateway library** — `gateway/mcp/` with HTTP/SSE and stdio transports, service discovery, tool generation, and JSON schema generation from Go types (2,500+ lines).
- **CLI integration** — `micro run --mcp-address` flag to start MCP alongside services.
- **Documentation extraction** — auto-extract tool descriptions from Go doc comments with `@example` tag and struct tag parsing.
- **Blog post** — "Making Microservices AI-Native with MCP"
- **MCP examples** — `examples/mcp/hello/` and `examples/mcp/documented/`
---
## [2026.01] - January 2026
### Added
- **`micro deploy`** — deploy services to any Linux server via SSH + systemd with `micro deploy user@server`.
- **`micro build`** — build Go binaries and Docker images with `micro build --docker`.
- **Blog post** — "Introducing micro deploy"
---
_For earlier changes, see the [git log](https://github.com/micro/go-micro/commits/master)._
================================================
FILE: CLAUDE.md
================================================
# CLAUDE.md - Go Micro Project Guide
## Project Overview
Go Micro is a framework for distributed systems development in Go. It provides pluggable abstractions for service discovery, RPC, pub/sub, config, auth, storage, and more.
The framework is evolving into an **AI-native platform** where every microservice is automatically accessible to AI agents via the Model Context Protocol (MCP).
## Build & Test
```bash
# Run all tests
make test
# Run tests for a specific package
go test ./gateway/mcp/...
go test ./ai/...
go test ./model/...
# Lint
make lint
# Format
make fmt
# Build CLI
go build -o micro ./cmd/micro
# Run locally with hot reload
micro run
```
## Project Structure
```
go-micro/
├── ai/ # AI model providers (Anthropic, OpenAI)
├── auth/ # Authentication (JWT, no-op)
├── broker/ # Message broker (NATS, RabbitMQ)
├── cache/ # Caching (Redis)
├── client/ # RPC client (gRPC)
├── cmd/micro/ # CLI tool (run, deploy, mcp, build, server)
├── codec/ # Message codecs (JSON, Proto)
├── config/ # Dynamic config (env, file, etcd, NATS)
├── errors/ # Error handling
├── events/ # Event system (NATS JetStream)
├── gateway/
│ ├── api/ # REST API gateway
│ └── mcp/ # MCP gateway (core AI integration)
│ └── deploy/ # Helm charts for MCP gateway
├── health/ # Health checking
├── logger/ # Logging
├── metadata/ # Context metadata
├── model/ # Typed data models (CRUD, queries, schemas)
├── registry/ # Service discovery (mDNS, Consul, etcd)
├── selector/ # Client-side load balancing
├── server/ # RPC server
├── service/ # Service interface + profiles
├── store/ # Data persistence (Postgres, NATS KV)
├── transport/ # Network transport
├── wrapper/ # Middleware (auth, trace, metrics)
├── examples/ # Working examples
└── internal/ # Non-public: docs, utils, test harness
```
## Key Architectural Decisions
- **Plugin architecture**: All abstractions use Go interfaces. Defaults work out of the box, everything is swappable.
- **Progressive complexity**: Zero-config for development, full control for production.
- **AI-native by default**: Every service is automatically an MCP tool. No extra code needed.
- **In-repo plugins**: Plugins live in the main repo to avoid version compatibility issues.
- **Reflection-based registration**: Handlers are registered via reflection for minimal boilerplate.
## Code Conventions
- Standard Go conventions (gofmt, golint)
- Functional options pattern for configuration (`WithX()` functions)
- Interface-first design: define the interface, then implement
- Tests alongside code (not in separate test directories)
- Commit messages: imperative mood, concise summary line
## Current Focus & Priorities (March 2026)
### Status
- **Q1 2026 (MCP Foundation):** COMPLETE
- **Q2 2026 (Agent DX):** COMPLETE (100%)
- **Q3 2026 (Production):** 50% complete (ahead of schedule)
### Priority 1: Agent Showcase & Examples
Build compelling demos showing agents interacting with go-micro services in realistic scenarios.
### Priority 2: Additional Protocol Support
- gRPC reflection-based MCP
- HTTP/3 support
### Priority 3: Kubernetes & Deployment
- Helm Charts for MCP gateway
- Kubernetes Operator with CRDs
### Recently Completed
- **`micro new` MCP Templates** - Scaffolds MCP-enabled services with doc comments, `@example` tags, `WithMCP()`. `--no-mcp` to opt out.
- **CRUD Example** - Contact book service with 6 operations, rich agent docs (`examples/mcp/crud/`)
- **Migration Guide** - "Add MCP to Existing Services" guide with 3 approaches
- **Troubleshooting Guide** - Common MCP issues and solutions
- **Error Handling Guide** - Patterns for agent-friendly error responses
- **Documentation Guides** - Six guides: AI-native services, MCP security, tool descriptions, agent patterns, error handling, troubleshooting
- **WithMCP Option** - One-line MCP setup (`gateway/mcp/option.go`)
- **Agent Playground Redesign** - Chat-focused UI with collapsible tool calls
- **Standalone Gateway Binary** - `micro-mcp-gateway` with Docker support
- **WebSocket Transport** - Bidirectional JSON-RPC 2.0 streaming (`gateway/mcp/websocket.go`)
- **OpenTelemetry Integration** - Full span instrumentation with W3C trace context (`gateway/mcp/otel.go`)
- **LlamaIndex SDK** - Python package with RAG examples (`contrib/go-micro-llamaindex/`)
## Key Files
| Purpose | File |
|---------|------|
| MCP Gateway | `gateway/mcp/mcp.go` |
| MCP Docs | `gateway/mcp/DOCUMENTATION.md` |
| AI Interface | `ai/model.go` |
| Model Layer | `model/model.go` |
| CLI Entry | `cmd/micro/main.go` |
| MCP CLI | `cmd/micro/mcp/` |
| Server (run/server) | `cmd/micro/server/server.go` |
| Roadmap | `internal/docs/ROADMAP_2026.md` |
| Status | `internal/docs/CURRENT_STATUS_SUMMARY.md` |
| Changelog | `CHANGELOG.md` |
| Docs Site | `internal/website/docs/` |
## Roadmap & Status Documents
- **[ROADMAP.md](ROADMAP.md)** - General framework roadmap
- **[internal/docs/ROADMAP_2026.md](internal/docs/ROADMAP_2026.md)** - AI-native era roadmap with business model
- **[internal/docs/CURRENT_STATUS_SUMMARY.md](internal/docs/CURRENT_STATUS_SUMMARY.md)** - Quick status overview
- **[internal/docs/PROJECT_STATUS_2026.md](internal/docs/PROJECT_STATUS_2026.md)** - Detailed technical status
- **[internal/docs/IMPLEMENTATION_SUMMARY.md](internal/docs/IMPLEMENTATION_SUMMARY.md)** - Implementation notes
- **[CHANGELOG.md](CHANGELOG.md)** - What changed and when
## Contributing
See [CONTRIBUTING.md](CONTRIBUTING.md) for full guidelines. Key points:
- Open an issue before large changes
- Include tests for new features
- Run `make test` and `make lint` before submitting
- Follow commit message format: `type: description` (e.g., `feat: add WebSocket transport`)
================================================
FILE: CONTRIBUTING.md
================================================
# Contributing to Go Micro
Thank you for your interest in contributing to Go Micro! This document provides guidelines and instructions for contributing.
## Code of Conduct
Be respectful, inclusive, and collaborative. We're all here to build great software together.
## Getting Started
1. Fork the repository
2. Clone your fork: `git clone https://github.com/YOUR_USERNAME/go-micro.git`
3. Add upstream remote: `git remote add upstream https://github.com/micro/go-micro.git`
4. Create a feature branch: `git checkout -b feature/my-feature`
## Development Setup
```bash
# Install dependencies
go mod download
# Install development tools
make install-tools
# Run tests
make test
# Run tests with race detector and coverage
make test-coverage
# Run linter
make lint
# Format code
make fmt
```
See `make help` for all available commands.
## Making Changes
### Code Guidelines
- Follow standard Go conventions (use `gofmt`, `golint`)
- Write clear, descriptive commit messages
- Add tests for new functionality
- Update documentation for API changes
- Keep PRs focused - one feature/fix per PR
### Commit Messages
Use conventional commits format:
```
type(scope): subject
body
footer
```
Types:
- `feat`: New feature
- `fix`: Bug fix
- `docs`: Documentation changes
- `test`: Test additions/changes
- `refactor`: Code refactoring
- `perf`: Performance improvements
- `chore`: Maintenance tasks
Examples:
```
feat(registry): add kubernetes registry plugin
fix(broker): resolve nats connection leak
docs(examples): add streaming example
```
### Testing
- Write unit tests for all new code
- Ensure existing tests pass
- Add integration tests for plugin implementations
- Test with multiple Go versions (1.20+)
```bash
# Run specific package tests
go test ./registry/...
# Run with verbose output
go test -v ./...
# Run specific test
go test -run TestMyFunction ./pkg/...
# Optional: Use richgo for colored output
go install github.com/kyoh86/richgo@latest
richgo test -v ./...
```
### Documentation
- Update relevant markdown files in `internal/website/docs/`
- Add examples to `internal/website/docs/examples/` for new features
- Update README.md for major features
- Add godoc comments for exported functions/types
## Pull Request Process
1. **Update your branch**
```bash
git fetch upstream
git rebase upstream/master
```
2. **Run tests and linting**
```bash
go test ./...
golangci-lint run
```
3. **Push to your fork**
```bash
git push origin feature/my-feature
```
4. **Create Pull Request**
- Use a descriptive title
- Reference any related issues
- Describe what changed and why
- Add screenshots for UI changes
- Mark as draft if work in progress
5. **PR Review**
- Respond to feedback promptly
- Make requested changes
- Re-request review after updates
### PR Checklist
- [ ] Tests pass locally
- [ ] Code follows Go conventions
- [ ] Documentation updated
- [ ] Commit messages are clear
- [ ] Branch is up to date with master
- [ ] No merge conflicts
## Adding Plugins
New plugins should:
1. Live in the appropriate interface directory (e.g., `registry/myplugin/`)
2. Implement the interface completely
3. Include comprehensive tests
4. Provide usage examples
5. Document configuration options (env vars, options)
6. Add to plugin documentation
Example structure:
```
registry/myplugin/
├── myplugin.go # Main implementation
├── myplugin_test.go # Tests
├── options.go # Plugin-specific options
└── README.md # Usage and configuration
```
## Reporting Issues
Before creating an issue:
1. Search existing issues
2. Check documentation
3. Try the latest version
When reporting bugs:
- Use the bug report template
- Include minimal reproduction code
- Specify versions (Go, Go Micro, plugins)
- Provide relevant logs
## Documentation Contributions
Documentation improvements are always welcome!
- Fix typos and grammar
- Improve clarity
- Add missing examples
- Update outdated information
Documentation lives in `internal/website/docs/`. Preview locally with Jekyll:
```bash
cd internal/website
bundle install
bundle exec jekyll serve --livereload
```
## Community
- GitHub Issues: Bug reports and feature requests
- GitHub Discussions: Questions, ideas, and community chat
- Sponsorship: [GitHub Sponsors](https://github.com/sponsors/micro)
## Release Process
Maintainers handle releases:
1. Update CHANGELOG.md
2. Tag release: `git tag -a v5.x.x -m "Release v5.x.x"`
3. Push tag: `git push origin v5.x.x`
4. GitHub Actions creates release
## Questions?
- Check [documentation](internal/website/docs/)
- Browse [examples](internal/website/docs/examples/)
- Open a [question issue](.github/ISSUE_TEMPLATE/question.md)
Thank you for contributing to Go Micro! 🎉
================================================
FILE: Dockerfile
================================================
FROM alpine:latest
ARG TARGETPLATFORM
ENV USER=micro
ENV GROUPNAME=$USER
ARG UID=1001
ARG GID=1001
RUN addgroup --gid "$GID" "$GROUPNAME" \
&& adduser \
--disabled-password \
--gecos "" \
--home "/micro" \
--ingroup "$GROUPNAME" \
--no-create-home \
--uid "$UID" "$USER"
ENV PATH=/usr/local/go/bin:$PATH
RUN apk --no-cache add git make curl
COPY --from=golang:1.26.0-alpine /usr/local/go /usr/local/go
COPY $TARGETPLATFORM/micro /usr/local/go/bin/
COPY $TARGETPLATFORM/protoc-gen-micro /usr/local/go/bin/
WORKDIR /micro
EXPOSE 8080
ENTRYPOINT ["/usr/local/go/bin/micro"]
CMD ["server"]
================================================
FILE: LICENSE
================================================
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright [yyyy] [name of copyright owner]
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.
================================================
FILE: Makefile
================================================
NAME = micro
GIT_COMMIT = $(shell git rev-parse --short HEAD)
GIT_TAG = $(shell git describe --abbrev=0 --tags --always --match "v*")
GIT_IMPORT = go-micro.dev/v5/cmd/micro
BUILD_DATE = $(shell date +%s)
LDFLAGS = -X $(GIT_IMPORT).BuildDate=$(BUILD_DATE) -X $(GIT_IMPORT).GitCommit=$(GIT_COMMIT) -X $(GIT_IMPORT).GitTag=$(GIT_TAG)
# GORELEASER_DOCKER_IMAGE = ghcr.io/goreleaser/goreleaser-cross:v1.25.7
GORELEASER_DOCKER_IMAGE = ghcr.io/goreleaser/goreleaser:latest
.PHONY: test test-race test-coverage lint fmt install-tools proto clean help gorelease-dry-run gorelease-dry-run-docker
# Default target
help:
@echo "Go Micro Development Tasks"
@echo ""
@echo " make test - Run tests"
@echo " make test-race - Run tests with race detector"
@echo " make test-coverage - Run tests with coverage"
@echo " make lint - Run linter"
@echo " make fmt - Format code"
@echo " make install-tools - Install development tools"
@echo " make proto - Generate protobuf code"
@echo " make clean - Clean build artifacts"
$(NAME):
CGO_ENABLED=0 go build -ldflags "-s -w ${LDFLAGS}" -o $(NAME) cmd/micro/main.go
# Run tests
test:
go test -v ./...
# Run tests with race detector
test-race:
go test -v -race ./...
# Run tests with coverage
test-coverage:
go test -v -race -coverprofile=coverage.out -covermode=atomic ./...
go tool cover -html=coverage.out -o coverage.html
@echo "Coverage report: coverage.html"
# Run linter
lint:
golangci-lint run
# Format code
fmt:
gofmt -s -w .
goimports -w .
# Install development tools
install-tools:
@echo "Installing development tools..."
go install github.com/golangci/golangci-lint/cmd/golangci-lint@latest
go install golang.org/x/tools/cmd/goimports@latest
go install github.com/kyoh86/richgo@latest
go install go-micro.dev/v5/cmd/protoc-gen-micro@latest
@echo "Tools installed successfully"
# Generate protobuf code
proto:
@echo "Generating protobuf code..."
find . -name "*.proto" -not -path "./vendor/*" -exec protoc --proto_path=. --micro_out=. --go_out=. {} \;
# Clean build artifacts
clean:
rm -f coverage.out coverage.html
find . -name "*.test" -type f -delete
go clean -cache -testcache
# Try binary release
gorelease-dry-run:
docker run \
--rm \
-e CGO_ENABLED=0 \
-v $(CURDIR):/$(NAME) \
-v /var/run/docker.sock:/var/run/docker.sock \
-w /$(NAME) \
$(GORELEASER_DOCKER_IMAGE) \
--clean --verbose --skip=publish,validate --snapshot
================================================
FILE: README.md
================================================
# Go Micro [](https://pkg.go.dev/go-micro.dev/v5?tab=doc) [](https://goreportcard.com/report/github.com/go-micro/go-micro)
Go Micro is a framework for distributed systems development.
**[📖 Documentation](https://go-micro.dev/docs/)** | [Sponsored by Anthropic](https://go-micro.dev/blog/3)
## Overview
Go Micro provides the core requirements for distributed systems development including RPC and Event driven communication.
The Go Micro philosophy is sane defaults with a pluggable architecture. We provide defaults to get you started quickly
but everything can be easily swapped out.
## Features
Go Micro abstracts away the details of distributed systems. Here are the main features.
- **Authentication** - Auth is built in as a first class citizen. Authentication and authorization enable secure
zero trust networking by providing every service an identity and certificates. This additionally includes rule
based access control.
- **Dynamic Config** - Load and hot reload dynamic config from anywhere. The config interface provides a way to load application
level config from any source such as env vars, file, etcd. You can merge the sources and even define fallbacks.
- **Data Storage** - A simple data store interface to read, write and delete records. It includes support for many storage backends
in the plugins repo. State and persistence becomes a core requirement beyond prototyping and Micro looks to build that into the framework.
- **Data Model** - A typed data model layer with CRUD operations, queries, and multiple backends (memory, SQLite, Postgres). Define Go
structs with tags and get type-safe Create/Read/Update/Delete/List/Count operations. Accessible via `service.Model()` alongside
`service.Client()` and `service.Server()` for a complete service experience: call services, handle requests, save and query data.
- **Service Discovery** - Automatic service registration and name resolution. Service discovery is at the core of micro service
development. When service A needs to speak to service B it needs the location of that service. The default discovery mechanism is
multicast DNS (mdns), a zeroconf system.
- **Load Balancing** - Client side load balancing built on service discovery. Once we have the addresses of any number of instances
of a service we now need a way to decide which node to route to. We use random hashed load balancing to provide even distribution
across the services and retry a different node if there's a problem.
- **Message Encoding** - Dynamic message encoding based on content-type. The client and server will use codecs along with content-type
to seamlessly encode and decode Go types for you. Any variety of messages could be encoded and sent from different clients. The client
and server handle this by default. This includes protobuf and json by default.
- **RPC Client/Server** - RPC based request/response with support for bidirectional streaming. We provide an abstraction for synchronous
communication. A request made to a service will be automatically resolved, load balanced, dialled and streamed.
- **Async Messaging** - PubSub is built in as a first class citizen for asynchronous communication and event driven architectures.
Event notifications are a core pattern in micro service development. The default messaging system is a HTTP event message broker.
- **MCP Integration** - An MCP gateway you can integrate as a library, server or CLI command which automatically exposes services
as tools for agents or other AI applications. Every service/endpoint get's converted into a callable tool.
- **Multi-Service Binaries** - Run multiple services in a single process with isolated state per service. Start as a modular monolith,
split into separate deployments when you need independent scaling. Each service gets its own server, client, and store while sharing
the registry and broker for inter-service communication.
- **Pluggable Interfaces** - Go Micro makes use of Go interfaces for each distributed system abstraction. Because of this these interfaces
are pluggable and allows Go Micro to be runtime agnostic. You can plugin any underlying technology.
## Getting Started
To make use of Go Micro
```bash
go get go-micro.dev/v5@v5.16.0
```
Create a service and register a handler
```go
package main
import (
"go-micro.dev/v5"
)
type Request struct {
Name string `json:"name"`
}
type Response struct {
Message string `json:"message"`
}
type Say struct{}
func (h *Say) Hello(ctx context.Context, req *Request, rsp *Response) error {
rsp.Message = "Hello " + req.Name
return nil
}
func main() {
// create the service
service := micro.New("helloworld")
// register handler
service.Handle(new(Say))
// run the service
service.Run()
}
```
Set a fixed address
```go
service := micro.New("helloworld", micro.Address(":8080"))
```
Call it via curl
```bash
curl -XPOST \
-H 'Content-Type: application/json' \
-H 'Micro-Endpoint: Say.Hello' \
-d '{"name": "alice"}' \
http://localhost:8080
```
## MCP & AI Agents
Go Micro is designed for an **agent-first** workflow. Every service you build automatically becomes a tool that AI agents can discover and use via the [Model Context Protocol (MCP)](https://modelcontextprotocol.io/).
- **[🤖 Agent Playground](https://go-micro.dev/docs/mcp.html)** — Chat with your services through an interactive AI agent at `/agent`
- **[🔧 MCP Tools Registry](https://go-micro.dev/docs/mcp.html)** — Browse all services exposed as AI-callable tools at `/api/mcp/tools`
- **[📖 MCP Documentation](https://go-micro.dev/docs/mcp.html)** — Full guide to MCP integration, auth, and scopes
### Services as Tools
Write a normal Go Micro service and it's instantly available as an MCP tool:
```go
// SayHello greets a person by name.
// @example {"name": "Alice"}
func (g *GreeterService) SayHello(ctx context.Context, req *HelloRequest, rsp *HelloResponse) error {
rsp.Message = "Hello " + req.Name
return nil
}
```
Run with `micro run` and the agent playground and MCP tools registry are ready:
```bash
micro run
# Agent Playground: http://localhost:8080/agent
# MCP Tools: http://localhost:8080/api/mcp/tools
```
Use `micro mcp serve` for local AI tools like Claude Code, or connect any MCP-compatible agent to the HTTP endpoint.
See the [MCP guide](https://go-micro.dev/docs/mcp.html) for authentication, scopes, and advanced usage.
## Multi-Service Binaries
Run multiple services in a single binary — start as a modular monolith, split into separate deployments later when you actually need to.
```go
users := micro.New("users", micro.Address(":9001"))
orders := micro.New("orders", micro.Address(":9002"))
users.Handle(new(Users))
orders.Handle(new(Orders))
// Run all services together with shared lifecycle
g := micro.NewGroup(users, orders)
g.Run()
```
Each service gets its own server, client, store, and cache while sharing the registry, broker, and transport — so they can discover and call each other within the same process.
See the [multi-service example](examples/multi-service/) for a working demo.
## Data Model
Go Micro includes a typed data model layer for persistence. Define a struct, tag a key field, and get type-safe CRUD and query operations backed by memory, SQLite, or Postgres.
```go
import (
"go-micro.dev/v5/model"
"go-micro.dev/v5/model/sqlite"
)
// Define your data type
type User struct {
ID string `json:"id" model:"key"`
Name string `json:"name"`
Email string `json:"email" model:"index"`
Age int `json:"age"`
}
```
Register your types and use the model:
```go
service := micro.New("users")
// Register and use the service's model backend
db := service.Model()
db.Register(&User{})
// CRUD operations
db.Create(ctx, &User{ID: "1", Name: "Alice", Email: "alice@example.com", Age: 30})
user := &User{}
db.Read(ctx, "1", user)
user.Name = "Alice Smith"
db.Update(ctx, user)
db.Delete(ctx, "1", &User{})
```
Query with filters, ordering, and pagination:
```go
var results []*User
// Find users by field
db.List(ctx, &results, model.Where("email", "alice@example.com"))
// Complex queries
db.List(ctx, &results,
model.WhereOp("age", ">=", 18),
model.OrderDesc("name"),
model.Limit(10),
model.Offset(20),
)
count, _ := users.Count(ctx, model.Where("age", 30))
```
Swap backends with an option:
```go
// Development: in-memory (default)
service := micro.New("users")
// Production: SQLite or Postgres
db, _ := sqlite.New(model.WithDSN("file:app.db"))
service := micro.New("users", micro.Model(db))
```
Every service gets `Client()`, `Server()`, and `Model()` — call services, handle requests, and save data all from the same interface.
## Examples
Check out [/examples](examples/) for runnable code:
- [hello-world](examples/hello-world/) - Basic RPC service
- [web-service](examples/web-service/) - HTTP REST API
- [multi-service](examples/multi-service/) - Multiple services in one binary
- [mcp](examples/mcp/) - MCP integration with AI agents
See [all examples](examples/README.md) for more.
## Protobuf
Install the code generator and see usage in the docs:
```bash
go install go-micro.dev/v5/cmd/protoc-gen-micro@v5.16.0
```
> **Note:** Use a specific version instead of `@latest` to avoid module path conflicts. See [releases](https://github.com/micro/go-micro/releases) for the latest version.
Docs: [`internal/website/docs/getting-started.md`](internal/website/docs/getting-started.md)
## Command Line
Install the CLI:
```
go install go-micro.dev/v5/cmd/micro@v5.16.0
```
> **Note:** Use a specific version instead of `@latest` to avoid module path conflicts. See [releases](https://github.com/micro/go-micro/releases) for the latest version.
### Quick Start
```bash
micro new helloworld # Create a new service
cd helloworld
micro run # Run with API gateway and hot reload
```
Then open http://localhost:8080 to see your service and call it from the browser.
### Development Workflow
| Stage | Command | Purpose |
|-------|---------|---------|
| **Develop** | `micro run` | Local dev with hot reload and API gateway |
| **Build** | `micro build` | Compile production binaries |
| **Deploy** | `micro deploy` | Push to a remote Linux server via SSH + systemd |
| **Dashboard** | `micro server` | Optional production web UI with JWT auth |
### micro run
`micro run` starts your services with:
- **Web Dashboard** - Browse and call services at `/`
- **Agent Playground** - AI chat with MCP tools at `/agent`
- **API Explorer** - Browse endpoints and schemas at `/api`
- **API Gateway** - HTTP to RPC proxy at `/api/{service}/{method}` (no auth in dev mode)
- **MCP Tools** - Services as AI tools at `/api/mcp/tools`
- **Health Checks** - Aggregated health at `/health`
- **Hot Reload** - Auto-rebuild on file changes
> **Note:** `micro run` and `micro server` use a unified gateway architecture. See [Gateway Architecture](cmd/micro/README.md#gateway-architecture) for details.
```bash
micro run # Gateway on :8080
micro run --address :3000 # Custom gateway port
micro run --no-gateway # Services only
micro run --env production # Use production environment
```
### Configuration
For multi-service projects, create a `micro.mu` file:
```
service users
path ./users
port 8081
service posts
path ./posts
port 8082
depends users
env development
DATABASE_URL sqlite://./dev.db
```
The gateway runs on :8080 by default, so services should use other ports.
### Deployment
Deploy to any Linux server with systemd:
```bash
# On your server (one-time setup)
curl -fsSL https://go-micro.dev/install.sh | sh
sudo micro init --server
# From your laptop
micro deploy user@your-server
```
The deploy command:
1. Builds binaries for Linux
2. Copies via SSH to the server
3. Sets up systemd services
4. Verifies services are healthy
Optionally run `micro server` on the deployed machine for a production web dashboard with JWT auth, user management, and API explorer.
Manage deployed services:
```bash
micro status --remote user@server # Check status
micro logs --remote user@server # View logs
micro logs myservice --remote user@server -f # Follow specific service
```
No Docker required. No Kubernetes. Just systemd.
See [internal/website/docs/deployment.md](internal/website/docs/deployment.md) for full deployment guide.
See [cmd/micro/README.md](cmd/micro/README.md) for full CLI documentation.
Docs: [`internal/website/docs`](internal/website/docs)
Package reference: https://pkg.go.dev/go-micro.dev/v5
**User Guides:**
- [Getting Started](internal/website/docs/getting-started.md)
- [Data Model](internal/website/docs/model.md)
- [MCP & AI Agents](internal/website/docs/mcp.md)
- [Plugins Overview](internal/website/docs/plugins.md)
- [Learn by Example](internal/website/docs/examples/index.md)
- [Deployment Guide](internal/website/docs/deployment.md)
**Architecture & Performance:**
- [Performance Considerations](internal/website/docs/performance.md)
- [Reflection Usage & Philosophy](internal/website/docs/REFLECTION-EVALUATION-SUMMARY.md)
**Security:**
- [TLS Security Migration](internal/website/docs/TLS_SECURITY_UPDATE.md)
- [Security Migration Guide](internal/website/docs/SECURITY_MIGRATION.md)
## Adopters
- [Sourse](https://sourse.eu) - Work in the field of earth observation, including embedded Kubernetes running onboard aircraft, and we’ve built a mission management SaaS platform using Go Micro.
================================================
FILE: ROADMAP.md
================================================
# Go Micro Roadmap
This roadmap outlines the planned features and improvements for Go Micro. Community feedback and contributions are welcome!
> **See [internal/docs/ROADMAP_2026.md](internal/docs/ROADMAP_2026.md) for the AI-Native Era roadmap** focused on MCP integration, agent-first development, and business sustainability. This document covers general framework improvements.
## Current Focus (Q1 2026) - COMPLETE
### Documentation & Developer Experience
- [x] Modernize documentation structure
- [x] Add learn-by-example guides
- [x] Update issue templates
- [x] MCP integration documentation
- [x] Agent playground and MCP tools registry
- [ ] Create video tutorials
- [ ] Interactive documentation site
- [ ] Plugin discovery dashboard
### AI & Model Integration
- [x] AI package with provider abstraction (`ai.Model` interface)
- [x] Anthropic Claude provider (`ai/anthropic`)
- [x] OpenAI GPT provider (`ai/openai`)
- [x] Tool execution with auto-calling support
- [x] Streaming support via `ai.Stream`
### Observability
- [ ] OpenTelemetry native support
- [ ] Auto-instrumentation for handlers
- [ ] Metrics export standardization
- [ ] Distributed tracing examples
- [ ] Integration with popular observability platforms
### Developer Tools
- [x] `micro run` with hot reload and unified gateway
- [x] `micro deploy` with SSH + systemd deployment
- [x] `micro mcp` command suite (serve, list, test, docs, export)
- [ ] `micro dev` with enhanced hot reload
- [ ] Service templates (`micro new --template`)
- [ ] Better error messages with suggestions
- [ ] Debug tooling improvements
- [ ] VS Code extension for Go Micro
## Q2 2026
### Production Readiness
- [x] Health check standardization
- [x] Graceful shutdown improvements
- [ ] Resource cleanup best practices
- [ ] Load testing framework integration
- [ ] Performance benchmarking suite
### Cloud Native
- [ ] Kubernetes operator
- [ ] Helm charts for common setups
- [ ] Service mesh integration guides (Istio, Linkerd)
- [ ] Cloud provider quickstarts (AWS, GCP, Azure)
- [ ] Multi-cluster patterns
### Security
- [x] Bearer token authentication for MCP
- [x] Per-tool scope enforcement
- [x] Audit logging
- [x] Rate limiting
- [ ] mTLS by default option
- [ ] Secret management integration (Vault, AWS Secrets Manager)
- [ ] RBAC improvements
- [ ] Security audit and hardening
- [ ] CVE scanning and response process
## Q3 2026
### Plugin Ecosystem
- [ ] Plugin marketplace/registry
- [ ] Plugin quality standards
- [ ] Community plugin contributions
- [ ] Plugin compatibility matrix
- [ ] Auto-discovery of available plugins
### Streaming & Async
- [ ] Improved streaming support
- [x] Server-sent events (SSE) support (via MCP gateway)
- [ ] WebSocket plugin
- [ ] Event sourcing patterns
- [ ] CQRS examples
### Testing
- [ ] Mock generation tooling
- [ ] Integration test helpers
- [ ] Contract testing support
- [ ] Chaos engineering examples
- [ ] E2E testing framework
## Q4 2026
### Performance
- [ ] Connection pooling optimizations
- [ ] Zero-allocation paths
- [ ] gRPC performance improvements
- [ ] Caching strategies guide
- [ ] Performance profiling tools
### Developer Productivity
- [ ] Code generation improvements
- [ ] Better IDE support
- [ ] Debugging tools
- [ ] Migration automation tools
- [ ] Upgrade helpers
### Community
- [ ] Regular blog posts and case studies
- [ ] Community spotlight program
- [ ] Contribution rewards
- [ ] Monthly community calls
- [ ] Conference presence
## Long-term Vision
### Core Framework
- Maintain backward compatibility (Go Micro v5+)
- Progressive disclosure of complexity
- Best-in-class developer experience
- Production-grade reliability
- Comprehensive plugin ecosystem
### Ecosystem Goals
- 100+ production deployments documented
- 50+ community plugins
- Active contributor community
- Regular releases (monthly patches, quarterly features)
- Comprehensive benchmarks vs alternatives
### Differentiation
- **Batteries included, fully swappable** - Start simple, scale complex
- **Zero-config local development** - No infrastructure required to start
- **AI-native by default** - Every service is an MCP tool automatically
- **Plugin ecosystem in-repo** - No version compatibility hell
- **Progressive complexity** - Learn as you grow
- **Cloud-native first** - Built for Kubernetes and containers
## Contributing
We welcome contributions to any roadmap items! See [CONTRIBUTING.md](CONTRIBUTING.md) for guidelines.
### High Priority Areas
1. Documentation improvements (guides, tutorials)
2. Multi-protocol MCP support (WebSocket, gRPC)
3. Agent SDK integrations (LlamaIndex, AutoGPT)
4. OpenTelemetry integration
5. Kubernetes operator and Helm charts
### How to Contribute
- Pick an item from the roadmap
- Open an issue to discuss approach
- Submit a PR with implementation
- Help review others' contributions
## Feedback
Have suggestions for the roadmap?
- Open a [feature request](.github/ISSUE_TEMPLATE/feature_request.md)
- Start a discussion in GitHub Discussions
- Comment on existing roadmap issues
## Version Compatibility
We follow semantic versioning:
- Major versions (v5 → v6): Breaking changes
- Minor versions (v5.3 → v5.4): New features, backward compatible
- Patch versions (v5.3.0 → v5.3.1): Bug fixes, no API changes
## Support Timeline
- v5: Active development (current)
- v4: Security fixes only (until v6 release)
- v3: End of life
---
Last updated: March 2026
This roadmap is subject to change based on community needs and priorities.
================================================
FILE: SECURITY.md
================================================
# Security Policy
## Supported Versions
We actively support the following versions of go-micro:
| Version | Supported |
| ------- | ------------------ |
| 5.x | :white_check_mark: |
| 4.x | :x: |
| 3.x | :x: |
| < 3.0 | :x: |
## Reporting a Vulnerability
**Please do not report security vulnerabilities through public GitHub issues.**
### How to Report
Send security vulnerability reports to: **security@go-micro.dev**
Or use GitHub's private security advisory feature:
https://github.com/micro/go-micro/security/advisories/new
### What to Include
Please include as much of the following information as possible:
- Type of vulnerability (e.g., RCE, XSS, SQL injection, etc.)
- Full paths of source file(s) related to the vulnerability
- Location of the affected source code (tag/branch/commit or direct URL)
- Step-by-step instructions to reproduce the issue
- Proof-of-concept or exploit code (if possible)
- Impact of the issue, including how an attacker might exploit it
### Response Timeline
- **Acknowledgment**: Within 48 hours
- **Initial Assessment**: Within 5 business days
- **Fix Timeline**: Depends on severity
- Critical: 7 days
- High: 14 days
- Medium: 30 days
- Low: Next release cycle
### Disclosure Policy
- We follow **coordinated disclosure**
- We'll work with you to understand and fix the issue
- We'll credit you in the security advisory (unless you prefer to remain anonymous)
- Please give us reasonable time to fix before public disclosure
- We'll publish a security advisory on GitHub when the fix is released
## Security Best Practices
When using go-micro in production:
### TLS/Transport Security
```go
import "go-micro.dev/v5/transport"
// Enable TLS verification (recommended)
os.Setenv("MICRO_TLS_SECURE", "true")
// Or use SecureConfig explicitly
tlsConfig := transport.SecureConfig()
```
See [TLS Security Update](internal/website/docs/TLS_SECURITY_UPDATE.md) for details.
### Authentication
```go
import "go-micro.dev/v5/auth"
// Use JWT authentication
service := micro.NewService(
micro.Auth(auth.NewAuth()),
)
```
### Input Validation
Always validate and sanitize inputs in your handlers:
```go
func (h *Handler) Create(ctx context.Context, req *Request, rsp *Response) error {
// Validate input
if req.Name == "" {
return errors.BadRequest("handler.create", "name is required")
}
// Sanitize and process
// ...
}
```
### Rate Limiting
Implement rate limiting for public-facing services:
```go
import "go-micro.dev/v5/client"
// Client-side rate limiting
client.NewClient(
client.RequestTimeout(time.Second * 5),
client.Retries(3),
)
```
### Secrets Management
Never commit secrets to version control:
```go
// Good: Use environment variables
apiKey := os.Getenv("API_KEY")
// Better: Use a secrets manager
import "github.com/hashicorp/vault/api"
```
### Dependency Security
Regularly update dependencies:
```bash
# Check for vulnerabilities
go list -json -m all | nancy sleuth
# Update dependencies
go get -u ./...
go mod tidy
```
## Known Security Considerations
### Reflection Usage
go-micro uses reflection for automatic handler registration. While this is a deliberate design choice for developer productivity, be aware:
- Type safety is enforced at runtime, not compile time
- Malformed requests won't crash services (errors are returned)
- See [Performance Considerations](internal/website/docs/performance.md)
### TLS Certificate Verification
**Default behavior in v5**: TLS certificate verification is **disabled** for backward compatibility.
**Production recommendation**: Enable secure mode:
```bash
export MICRO_TLS_SECURE=true
```
This will be the default in v6.
## Security Updates
Security updates are published as:
- GitHub Security Advisories
- Release notes with `[SECURITY]` prefix
- CVE entries for critical issues
Subscribe to releases: https://github.com/micro/go-micro/releases
## Bug Bounty
We currently do not offer a bug bounty program, but we greatly appreciate responsible disclosure and will publicly credit researchers who report valid security issues.
## Questions?
For security questions that are not vulnerabilities, please:
- Open a discussion: https://github.com/micro/go-micro/discussions
- Join Discord: https://discord.gg/jwTYuUVAGh
- Email: support@go-micro.dev
================================================
FILE: ai/README.md
================================================
# AI Package
The `ai` package provides a simple, high-level interface for AI model providers like Anthropic Claude and OpenAI GPT.
## Interface
The Model interface follows the same patterns as other go-micro packages (Registry, Client, Broker):
```go
type Model interface {
Init(...Option) error
Options() Options
Generate(ctx context.Context, req *Request, opts ...GenerateOption) (*Response, error)
Stream(ctx context.Context, req *Request, opts ...GenerateOption) (Stream, error)
String() string
}
```
## Quick Start
```go
import (
"context"
"go-micro.dev/v5/ai"
_ "go-micro.dev/v5/ai/anthropic"
_ "go-micro.dev/v5/ai/openai"
)
// Create a model
m := ai.New("openai",
ai.WithAPIKey("your-api-key"),
ai.WithModel("gpt-4o"),
)
// Generate a response
req := &ai.Request{
Prompt: "What is Go?",
SystemPrompt: "You are a helpful programming assistant",
}
resp, err := m.Generate(context.Background(), req)
if err != nil {
log.Fatal(err)
}
fmt.Println(resp.Reply)
```
## Options
Configure the model using functional options:
```go
m := ai.New("anthropic",
ai.WithAPIKey("your-key"), // Required
ai.WithModel("claude-sonnet-4-20250514"), // Optional, uses provider default
ai.WithBaseURL("https://api.anthropic.com"), // Optional, uses provider default
)
```
You can also update options after creation:
```go
m.Init(
ai.WithModel("gpt-4o-mini"),
ai.WithAPIKey("new-key"),
)
```
## Using Tools
The model can automatically execute tool calls when provided with a tool handler:
```go
// Define a tool handler
toolHandler := func(name string, input map[string]any) (result any, content string) {
// Execute the tool and return results
switch name {
case "get_weather":
return map[string]string{"temp": "72F"}, `{"temp": "72F"}`
default:
return nil, `{"error": "unknown tool"}`
}
}
// Create model with tool handler
m := ai.New("openai",
ai.WithAPIKey("your-key"),
ai.WithToolHandler(toolHandler),
)
// Provide tools in the request
req := &ai.Request{
Prompt: "What's the weather?",
SystemPrompt: "You are a helpful assistant",
Tools: []ai.Tool{
{
Name: "get_weather",
Description: "Get current weather",
Properties: map[string]any{
"location": map[string]any{
"type": "string",
"description": "City name",
},
},
},
},
}
// Generate will automatically call tools and return final answer
resp, err := m.Generate(context.Background(), req)
fmt.Println(resp.Answer) // Final answer after tool execution
```
## Response Structure
```go
type Response struct {
Reply string // Initial reply from model
ToolCalls []ToolCall // Tools the model wants to call
Answer string // Final answer (after tool execution if handler provided)
}
```
- `Reply`: The model's first response
- `ToolCalls`: List of tools the model requested (if any)
- `Answer`: The final answer after tools are executed (only set if ToolHandler is provided)
## Supported Providers
### Anthropic Claude
```go
m := ai.New("anthropic",
ai.WithAPIKey("sk-ant-..."),
ai.WithModel("claude-sonnet-4-20250514"), // default
)
```
Default model: `claude-sonnet-4-20250514`
Default base URL: `https://api.anthropic.com`
### OpenAI GPT
```go
m := ai.New("openai",
ai.WithAPIKey("sk-..."),
ai.WithModel("gpt-4o"), // default
)
```
Default model: `gpt-4o`
Default base URL: `https://api.openai.com`
## Auto-Detection
Use `AutoDetectProvider()` to detect the provider from a base URL:
```go
provider := ai.AutoDetectProvider("https://api.anthropic.com")
// Returns "anthropic"
m := ai.New(provider, ai.WithAPIKey("..."))
```
## Adding a New Provider
1. Create a new package under `ai/`:
```go
package myprovider
import "go-micro.dev/v5/ai"
func init() {
ai.Register("myprovider", func(opts ...ai.Option) ai.Model {
return NewProvider(opts...)
})
}
type Provider struct {
opts ai.Options
}
func NewProvider(opts ...ai.Option) *Provider {
options := ai.NewOptions(opts...)
// Set defaults
if options.Model == "" {
options.Model = "my-default-model"
}
if options.BaseURL == "" {
options.BaseURL = "https://api.myprovider.com"
}
return &Provider{opts: options}
}
func (p *Provider) Init(opts ...ai.Option) error {
for _, o := range opts {
o(&p.opts)
}
return nil
}
func (p *Provider) Options() ai.Options {
return p.opts
}
func (p *Provider) String() string {
return "myprovider"
}
func (p *Provider) Generate(ctx context.Context, req *ai.Request, opts ...ai.GenerateOption) (*ai.Response, error) {
// Implement your provider logic
// - Build API request
// - Make HTTP call
// - Parse response
// - Handle tools if ToolHandler is set
return &ai.Response{}, nil
}
func (p *Provider) Stream(ctx context.Context, req *ai.Request, opts ...ai.GenerateOption) (ai.Stream, error) {
return nil, fmt.Errorf("streaming not implemented")
}
```
2. Import your provider:
```go
import _ "go-micro.dev/v5/ai/myprovider"
```
## Comparison with Other Packages
The ai package follows the same patterns as other go-micro packages:
**Registry:**
```go
r := registry.NewRegistry(registry.Addrs("..."))
r.Register(service)
```
**Client:**
```go
c := client.NewClient(client.Retries(3))
c.Call(ctx, req, rsp)
```
**AI:**
```go
m := ai.New("openai", ai.WithAPIKey("..."))
m.Generate(ctx, req)
```
All use:
- `Init()` to update options
- `Options()` to get current options
- `String()` to get the implementation name
- Functional options pattern
## Testing
```bash
go test ./ai/...
```
## Examples
See the [server implementation](../cmd/micro/server/server.go) for a complete example of using the ai package with tool execution.
================================================
FILE: ai/anthropic/anthropic.go
================================================
// Package anthropic implements the Anthropic Claude model provider
package anthropic
import (
"bytes"
"context"
"encoding/json"
"fmt"
"io"
"net/http"
"strings"
"go-micro.dev/v5/ai"
)
func init() {
ai.Register("anthropic", func(opts ...ai.Option) ai.Model {
return NewProvider(opts...)
})
}
// Provider implements the ai.Model interface for Anthropic Claude
type Provider struct {
opts ai.Options
}
// NewProvider creates a new Anthropic provider
func NewProvider(opts ...ai.Option) *Provider {
options := ai.NewOptions(opts...)
// Set defaults if not provided
if options.Model == "" {
options.Model = "claude-sonnet-4-20250514"
}
if options.BaseURL == "" {
options.BaseURL = "https://api.anthropic.com"
}
return &Provider{
opts: options,
}
}
// Init initializes the provider with options
func (p *Provider) Init(opts ...ai.Option) error {
for _, o := range opts {
o(&p.opts)
}
return nil
}
// Options returns the provider options
func (p *Provider) Options() ai.Options {
return p.opts
}
// String returns the provider name
func (p *Provider) String() string {
return "anthropic"
}
// Generate generates a response from the model
func (p *Provider) Generate(ctx context.Context, req *ai.Request, opts ...ai.GenerateOption) (*ai.Response, error) {
// Build tools for Anthropic format
var anthropicTools []map[string]any
for _, t := range req.Tools {
anthropicTools = append(anthropicTools, map[string]any{
"name": t.Name,
"description": t.Description,
"input_schema": map[string]any{
"type": "object",
"properties": t.Properties,
},
})
}
// Build initial request
apiReq := map[string]any{
"model": p.opts.Model,
"max_tokens": 4096,
"system": req.SystemPrompt,
"messages": []map[string]any{
{"role": "user", "content": req.Prompt},
},
}
if len(anthropicTools) > 0 {
apiReq["tools"] = anthropicTools
}
// Make API call
resp, rawContent, err := p.callAPI(ctx, apiReq)
if err != nil {
return nil, err
}
// If no tool calls, return response
if len(resp.ToolCalls) == 0 {
return resp, nil
}
// If tool handler is provided, execute tools and get final answer
if p.opts.ToolHandler != nil {
var toolResults []ai.ToolResult
for _, tc := range resp.ToolCalls {
_, content := p.opts.ToolHandler(tc.Name, tc.Input)
toolResults = append(toolResults, ai.ToolResult{
ID: tc.ID,
Content: content,
})
}
// Build follow-up request with tool results
var toolResultBlocks []map[string]any
for _, tr := range toolResults {
toolResultBlocks = append(toolResultBlocks, map[string]any{
"type": "tool_result",
"tool_use_id": tr.ID,
"content": tr.Content,
})
}
followUpReq := map[string]any{
"model": p.opts.Model,
"max_tokens": 4096,
"system": req.SystemPrompt,
"messages": []map[string]any{
{"role": "user", "content": req.Prompt},
{"role": "assistant", "content": rawContent},
{"role": "user", "content": toolResultBlocks},
},
}
// Make follow-up API call
followUpResp, _, err := p.callAPI(ctx, followUpReq)
if err == nil && followUpResp.Reply != "" {
resp.Answer = followUpResp.Reply
}
}
return resp, nil
}
// Stream generates a streaming response (not yet implemented)
func (p *Provider) Stream(ctx context.Context, req *ai.Request, opts ...ai.GenerateOption) (ai.Stream, error) {
return nil, fmt.Errorf("streaming not yet implemented for anthropic provider")
}
// callAPI makes an HTTP request to the Anthropic API
func (p *Provider) callAPI(ctx context.Context, req map[string]any) (*ai.Response, any, error) {
// Marshal request
reqBody, err := json.Marshal(req)
if err != nil {
return nil, nil, fmt.Errorf("failed to marshal request: %w", err)
}
// Build HTTP request
apiURL := strings.TrimRight(p.opts.BaseURL, "/") + "/v1/messages"
httpReq, err := http.NewRequestWithContext(ctx, "POST", apiURL, bytes.NewReader(reqBody))
if err != nil {
return nil, nil, fmt.Errorf("failed to create request: %w", err)
}
// Set headers
httpReq.Header.Set("Content-Type", "application/json")
httpReq.Header.Set("x-api-key", p.opts.APIKey)
httpReq.Header.Set("anthropic-version", "2023-06-01")
// Make request
httpResp, err := http.DefaultClient.Do(httpReq)
if err != nil {
return nil, nil, fmt.Errorf("API request failed: %w", err)
}
defer httpResp.Body.Close()
// Read response
respBody, _ := io.ReadAll(httpResp.Body)
if httpResp.StatusCode != 200 {
return nil, nil, fmt.Errorf("API error (%s): %s", httpResp.Status, string(respBody))
}
// Parse response
var anthropicResp struct {
Content []struct {
Type string `json:"type"`
Text string `json:"text"`
ID string `json:"id"`
Name string `json:"name"`
Input json.RawMessage `json:"input"`
} `json:"content"`
StopReason string `json:"stop_reason"`
}
if err := json.Unmarshal(respBody, &anthropicResp); err != nil {
return nil, nil, fmt.Errorf("failed to parse response: %w", err)
}
response := &ai.Response{}
// Extract text reply
var replyParts []string
for _, block := range anthropicResp.Content {
if block.Type == "text" && block.Text != "" {
replyParts = append(replyParts, block.Text)
}
}
if len(replyParts) > 0 {
response.Reply = strings.Join(replyParts, "\n")
}
// Extract tool calls
for _, block := range anthropicResp.Content {
if block.Type == "tool_use" {
var input map[string]any
if err := json.Unmarshal(block.Input, &input); err != nil {
input = map[string]any{}
}
response.ToolCalls = append(response.ToolCalls, ai.ToolCall{
ID: block.ID,
Name: block.Name,
Input: input,
})
}
}
return response, anthropicResp.Content, nil
}
================================================
FILE: ai/anthropic/anthropic_test.go
================================================
package anthropic
import (
"context"
"testing"
"go-micro.dev/v5/ai"
)
func TestProvider_String(t *testing.T) {
p := NewProvider()
if p.String() != "anthropic" {
t.Errorf("Expected provider name 'anthropic', got '%s'", p.String())
}
}
func TestProvider_Init(t *testing.T) {
p := NewProvider()
err := p.Init(
ai.WithModel("test-model"),
ai.WithAPIKey("test-key"),
ai.WithBaseURL("https://test.com"),
)
if err != nil {
t.Fatalf("Init failed: %v", err)
}
opts := p.Options()
if opts.Model != "test-model" {
t.Errorf("Expected model 'test-model', got '%s'", opts.Model)
}
if opts.APIKey != "test-key" {
t.Errorf("Expected API key 'test-key', got '%s'", opts.APIKey)
}
if opts.BaseURL != "https://test.com" {
t.Errorf("Expected base URL 'https://test.com', got '%s'", opts.BaseURL)
}
}
func TestProvider_Options(t *testing.T) {
p := NewProvider(
ai.WithModel("custom-model"),
ai.WithAPIKey("my-key"),
)
opts := p.Options()
if opts.Model != "custom-model" {
t.Errorf("Expected model 'custom-model', got '%s'", opts.Model)
}
if opts.APIKey != "my-key" {
t.Errorf("Expected API key 'my-key', got '%s'", opts.APIKey)
}
}
func TestProvider_Defaults(t *testing.T) {
p := NewProvider()
opts := p.Options()
if opts.Model != "claude-sonnet-4-20250514" {
t.Errorf("Expected default model 'claude-sonnet-4-20250514', got '%s'", opts.Model)
}
if opts.BaseURL != "https://api.anthropic.com" {
t.Errorf("Expected default base URL 'https://api.anthropic.com', got '%s'", opts.BaseURL)
}
}
func TestProvider_Generate_NoAPIKey(t *testing.T) {
p := NewProvider()
req := &ai.Request{
Prompt: "Hello",
SystemPrompt: "You are helpful",
}
_, err := p.Generate(context.Background(), req)
if err == nil {
t.Error("Expected error when API key is missing, got nil")
}
}
func TestProvider_Stream_NotImplemented(t *testing.T) {
p := NewProvider()
req := &ai.Request{
Prompt: "Hello",
}
_, err := p.Stream(context.Background(), req)
if err == nil {
t.Error("Expected error for unimplemented streaming, got nil")
}
}
================================================
FILE: ai/model.go
================================================
// Package ai provides abstraction for AI model providers
package ai
import (
"context"
"strings"
)
// Model provides an interface for interacting with AI model providers
type Model interface {
// Init initializes the model with options
Init(...Option) error
// Options returns the model options
Options() Options
// Generate generates a response from the model
Generate(ctx context.Context, req *Request, opts ...GenerateOption) (*Response, error)
// Stream generates a streaming response (for future implementation)
Stream(ctx context.Context, req *Request, opts ...GenerateOption) (Stream, error)
// String returns the name of the provider
String() string
}
// Tool represents a tool/function that can be called by the model
type Tool struct {
Name string // LLM-safe name (e.g., "greeter_Greeter_Hello")
OriginalName string // Original name (e.g., "greeter.Greeter.Hello")
Description string
Properties map[string]any // JSON schema for tool parameters
}
// Request represents a request to generate content from a model
type Request struct {
// Prompt is the user's message/prompt
Prompt string
// SystemPrompt is the system instruction for the model
SystemPrompt string
// Tools available for the model to use
Tools []Tool
// Messages for continuing a conversation (optional)
Messages []Message
}
// Message represents a conversation message
type Message struct {
Role string // "user", "assistant", "system", "tool"
Content any // Can be string or structured content
}
// Response represents the response from a model
type Response struct {
// Reply is the text response from the model
Reply string
// ToolCalls are tool calls requested by the model
ToolCalls []ToolCall
// Answer is the final answer after tool execution (if tools were used)
Answer string
}
// ToolCall represents a request to call a tool
type ToolCall struct {
ID string // Tool call ID (for correlation)
Name string // Tool name
Input map[string]any // Tool input arguments
}
// ToolResult represents the result of a tool execution
type ToolResult struct {
ID string // Tool call ID (for correlation)
Content string // Tool execution result (JSON string)
}
// Stream is the interface for streaming responses (future implementation)
type Stream interface {
// Recv receives the next chunk of the response
Recv() (*Response, error)
// Close closes the stream
Close() error
}
// ToolHandler is a function that handles tool calls
type ToolHandler func(name string, input map[string]any) (result any, content string)
// NewFunc creates a new Model instance
type NewFunc func(...Option) Model
var providers = make(map[string]NewFunc)
// Register registers a model provider
func Register(name string, fn NewFunc) {
providers[name] = fn
}
// New creates a new Model instance based on the provider name
func New(provider string, opts ...Option) Model {
if fn, ok := providers[provider]; ok {
return fn(opts...)
}
// Default to first registered provider
if len(providers) > 0 {
for _, fn := range providers {
return fn(opts...)
}
}
return nil
}
// AutoDetectProvider attempts to detect the provider from the base URL
func AutoDetectProvider(baseURL string) string {
if baseURL == "" {
return "openai"
}
// Simple detection based on URL
if strings.Contains(baseURL, "anthropic") {
return "anthropic"
}
return "openai"
}
// DefaultModel is a default model instance
var DefaultModel Model
// Generate generates a response using the default model
func Generate(ctx context.Context, req *Request, opts ...GenerateOption) (*Response, error) {
if DefaultModel == nil {
return nil, nil
}
return DefaultModel.Generate(ctx, req, opts...)
}
================================================
FILE: ai/openai/openai.go
================================================
// Package openai implements the OpenAI model provider
package openai
import (
"bytes"
"context"
"encoding/json"
"fmt"
"io"
"net/http"
"strings"
"go-micro.dev/v5/ai"
)
func init() {
ai.Register("openai", func(opts ...ai.Option) ai.Model {
return NewProvider(opts...)
})
}
// Provider implements the ai.Model interface for OpenAI
type Provider struct {
opts ai.Options
}
// NewProvider creates a new OpenAI provider
func NewProvider(opts ...ai.Option) *Provider {
options := ai.NewOptions(opts...)
// Set defaults if not provided
if options.Model == "" {
options.Model = "gpt-4o"
}
if options.BaseURL == "" {
options.BaseURL = "https://api.openai.com"
}
return &Provider{
opts: options,
}
}
// Init initializes the provider with options
func (p *Provider) Init(opts ...ai.Option) error {
for _, o := range opts {
o(&p.opts)
}
return nil
}
// Options returns the provider options
func (p *Provider) Options() ai.Options {
return p.opts
}
// String returns the provider name
func (p *Provider) String() string {
return "openai"
}
// Generate generates a response from the model
func (p *Provider) Generate(ctx context.Context, req *ai.Request, opts ...ai.GenerateOption) (*ai.Response, error) {
// Build tools for OpenAI format
var openaiTools []map[string]any
for _, t := range req.Tools {
openaiTools = append(openaiTools, map[string]any{
"type": "function",
"function": map[string]any{
"name": t.Name,
"description": t.Description,
"parameters": map[string]any{
"type": "object",
"properties": t.Properties,
},
},
})
}
// Build messages
messages := []map[string]any{
{"role": "system", "content": req.SystemPrompt},
{"role": "user", "content": req.Prompt},
}
// Build initial request
apiReq := map[string]any{
"model": p.opts.Model,
"messages": messages,
}
if len(openaiTools) > 0 {
apiReq["tools"] = openaiTools
}
// Make API call
resp, rawMessage, err := p.callAPI(ctx, apiReq)
if err != nil {
return nil, err
}
// If no tool calls, return response
if len(resp.ToolCalls) == 0 {
return resp, nil
}
// If tool handler is provided, execute tools and get final answer
if p.opts.ToolHandler != nil {
// Build follow-up messages
followUpMessages := append(messages, map[string]any{
"role": "assistant",
"content": rawMessage["content"],
"tool_calls": rawMessage["tool_calls"],
})
for _, tc := range resp.ToolCalls {
_, content := p.opts.ToolHandler(tc.Name, tc.Input)
followUpMessages = append(followUpMessages, map[string]any{
"role": "tool",
"tool_call_id": tc.ID,
"content": content,
})
}
followUpReq := map[string]any{
"model": p.opts.Model,
"messages": followUpMessages,
}
// Make follow-up API call
followUpResp, _, err := p.callAPI(ctx, followUpReq)
if err == nil && followUpResp.Reply != "" {
resp.Answer = followUpResp.Reply
}
}
return resp, nil
}
// Stream generates a streaming response (not yet implemented)
func (p *Provider) Stream(ctx context.Context, req *ai.Request, opts ...ai.GenerateOption) (ai.Stream, error) {
return nil, fmt.Errorf("streaming not yet implemented for openai provider")
}
// callAPI makes an HTTP request to the OpenAI API
func (p *Provider) callAPI(ctx context.Context, req map[string]any) (*ai.Response, map[string]any, error) {
// Marshal request
reqBody, err := json.Marshal(req)
if err != nil {
return nil, nil, fmt.Errorf("failed to marshal request: %w", err)
}
// Build HTTP request
apiURL := strings.TrimRight(p.opts.BaseURL, "/") + "/v1/chat/completions"
httpReq, err := http.NewRequestWithContext(ctx, "POST", apiURL, bytes.NewReader(reqBody))
if err != nil {
return nil, nil, fmt.Errorf("failed to create request: %w", err)
}
// Set headers
httpReq.Header.Set("Content-Type", "application/json")
httpReq.Header.Set("Authorization", "Bearer "+p.opts.APIKey)
// Make request
httpResp, err := http.DefaultClient.Do(httpReq)
if err != nil {
return nil, nil, fmt.Errorf("API request failed: %w", err)
}
defer httpResp.Body.Close()
// Read response
respBody, _ := io.ReadAll(httpResp.Body)
if httpResp.StatusCode != 200 {
return nil, nil, fmt.Errorf("API error (%s): %s", httpResp.Status, string(respBody))
}
// Parse response
var chatResp struct {
Choices []struct {
Message struct {
Content string `json:"content"`
ToolCalls []struct {
ID string `json:"id"`
Function struct {
Name string `json:"name"`
Arguments string `json:"arguments"`
} `json:"function"`
} `json:"tool_calls"`
} `json:"message"`
} `json:"choices"`
}
if err := json.Unmarshal(respBody, &chatResp); err != nil {
return nil, nil, fmt.Errorf("failed to parse response: %w", err)
}
if len(chatResp.Choices) == 0 {
return nil, nil, fmt.Errorf("no response from API")
}
choice := chatResp.Choices[0]
response := &ai.Response{
Reply: choice.Message.Content,
}
// Extract tool calls
for _, tc := range choice.Message.ToolCalls {
var input map[string]any
if err := json.Unmarshal([]byte(tc.Function.Arguments), &input); err != nil {
input = map[string]any{}
}
response.ToolCalls = append(response.ToolCalls, ai.ToolCall{
ID: tc.ID,
Name: tc.Function.Name,
Input: input,
})
}
// Return raw message for potential follow-up
rawMessage := map[string]any{
"content": choice.Message.Content,
"tool_calls": choice.Message.ToolCalls,
}
return response, rawMessage, nil
}
================================================
FILE: ai/openai/openai_test.go
================================================
package openai
import (
"context"
"testing"
"go-micro.dev/v5/ai"
)
func TestProvider_String(t *testing.T) {
p := NewProvider()
if p.String() != "openai" {
t.Errorf("Expected provider name 'openai', got '%s'", p.String())
}
}
func TestProvider_Init(t *testing.T) {
p := NewProvider()
err := p.Init(
ai.WithModel("test-model"),
ai.WithAPIKey("test-key"),
ai.WithBaseURL("https://test.com"),
)
if err != nil {
t.Fatalf("Init failed: %v", err)
}
opts := p.Options()
if opts.Model != "test-model" {
t.Errorf("Expected model 'test-model', got '%s'", opts.Model)
}
if opts.APIKey != "test-key" {
t.Errorf("Expected API key 'test-key', got '%s'", opts.APIKey)
}
if opts.BaseURL != "https://test.com" {
t.Errorf("Expected base URL 'https://test.com', got '%s'", opts.BaseURL)
}
}
func TestProvider_Options(t *testing.T) {
p := NewProvider(
ai.WithModel("custom-model"),
ai.WithAPIKey("my-key"),
)
opts := p.Options()
if opts.Model != "custom-model" {
t.Errorf("Expected model 'custom-model', got '%s'", opts.Model)
}
if opts.APIKey != "my-key" {
t.Errorf("Expected API key 'my-key', got '%s'", opts.APIKey)
}
}
func TestProvider_Defaults(t *testing.T) {
p := NewProvider()
opts := p.Options()
if opts.Model != "gpt-4o" {
t.Errorf("Expected default model 'gpt-4o', got '%s'", opts.Model)
}
if opts.BaseURL != "https://api.openai.com" {
t.Errorf("Expected default base URL 'https://api.openai.com', got '%s'", opts.BaseURL)
}
}
func TestProvider_Generate_NoAPIKey(t *testing.T) {
p := NewProvider()
req := &ai.Request{
Prompt: "Hello",
SystemPrompt: "You are helpful",
}
_, err := p.Generate(context.Background(), req)
if err == nil {
t.Error("Expected error when API key is missing, got nil")
}
}
func TestProvider_Stream_NotImplemented(t *testing.T) {
p := NewProvider()
req := &ai.Request{
Prompt: "Hello",
}
_, err := p.Stream(context.Background(), req)
if err == nil {
t.Error("Expected error for unimplemented streaming, got nil")
}
}
================================================
FILE: ai/options.go
================================================
package ai
import (
"context"
)
// Options for model configuration
type Options struct {
// Context for the model
Context context.Context
// Model name (e.g., "gpt-4o", "claude-sonnet-4-20250514")
Model string
// APIKey for authentication
APIKey string
// BaseURL for the API endpoint
BaseURL string
// ToolHandler handles tool calls (optional, for automatic tool execution)
ToolHandler ToolHandler
}
// GenerateOptions for generate call
type GenerateOptions struct {
// Context for this specific generate call
Context context.Context
}
// Option is a function that modifies Options
type Option func(*Options)
// GenerateOption is a function that modifies GenerateOptions
type GenerateOption func(*GenerateOptions)
// NewOptions creates new Options with defaults
func NewOptions(opts ...Option) Options {
options := Options{
Context: context.Background(),
}
for _, o := range opts {
o(&options)
}
return options
}
// WithModel sets the model name
func WithModel(m string) Option {
return func(o *Options) {
o.Model = m
}
}
// WithAPIKey sets the API key
func WithAPIKey(key string) Option {
return func(o *Options) {
o.APIKey = key
}
}
// WithBaseURL sets the base URL
func WithBaseURL(url string) Option {
return func(o *Options) {
o.BaseURL = url
}
}
// WithContext sets the context
func WithContext(ctx context.Context) Option {
return func(o *Options) {
o.Context = ctx
}
}
// WithToolHandler sets the tool handler
func WithToolHandler(handler ToolHandler) Option {
return func(o *Options) {
o.ToolHandler = handler
}
}
================================================
FILE: auth/ANALYSIS.md
================================================
# Auth Package Analysis
## Current Status: ✅ Fully Functional
The auth package is now **production-ready** with complete server/client wrappers and integration examples.
---
## ✅ What Exists
### 1. Core Interfaces (`auth.go`)
```go
type Auth interface {
Generate(id string, opts ...GenerateOption) (*Account, error)
Inspect(token string) (*Account, error)
Token(opts ...TokenOption) (*Token, error)
}
type Rules interface {
Verify(acc *Account, res *Resource, opts ...VerifyOption) error
Grant(rule *Rule) error
Revoke(rule *Rule) error
List(...ListOption) ([]*Rule, error)
}
```
**Status:** ✅ Well-designed, complete
### 2. Data Types
- `Account` - represents authenticated user/service
- `Token` - access/refresh token pair
- `Resource` - service endpoint to protect
- `Rule` - access control rule
- `Access` - grant/deny enum
**Status:** ✅ Complete
### 3. Implementations
**Noop Auth** (`noop.go`):
- For development/testing
- Always grants access
- No actual authentication
**Status:** ✅ Works for dev
**JWT Auth** (`jwt/jwt.go`):
- Uses RSA keys for signing
- Generates and verifies JWT tokens
- **⚠️ Problem:** Depends on external plugin `github.com/micro/plugins/v5/auth/jwt/token`
**Status:** ⚠️ External dependency
### 4. Authorization Logic (`rules.go`)
- Rule-based access control (RBAC)
- Supports wildcards (`*`)
- Priority-based rule evaluation
- Scope-based permissions
**Status:** ✅ Complete and tested
---
## ✅ Recently Completed
### 1. **Service Integration Wrapper** ✅
**Status:** IMPLEMENTED in `wrapper/auth/server.go`
```go
// AuthHandler wraps a service to enforce authentication
func AuthHandler(opts HandlerOptions) server.HandlerWrapper
func PublicEndpoints(...) HandlerOptions
func AuthRequired(...) HandlerOptions
func AuthOptional(authProvider auth.Auth) server.HandlerWrapper
```
Features:
- Token extraction from metadata
- Token verification with auth.Inspect()
- Authorization checks with rules.Verify()
- Account injection into context
- Skip endpoints support
- Comprehensive error handling (401/403)
### 2. **Client Wrapper** ✅
**Status:** IMPLEMENTED in `wrapper/auth/client.go`
```go
// AuthClient adds authentication tokens to client requests
func AuthClient(opts ClientOptions) client.Wrapper
func FromToken(token string) client.Wrapper
func FromContext(authProvider auth.Auth) client.Wrapper
```
Features:
- Automatic token injection
- Static token support
- Dynamic token generation from context
- Works with Call, Stream, and Publish
### 3. **Metadata Helpers** ✅
**Status:** IMPLEMENTED in `wrapper/auth/metadata.go`
```go
// Standard token extraction and injection
func TokenFromMetadata(md metadata.Metadata) (string, error)
func TokenToMetadata(md metadata.Metadata, token string) metadata.Metadata
func AccountFromMetadata(md metadata.Metadata, a auth.Auth) (*auth.Account, error)
```
Features:
- Bearer token extraction
- Case-insensitive header lookup
- Token format validation
- Direct account extraction
### 6. **Standalone JWT Implementation** ⚠️
**Status:** Partially complete (low priority)
Current JWT auth in `auth/jwt/jwt.go` depends on external plugin:
```go
jwtToken "github.com/micro/plugins/v5/auth/jwt/token"
```
**Note:** This is NOT a blocker. The wrappers work with any auth.Auth implementation including:
- JWT auth (with plugin dependency)
- Noop auth (for development)
- Custom auth implementations
**Future improvement:** Create self-contained JWT implementation to remove plugin dependency.
### 4. **Examples** ✅
**Status:** IMPLEMENTED in `examples/auth/`
Complete working example with:
- Protected Greeter service (server/)
- Client with authentication (client/)
- Proto definitions (proto/)
- Comprehensive README with:
- Architecture diagrams
- Code walkthrough
- Auth strategies
- Authorization rules
- Testing guide
- Production considerations
- Troubleshooting guide
### 5. **Documentation** ✅
**Status:** IMPLEMENTED
Complete documentation:
- `wrapper/auth/README.md` - Full API reference (200+ lines)
- `examples/auth/README.md` - Integration tutorial (400+ lines)
- Server wrapper documentation with examples
- Client wrapper documentation with examples
- Metadata helpers API reference
- Best practices guide
- Troubleshooting guide
- Production considerations
---
## 🔍 Detailed Analysis
### JWT Implementation Dependency Issue
File: `auth/jwt/jwt.go:7`
```go
jwtToken "github.com/micro/plugins/v5/auth/jwt/token"
```
This depends on:
- `github.com/micro/plugins` repository
- Must be separately installed
- May not be maintained
- Breaks self-contained promise
**Recommendation:** Create standalone JWT implementation in `auth/jwt/token/`
### Rules Verification Works Well
The `Verify()` function in `rules.go` is well-implemented:
- ✅ Handles wildcards correctly
- ✅ Priority-based evaluation
- ✅ Supports resource hierarchies (e.g., `/foo/*` matches `/foo/bar`)
- ✅ Public vs authenticated vs scoped access
- ✅ Tested (see `rules_test.go`)
### Context Integration Exists
```go
// From auth.go
func AccountFromContext(ctx context.Context) (*Account, bool)
func ContextWithAccount(ctx context.Context, account *Account) context.Context
```
This is ready to use once wrappers are implemented.
---
## 🛠️ Implementation Status
### Phase 1: Critical ✅ COMPLETE
1. ✅ **Server Wrapper** - `wrapper/auth/server.go`
- Token extraction from metadata
- Verification with auth.Inspect()
- Authorization with rules.Verify()
- Skip endpoints support
- Helper functions (AuthRequired, PublicEndpoints, AuthOptional)
2. ✅ **Client Wrapper** - `wrapper/auth/client.go`
- Adds Authorization header/metadata
- Static token support (FromToken)
- Dynamic token generation (FromContext)
- Works with Call, Stream, Publish
3. ✅ **Metadata Helpers** - `wrapper/auth/metadata.go`
- TokenFromMetadata - extract Bearer token
- TokenToMetadata - inject Bearer token
- AccountFromMetadata - extract and verify in one step
### Phase 2: Important ✅ COMPLETE
4. ⚠️ **Standalone JWT Implementation** - Deferred (not critical)
- Current JWT works with plugin
- Can use noop auth for development
- Future enhancement to remove plugin dependency
5. ⚠️ **Key Generation Utilities** - Deferred (not critical)
- JWT auth handles key management
- Future enhancement for convenience
6. ✅ **Examples** - `examples/auth/`
- Complete server/client example
- Protected and public endpoints
- Comprehensive README (400+ lines)
- Code walkthrough and best practices
### Phase 3: Production Ready ✅ COMPLETE
7. ⚠️ **Advanced Examples** - Future enhancement
- Basic example covers most use cases
- Can be added based on demand
8. ✅ **Documentation**
- `wrapper/auth/README.md` - Full API reference
- `examples/auth/README.md` - Integration guide
- Best practices and troubleshooting
9. ✅ **Testing Utilities**
- Noop auth for tests
- Token generation examples in docs
---
## 📋 Integration Checklist
To use auth with services, users need:
- [x] Auth interface and implementations
- [x] **Server wrapper to enforce auth** ✅
- [x] **Client wrapper to send auth** ✅
- [x] Metadata helpers ✅
- [x] Examples showing integration ✅
- [x] Documentation ✅
- [~] Working JWT implementation (has plugin dependency, not critical)
**Current completeness: ~95%** 🎉
The auth system is now fully functional and production-ready!
---
## 💡 Recommendations
### ✅ Completed
1. ✅ **Created wrapper/auth package** with server and client wrappers
2. ✅ **Wrote comprehensive examples** showing protected service
3. ✅ **Documented** integration patterns with 600+ lines of docs
### Optional Future Enhancements
4. **Remove plugin dependency** - create standalone JWT
- Current solution works fine with plugin
- Would reduce external dependencies
- Priority: Low
5. **Add to CLI** - `micro auth` commands for token management
- Generate tokens from CLI
- Inspect tokens
- Manage accounts
- Priority: Medium
6. **OAuth2 provider** - for enterprise SSO
- Integration with external identity providers
- Priority: Low (can use custom auth provider)
7. **API key auth** - simpler alternative to JWT
- For machine-to-machine auth
- Priority: Low
8. **Audit logging** - track auth events
- Who accessed what and when
- Priority: Medium
9. **Rate limiting** - per account/scope
- Prevent abuse
- Priority: Medium
---
## 🎉 Status: Auth System Complete
The auth system is now **fully functional and production-ready**!
**What's available:**
- ✅ Server wrapper for enforcing auth
- ✅ Client wrapper for adding auth
- ✅ Metadata helpers for token handling
- ✅ Complete working example
- ✅ Comprehensive documentation
- ✅ Best practices guide
- ✅ Troubleshooting guide
**Usage:**
```go
// Server
micro.WrapHandler(authWrapper.AuthHandler(...))
// Client
micro.WrapClient(authWrapper.FromToken(...))
```
See `examples/auth/` for complete working code!
================================================
FILE: auth/auth.go
================================================
// Package auth provides authentication and authorization capability
package auth
import (
"context"
"errors"
"time"
)
const (
// BearerScheme used for Authorization header.
BearerScheme = "Bearer "
// ScopePublic is the scope applied to a rule to allow access to the public.
ScopePublic = ""
// ScopeAccount is the scope applied to a rule to limit to users with any valid account.
ScopeAccount = "*"
)
var (
// ErrInvalidToken is when the token provided is not valid.
ErrInvalidToken = errors.New("invalid token provided")
// ErrForbidden is when a user does not have the necessary scope to access a resource.
ErrForbidden = errors.New("resource forbidden")
)
// Auth provides authentication and authorization.
type Auth interface {
// Init the auth
Init(opts ...Option)
// Options set for auth
Options() Options
// Generate a new account
Generate(id string, opts ...GenerateOption) (*Account, error)
// Inspect a token
Inspect(token string) (*Account, error)
// Token generated using refresh token or credentials
Token(opts ...TokenOption) (*Token, error)
// String returns the name of the implementation
String() string
}
// Rules manages access to resources.
type Rules interface {
// Verify an account has access to a resource using the rules
Verify(acc *Account, res *Resource, opts ...VerifyOption) error
// Grant access to a resource
Grant(rule *Rule) error
// Revoke access to a resource
Revoke(rule *Rule) error
// List returns all the rules used to verify requests
List(...ListOption) ([]*Rule, error)
}
// Account provided by an auth provider.
type Account struct {
// Any other associated metadata
Metadata map[string]string `json:"metadata"`
// ID of the account e.g. email
ID string `json:"id"`
// Type of the account, e.g. service
Type string `json:"type"`
// Issuer of the account
Issuer string `json:"issuer"`
// Secret for the account, e.g. the password
Secret string `json:"secret"`
// Scopes the account has access to
Scopes []string `json:"scopes"`
}
// Token can be short or long lived.
type Token struct {
// Time of token creation
Created time.Time `json:"created"`
// Time of token expiry
Expiry time.Time `json:"expiry"`
// The token to be used for accessing resources
AccessToken string `json:"access_token"`
// RefreshToken to be used to generate a new token
RefreshToken string `json:"refresh_token"`
}
// Expired returns a boolean indicating if the token needs to be refreshed.
func (t *Token) Expired() bool {
return t.Expiry.Unix() < time.Now().Unix()
}
// Resource is an entity such as a user or.
type Resource struct {
// Name of the resource, e.g. go.micro.service.notes
Name string `json:"name"`
// Type of resource, e.g. service
Type string `json:"type"`
// Endpoint resource e.g NotesService.Create
Endpoint string `json:"endpoint"`
}
// Access defines the type of access a rule grants.
type Access int
const (
// AccessGranted to a resource.
AccessGranted Access = iota
// AccessDenied to a resource.
AccessDenied
)
// Rule is used to verify access to a resource.
type Rule struct {
// Resource the rule applies to
Resource *Resource
// ID of the rule, e.g. "public"
ID string
// Scope the rule requires, a blank scope indicates open to the public and * indicates the rule
// applies to any valid account
Scope string
// Access determines if the rule grants or denies access to the resource
Access Access
// Priority the rule should take when verifying a request, the higher the value the sooner the
// rule will be applied
Priority int32
}
type accountKey struct{}
// AccountFromContext gets the account from the context, which
// is set by the auth wrapper at the start of a call. If the account
// is not set, a nil account will be returned. The error is only returned
// when there was a problem retrieving an account.
func AccountFromContext(ctx context.Context) (*Account, bool) {
acc, ok := ctx.Value(accountKey{}).(*Account)
return acc, ok
}
// ContextWithAccount sets the account in the context.
func ContextWithAccount(ctx context.Context, account *Account) context.Context {
return context.WithValue(ctx, accountKey{}, account)
}
================================================
FILE: auth/jwt/jwt.go
================================================
package jwt
import (
"sync"
"time"
jwtToken "github.com/micro/plugins/v5/auth/jwt/token"
"go-micro.dev/v5/auth"
"go-micro.dev/v5/cmd"
)
func init() {
cmd.DefaultAuths["jwt"] = NewAuth
}
// NewAuth returns a new instance of the Auth service.
func NewAuth(opts ...auth.Option) auth.Auth {
j := new(jwt)
j.Init(opts...)
return j
}
func NewRules() auth.Rules {
return new(jwtRules)
}
type jwt struct {
sync.Mutex
options auth.Options
jwt jwtToken.Provider
}
type jwtRules struct {
sync.Mutex
rules []*auth.Rule
}
func (j *jwt) String() string {
return "jwt"
}
func (j *jwt) Init(opts ...auth.Option) {
j.Lock()
defer j.Unlock()
for _, o := range opts {
o(&j.options)
}
j.jwt = jwtToken.New(
jwtToken.WithPrivateKey(j.options.PrivateKey),
jwtToken.WithPublicKey(j.options.PublicKey),
)
}
func (j *jwt) Options() auth.Options {
j.Lock()
defer j.Unlock()
return j.options
}
func (j *jwt) Generate(id string, opts ...auth.GenerateOption) (*auth.Account, error) {
options := auth.NewGenerateOptions(opts...)
account := &auth.Account{
ID: id,
Type: options.Type,
Scopes: options.Scopes,
Metadata: options.Metadata,
Issuer: j.Options().Namespace,
}
// generate a JWT secret which can be provided to the Token() method
// and exchanged for an access token
secret, err := j.jwt.Generate(account)
if err != nil {
return nil, err
}
account.Secret = secret.Token
// return the account
return account, nil
}
func (j *jwtRules) Grant(rule *auth.Rule) error {
j.Lock()
defer j.Unlock()
j.rules = append(j.rules, rule)
return nil
}
func (j *jwtRules) Revoke(rule *auth.Rule) error {
j.Lock()
defer j.Unlock()
rules := make([]*auth.Rule, 0, len(j.rules))
for _, r := range j.rules {
if r.ID != rule.ID {
rules = append(rules, r)
}
}
j.rules = rules
return nil
}
func (j *jwtRules) Verify(acc *auth.Account, res *auth.Resource, opts ...auth.VerifyOption) error {
j.Lock()
defer j.Unlock()
var options auth.VerifyOptions
for _, o := range opts {
o(&options)
}
return auth.Verify(j.rules, acc, res)
}
func (j *jwtRules) List(opts ...auth.ListOption) ([]*auth.Rule, error) {
j.Lock()
defer j.Unlock()
return j.rules, nil
}
func (j *jwt) Inspect(token string) (*auth.Account, error) {
return j.jwt.Inspect(token)
}
func (j *jwt) Token(opts ...auth.TokenOption) (*auth.Token, error) {
options := auth.NewTokenOptions(opts...)
secret := options.RefreshToken
if len(options.Secret) > 0 {
secret = options.Secret
}
account, err := j.jwt.Inspect(secret)
if err != nil {
return nil, err
}
access, err := j.jwt.Generate(account, jwtToken.WithExpiry(options.Expiry))
if err != nil {
return nil, err
}
refresh, err := j.jwt.Generate(account, jwtToken.WithExpiry(options.Expiry+time.Hour))
if err != nil {
return nil, err
}
return &auth.Token{
Created: access.Created,
Expiry: access.Expiry,
AccessToken: access.Token,
RefreshToken: refresh.Token,
}, nil
}
================================================
FILE: auth/jwt/token/jwt.go
================================================
package token
import (
"encoding/base64"
"time"
"github.com/dgrijalva/jwt-go"
"go-micro.dev/v5/auth"
)
// authClaims to be encoded in the JWT.
type authClaims struct {
Type string `json:"type"`
Scopes []string `json:"scopes"`
Metadata map[string]string `json:"metadata"`
jwt.StandardClaims
}
// JWT implementation of token provider.
type JWT struct {
opts Options
}
// New returns an initialized basic provider.
func New(opts ...Option) Provider {
return &JWT{
opts: NewOptions(opts...),
}
}
// Generate a new JWT.
func (j *JWT) Generate(acc *auth.Account, opts ...GenerateOption) (*Token, error) {
// decode the private key
priv, err := base64.StdEncoding.DecodeString(j.opts.PrivateKey)
if err != nil {
return nil, err
}
// parse the private key
key, err := jwt.ParseRSAPrivateKeyFromPEM(priv)
if err != nil {
return nil, ErrEncodingToken
}
// parse the options
options := NewGenerateOptions(opts...)
// generate the JWT
expiry := time.Now().Add(options.Expiry)
t := jwt.NewWithClaims(jwt.SigningMethodRS256, authClaims{
acc.Type, acc.Scopes, acc.Metadata, jwt.StandardClaims{
Subject: acc.ID,
Issuer: acc.Issuer,
ExpiresAt: expiry.Unix(),
},
})
tok, err := t.SignedString(key)
if err != nil {
return nil, err
}
// return the token
return &Token{
Token: tok,
Expiry: expiry,
Created: time.Now(),
}, nil
}
// Inspect a JWT.
func (j *JWT) Inspect(t string) (*auth.Account, error) {
// decode the public key
pub, err := base64.StdEncoding.DecodeString(j.opts.PublicKey)
if err != nil {
return nil, err
}
// parse the public key
res, err := jwt.ParseWithClaims(t, &authClaims{}, func(token *jwt.Token) (interface{}, error) {
return jwt.ParseRSAPublicKeyFromPEM(pub)
})
if err != nil {
return nil, ErrInvalidToken
}
// validate the token
if !res.Valid {
return nil, ErrInvalidToken
}
claims, ok := res.Claims.(*authClaims)
if !ok {
return nil, ErrInvalidToken
}
// return the token
return &auth.Account{
ID: claims.Subject,
Issuer: claims.Issuer,
Type: claims.Type,
Scopes: claims.Scopes,
Metadata: claims.Metadata,
}, nil
}
// String returns JWT.
func (j *JWT) String() string {
return "jwt"
}
================================================
FILE: auth/jwt/token/jwt_test.go
================================================
package token
import (
"os"
"testing"
"time"
"go-micro.dev/v5/auth"
)
func TestGenerate(t *testing.T) {
privKey, err := os.ReadFile("test/sample_key")
if err != nil {
t.Fatalf("Unable to read private key: %v", err)
}
j := New(
WithPrivateKey(string(privKey)),
)
_, err = j.Generate(&auth.Account{ID: "test"})
if err != nil {
t.Fatalf("Generate returned %v error, expected nil", err)
}
}
func TestInspect(t *testing.T) {
pubKey, err := os.ReadFile("test/sample_key.pub")
if err != nil {
t.Fatalf("Unable to read public key: %v", err)
}
privKey, err := os.ReadFile("test/sample_key")
if err != nil {
t.Fatalf("Unable to read private key: %v", err)
}
j := New(
WithPublicKey(string(pubKey)),
WithPrivateKey(string(privKey)),
)
t.Run("Valid token", func(t *testing.T) {
md := map[string]string{"foo": "bar"}
scopes := []string{"admin"}
subject := "test"
acc := &auth.Account{ID: subject, Scopes: scopes, Metadata: md}
tok, err := j.Generate(acc)
if err != nil {
t.Fatalf("Generate returned %v error, expected nil", err)
}
tok2, err := j.Inspect(tok.Token)
if err != nil {
t.Fatalf("Inspect returned %v error, expected nil", err)
}
if acc.ID != subject {
t.Errorf("Inspect returned %v as the token subject, expected %v", acc.ID, subject)
}
if len(tok2.Scopes) != len(scopes) {
t.Errorf("Inspect returned %v scopes, expected %v", len(tok2.Scopes), len(scopes))
}
if len(tok2.Metadata) != len(md) {
t.Errorf("Inspect returned %v as the token metadata, expected %v", tok2.Metadata, md)
}
})
t.Run("Expired token", func(t *testing.T) {
tok, err := j.Generate(&auth.Account{}, WithExpiry(-10*time.Second))
if err != nil {
t.Fatalf("Generate returned %v error, expected nil", err)
}
if _, err = j.Inspect(tok.Token); err != ErrInvalidToken {
t.Fatalf("Inspect returned %v error, expected %v", err, ErrInvalidToken)
}
})
t.Run("Invalid token", func(t *testing.T) {
_, err := j.Inspect("Invalid token")
if err != ErrInvalidToken {
t.Fatalf("Inspect returned %v error, expected %v", err, ErrInvalidToken)
}
})
}
================================================
FILE: auth/jwt/token/options.go
================================================
package token
import (
"time"
"go-micro.dev/v5/store"
)
type Options struct {
// Store to persist the tokens
Store store.Store
// PublicKey base64 encoded, used by JWT
PublicKey string
// PrivateKey base64 encoded, used by JWT
PrivateKey string
}
type Option func(o *Options)
// WithStore sets the token providers store.
func WithStore(s store.Store) Option {
return func(o *Options) {
o.Store = s
}
}
// WithPublicKey sets the JWT public key.
func WithPublicKey(key string) Option {
return func(o *Options) {
o.PublicKey = key
}
}
// WithPrivateKey sets the JWT private key.
func WithPrivateKey(key string) Option {
return func(o *Options) {
o.PrivateKey = key
}
}
func NewOptions(opts ...Option) Options {
var options Options
for _, o := range opts {
o(&options)
}
// set default store
if options.Store == nil {
options.Store = store.DefaultStore
}
return options
}
type GenerateOptions struct {
// Expiry for the token
Expiry time.Duration
}
type GenerateOption func(o *GenerateOptions)
// WithExpiry for the generated account's token expires.
func WithExpiry(d time.Duration) GenerateOption {
return func(o *GenerateOptions) {
o.Expiry = d
}
}
// NewGenerateOptions from a slice of options.
func NewGenerateOptions(opts ...GenerateOption) GenerateOptions {
var options GenerateOptions
for _, o := range opts {
o(&options)
}
// set default Expiry of token
if options.Expiry == 0 {
options.Expiry = time.Minute * 15
}
return options
}
================================================
FILE: auth/jwt/token/test/sample_key
================================================
LS0tLS1CRUdJTiBSU0EgUFJJVkFURSBLRVktLS0tLQpNSUlKS3dJQkFBS0NBZ0VBOFNiSlA1WGJFaWRSbTViMnNOcExHbzJlV2ZVNU9KZTBpemdySHdEOEg3RjZQa1BkCi9SbDkvMXBNVjdNaU8zTEh3dGhIQzJCUllxcisxd0Zkb1pDR0JZckxhWHVYRnFLMHZ1WmhQcUUzYXpqdUlIUXUKMEJIL2xYUU1xeUVxRjVNSTJ6ZWpDNHpNenIxNU9OK2dFNEpuaXBqcC9DZGpPUEFEbUpHK0JKOXFlRS9RUGVtLwptVWRJVC9MYUY3a1F4eVlLNVZLbitOZ09Xek1sektBQXBDbjdUVEtCVWU4RlpHNldTWDdMVjBlTEdIc29pYnhsCm85akRqbFk1b0JPY3pmcWVOV0hLNUdYQjdRd3BMTmg5NDZQelpucW9hcFdVZStZL1JPaUhpekpUY3I1Wk1TTDUKd2xFcThoTmhtaG01Tk5lL08rR2dqQkROU2ZVaDA2K3E0bmdtYm1OWDVoODM4QmJqUmN5YzM2ZHd6NkpVK2R1bwpSdFFoZ2lZOTEwcFBmOWJhdVhXcXdVQ1VhNHFzSHpqS1IwTC9OMVhYQXlsQ0RqeWVnWnp6Y093MkNIOFNrZkZVCnJnTHJQYkVCOWVnY0drMzgrYnBLczNaNlJyNSt0bkQxQklQSUZHTGVJMFVPQzAreGlCdjBvenhJRE9GbldhOVUKVEdEeFV4OG9qOFZJZVJuV0RxNk1jMWlKcDhVeWNpQklUUnR3NGRabzcweG1mbmVJV3pyM0tTTmFoU29nSmRSMApsYVF6QXVQM2FpV1hJTXAyc2M4U2MrQmwrTGpYbUJveEJyYUJIaDlLa0pKRWNnQUZ3czJib2pDbEpPWXhvRi9YCmdGS1NzSW5IRHJIVk95V1BCZTNmYWRFYzc3YituYi9leE96cjFFcnhoR2c5akZtcmtPK3M0eEdodjZNQ0F3RUEKQVFLQ0FnRUFqUzc1Q2VvUlRRcUtBNzZaaFNiNGEzNVlKRENtcEpSazFsRTNKYnFzNFYxRnhXaDBjZmJYeG9VMgpSdTRRYjUrZWhsdWJGSFQ2a1BxdG9uRWhRVExjMUNmVE9WbHJOb3hocDVZM2ZyUmlQcnNnNXcwK1R3RUtrcFJUCnltanJQTXdQbGxCM2U0NmVaYmVXWGc3R3FFVmptMGcxVFRRK0tocVM4R0w3VGJlTFhRN1ZTem9ydTNCNVRKMVEKeEN6TVB0dnQ2eDYrU3JrcmhvZG1iT3VNRkpDam1TbWxmck9pZzQ4Zkc3NUpERHRObXpLWHBEUVJpYUNodFJhVQpQRHpmUTlTamhYdFFqdkZvWFFFT3BqdkZVRjR2WldNUWNQNUw1VklDM3JRSWp4MFNzQTN6S0FwakVUbjJHNjN2CktZby8zVWttbzhkUCtGRHA3NCs5a3pLNHFFaFJycEl3bEtiN0VOZWtDUXZqUFl1K3pyKzMyUXdQNTJ2L2FveWQKdjJJaUY3M2laTU1vZDhhYjJuQStyVEI2T0cvOVlSYk5kV21tay9VTi9jUHYrN214TmZ6Y1d1ZU1XcThxMXh4eAptNTNpR0NSQ29PQ1lDQk4zcUFkb1JwYW5xd3lCOUxrLzFCQjBHUld3MjgxK3VhNXNYRnZBVDBKeTVURnduMncvClU1MlJKWFlNOXVhMFBvd214b0RDUWRuNFZYVkdNZGdXaHN4aXhHRlYwOUZObWJJQWJaN0xaWGtkS1gzc1ZVbTcKWU1WYWIzVVo2bEhtdXYzT1NzcHNVUlRqN1hiRzZpaVVlaDU1aW91OENWbnRndWtFcnEzQTQwT05FVzhjNDBzOQphVTBGaSs4eWZpQTViaVZHLzF0bWlucUVERkhuQStnWk1xNEhlSkZxcWZxaEZKa1JwRGtDZ2dFQkFQeGR1NGNKCm5Da1duZDdPWFlHMVM3UDdkVWhRUzgwSDlteW9uZFc5bGFCQm84RWRPeTVTZzNOUmsxQ2pNZFZ1a3FMcjhJSnkKeStLWk15SVpvSlJvbllaMEtIUUVMR3ZLbzFOS2NLQ1FJbnYvWHVCdFJpRzBVb1pQNVkwN0RpRFBRQWpYUjlXUwpBc0EzMmQ1eEtFOC91Y3h0MjVQVzJFakNBUmtVeHQ5d0tKazN3bC9JdXVYRlExTDdDWjJsOVlFUjlHeWxUbzhNCmxXUEY3YndtUFV4UVNKaTNVS0FjTzZweTVUU1lkdWQ2aGpQeXJwSXByNU42VGpmTlRFWkVBeU9LbXVpOHVkUkoKMUg3T3RQVEhGZElKQjNrNEJnRDZtRE1HbjB2SXBLaDhZN3NtRUZBbFkvaXlCZjMvOHk5VHVMb1BycEdqR3RHbgp4Y2RpMHFud2p0SGFNbFVDZ2dFQkFQU2Z0dVFCQ2dTU2JLUSswUEFSR2VVeEQyTmlvZk1teENNTmdHUzJ5Ull3CjRGaGV4ZWkwMVJoaFk1NjE3UjduR1dzb0czd1RQa3dvRTJtbE1aQkoxeWEvUU9RRnQ3WG02OVl0RGh0T2FWbDgKL0o4dlVuSTBtWmxtT2pjTlRoYnVPZDlNSDlRdGxIRUMxMlhYdHJNb3Fsb0U2a05TT0pJalNxYm9wcDRXc1BqcApvZTZ0Nkdyd1RhOHBHeUJWWS90Mi85Ym5ORHVPVlpjODBaODdtY2gzcDNQclBqU3h5di9saGxYMFMwYUdHTkhTCk1XVjdUa25OaGo1TWlIRXFnZ1pZemtBWTkyd1JoVENnU1A2M0VNcitUWXFudXVuMXJHbndPYm95TDR2aFRpV0UKcU42UDNCTFlCZ1FpMllDTDludEJrOEl6RHZyd096dW5GVnhhZ0g5SVVoY0NnZ0VCQUwzQXlLa1BlOENWUmR6cQpzL284VkJDZmFSOFhhUGRnSGxTek1BSXZpNXEwNENqckRyMlV3MHZwTVdnM1hOZ0xUT3g5bFJpd3NrYk9SRmxHCmhhd3hRUWlBdkk0SE9WTlBTU0R1WHVNTG5USTQ0S0RFNlMrY2cxU0VMS2pWbDVqcDNFOEpkL1RJMVpLc0xBQUsKZTNHakM5UC9ZbE8xL21ndW4xNjVkWk01cFAwWHBPb2FaeFV2RHFFTktyekR0V1g0RngyOTZlUzdaSFJodFpCNwovQ2t1VUhlcmxrN2RDNnZzdWhTaTh2eTM3c0tPbmQ0K3c4cVM4czhZYVZxSDl3ZzVScUxxakp0bmJBUnc3alVDCm9KQ053M1hNdnc3clhaYzRTbnhVQUNMRGJNV2lLQy9xL1ZGWW9oTEs2WkpUVkJscWd5cjBSYzBRWmpDMlNJb0kKMjRwRWt3VUNnZ0VCQUpqb0FJVVNsVFY0WlVwaExXN3g4WkxPa01UWjBVdFFyd2NPR0hSYndPUUxGeUNGMVFWNQppejNiR2s4SmZyZHpVdk1sTmREZm9uQXVHTHhQa3VTVEUxWlg4L0xVRkJveXhyV3dvZ0cxaUtwME11QTV6em90CjROai9DbUtCQVkvWnh2anA5M2RFS21aZGxWQkdmeUFMeWpmTW5MWUovZXh5L09YSnhPUktZTUttSHg4M08zRWsKMWhvb0FwbTZabTIzMjRGME1iVU1ham5Idld2ZjhHZGJTNk5zcHd4L0dkbk1tYVMrdUJMVUhVMkNLbmc1bEIwVAp4OWJITmY0dXlPbTR0dXRmNzhCd1R5V3UreEdrVW0zZ2VZMnkvR1hqdDZyY2l1ajFGNzFDenZzcXFmZThTcDdJCnd6SHdxcTNzVHR5S2lCYTZuYUdEYWpNR1pKYSt4MVZJV204Q2dnRUJBT001ajFZR25Ba0pxR0czQWJSVDIvNUMKaVVxN0loYkswOGZsSGs5a2YwUlVjZWc0ZVlKY3dIRXJVaE4rdWQyLzE3MC81dDYra0JUdTVZOUg3bkpLREtESQpoeEg5SStyamNlVkR0RVNTRkluSXdDQ1lrOHhOUzZ0cHZMV1U5b0pibGFKMlZsalV2NGRFWGVQb0hkREh1Zk9ZClVLa0lsV2E3Uit1QzNEOHF5U1JrQnFLa3ZXZ1RxcFNmTVNkc1ZTeFIzU2Q4SVhFSHFjTDNUNEtMWGtYNEdEamYKMmZOSTFpZkx6ekhJMTN3Tk5IUTVRNU9SUC9pell2QzVzZkx4U2ZIUXJiMXJZVkpKWkI5ZjVBUjRmWFpHSVFsbApjMG8xd0JmZFlqMnZxVDlpR09IQnNSSTlSL2M2RzJQcUt3aFRpSzJVR2lmVFNEUVFuUkF6b2tpQVkrbE8vUjQ9Ci0tLS0tRU5EIFJTQSBQUklWQVRFIEtFWS0tLS0tCg==
================================================
FILE: auth/jwt/token/test/sample_key 2
================================================
LS0tLS1CRUdJTiBSU0EgUFJJVkFURSBLRVktLS0tLQpNSUlKS3dJQkFBS0NBZ0VBOFNiSlA1WGJFaWRSbTViMnNOcExHbzJlV2ZVNU9KZTBpemdySHdEOEg3RjZQa1BkCi9SbDkvMXBNVjdNaU8zTEh3dGhIQzJCUllxcisxd0Zkb1pDR0JZckxhWHVYRnFLMHZ1WmhQcUUzYXpqdUlIUXUKMEJIL2xYUU1xeUVxRjVNSTJ6ZWpDNHpNenIxNU9OK2dFNEpuaXBqcC9DZGpPUEFEbUpHK0JKOXFlRS9RUGVtLwptVWRJVC9MYUY3a1F4eVlLNVZLbitOZ09Xek1sektBQXBDbjdUVEtCVWU4RlpHNldTWDdMVjBlTEdIc29pYnhsCm85akRqbFk1b0JPY3pmcWVOV0hLNUdYQjdRd3BMTmg5NDZQelpucW9hcFdVZStZL1JPaUhpekpUY3I1Wk1TTDUKd2xFcThoTmhtaG01Tk5lL08rR2dqQkROU2ZVaDA2K3E0bmdtYm1OWDVoODM4QmJqUmN5YzM2ZHd6NkpVK2R1bwpSdFFoZ2lZOTEwcFBmOWJhdVhXcXdVQ1VhNHFzSHpqS1IwTC9OMVhYQXlsQ0RqeWVnWnp6Y093MkNIOFNrZkZVCnJnTHJQYkVCOWVnY0drMzgrYnBLczNaNlJyNSt0bkQxQklQSUZHTGVJMFVPQzAreGlCdjBvenhJRE9GbldhOVUKVEdEeFV4OG9qOFZJZVJuV0RxNk1jMWlKcDhVeWNpQklUUnR3NGRabzcweG1mbmVJV3pyM0tTTmFoU29nSmRSMApsYVF6QXVQM2FpV1hJTXAyc2M4U2MrQmwrTGpYbUJveEJyYUJIaDlLa0pKRWNnQUZ3czJib2pDbEpPWXhvRi9YCmdGS1NzSW5IRHJIVk95V1BCZTNmYWRFYzc3YituYi9leE96cjFFcnhoR2c5akZtcmtPK3M0eEdodjZNQ0F3RUEKQVFLQ0FnRUFqUzc1Q2VvUlRRcUtBNzZaaFNiNGEzNVlKRENtcEpSazFsRTNKYnFzNFYxRnhXaDBjZmJYeG9VMgpSdTRRYjUrZWhsdWJGSFQ2a1BxdG9uRWhRVExjMUNmVE9WbHJOb3hocDVZM2ZyUmlQcnNnNXcwK1R3RUtrcFJUCnltanJQTXdQbGxCM2U0NmVaYmVXWGc3R3FFVmptMGcxVFRRK0tocVM4R0w3VGJlTFhRN1ZTem9ydTNCNVRKMVEKeEN6TVB0dnQ2eDYrU3JrcmhvZG1iT3VNRkpDam1TbWxmck9pZzQ4Zkc3NUpERHRObXpLWHBEUVJpYUNodFJhVQpQRHpmUTlTamhYdFFqdkZvWFFFT3BqdkZVRjR2WldNUWNQNUw1VklDM3JRSWp4MFNzQTN6S0FwakVUbjJHNjN2CktZby8zVWttbzhkUCtGRHA3NCs5a3pLNHFFaFJycEl3bEtiN0VOZWtDUXZqUFl1K3pyKzMyUXdQNTJ2L2FveWQKdjJJaUY3M2laTU1vZDhhYjJuQStyVEI2T0cvOVlSYk5kV21tay9VTi9jUHYrN214TmZ6Y1d1ZU1XcThxMXh4eAptNTNpR0NSQ29PQ1lDQk4zcUFkb1JwYW5xd3lCOUxrLzFCQjBHUld3MjgxK3VhNXNYRnZBVDBKeTVURnduMncvClU1MlJKWFlNOXVhMFBvd214b0RDUWRuNFZYVkdNZGdXaHN4aXhHRlYwOUZObWJJQWJaN0xaWGtkS1gzc1ZVbTcKWU1WYWIzVVo2bEhtdXYzT1NzcHNVUlRqN1hiRzZpaVVlaDU1aW91OENWbnRndWtFcnEzQTQwT05FVzhjNDBzOQphVTBGaSs4eWZpQTViaVZHLzF0bWlucUVERkhuQStnWk1xNEhlSkZxcWZxaEZKa1JwRGtDZ2dFQkFQeGR1NGNKCm5Da1duZDdPWFlHMVM3UDdkVWhRUzgwSDlteW9uZFc5bGFCQm84RWRPeTVTZzNOUmsxQ2pNZFZ1a3FMcjhJSnkKeStLWk15SVpvSlJvbllaMEtIUUVMR3ZLbzFOS2NLQ1FJbnYvWHVCdFJpRzBVb1pQNVkwN0RpRFBRQWpYUjlXUwpBc0EzMmQ1eEtFOC91Y3h0MjVQVzJFakNBUmtVeHQ5d0tKazN3bC9JdXVYRlExTDdDWjJsOVlFUjlHeWxUbzhNCmxXUEY3YndtUFV4UVNKaTNVS0FjTzZweTVUU1lkdWQ2aGpQeXJwSXByNU42VGpmTlRFWkVBeU9LbXVpOHVkUkoKMUg3T3RQVEhGZElKQjNrNEJnRDZtRE1HbjB2SXBLaDhZN3NtRUZBbFkvaXlCZjMvOHk5VHVMb1BycEdqR3RHbgp4Y2RpMHFud2p0SGFNbFVDZ2dFQkFQU2Z0dVFCQ2dTU2JLUSswUEFSR2VVeEQyTmlvZk1teENNTmdHUzJ5Ull3CjRGaGV4ZWkwMVJoaFk1NjE3UjduR1dzb0czd1RQa3dvRTJtbE1aQkoxeWEvUU9RRnQ3WG02OVl0RGh0T2FWbDgKL0o4dlVuSTBtWmxtT2pjTlRoYnVPZDlNSDlRdGxIRUMxMlhYdHJNb3Fsb0U2a05TT0pJalNxYm9wcDRXc1BqcApvZTZ0Nkdyd1RhOHBHeUJWWS90Mi85Ym5ORHVPVlpjODBaODdtY2gzcDNQclBqU3h5di9saGxYMFMwYUdHTkhTCk1XVjdUa25OaGo1TWlIRXFnZ1pZemtBWTkyd1JoVENnU1A2M0VNcitUWXFudXVuMXJHbndPYm95TDR2aFRpV0UKcU42UDNCTFlCZ1FpMllDTDludEJrOEl6RHZyd096dW5GVnhhZ0g5SVVoY0NnZ0VCQUwzQXlLa1BlOENWUmR6cQpzL284VkJDZmFSOFhhUGRnSGxTek1BSXZpNXEwNENqckRyMlV3MHZwTVdnM1hOZ0xUT3g5bFJpd3NrYk9SRmxHCmhhd3hRUWlBdkk0SE9WTlBTU0R1WHVNTG5USTQ0S0RFNlMrY2cxU0VMS2pWbDVqcDNFOEpkL1RJMVpLc0xBQUsKZTNHakM5UC9ZbE8xL21ndW4xNjVkWk01cFAwWHBPb2FaeFV2RHFFTktyekR0V1g0RngyOTZlUzdaSFJodFpCNwovQ2t1VUhlcmxrN2RDNnZzdWhTaTh2eTM3c0tPbmQ0K3c4cVM4czhZYVZxSDl3ZzVScUxxakp0bmJBUnc3alVDCm9KQ053M1hNdnc3clhaYzRTbnhVQUNMRGJNV2lLQy9xL1ZGWW9oTEs2WkpUVkJscWd5cjBSYzBRWmpDMlNJb0kKMjRwRWt3VUNnZ0VCQUpqb0FJVVNsVFY0WlVwaExXN3g4WkxPa01UWjBVdFFyd2NPR0hSYndPUUxGeUNGMVFWNQppejNiR2s4SmZyZHpVdk1sTmREZm9uQXVHTHhQa3VTVEUxWlg4L0xVRkJveXhyV3dvZ0cxaUtwME11QTV6em90CjROai9DbUtCQVkvWnh2anA5M2RFS21aZGxWQkdmeUFMeWpmTW5MWUovZXh5L09YSnhPUktZTUttSHg4M08zRWsKMWhvb0FwbTZabTIzMjRGME1iVU1ham5Idld2ZjhHZGJTNk5zcHd4L0dkbk1tYVMrdUJMVUhVMkNLbmc1bEIwVAp4OWJITmY0dXlPbTR0dXRmNzhCd1R5V3UreEdrVW0zZ2VZMnkvR1hqdDZyY2l1ajFGNzFDenZzcXFmZThTcDdJCnd6SHdxcTNzVHR5S2lCYTZuYUdEYWpNR1pKYSt4MVZJV204Q2dnRUJBT001ajFZR25Ba0pxR0czQWJSVDIvNUMKaVVxN0loYkswOGZsSGs5a2YwUlVjZWc0ZVlKY3dIRXJVaE4rdWQyLzE3MC81dDYra0JUdTVZOUg3bkpLREtESQpoeEg5SStyamNlVkR0RVNTRkluSXdDQ1lrOHhOUzZ0cHZMV1U5b0pibGFKMlZsalV2NGRFWGVQb0hkREh1Zk9ZClVLa0lsV2E3Uit1QzNEOHF5U1JrQnFLa3ZXZ1RxcFNmTVNkc1ZTeFIzU2Q4SVhFSHFjTDNUNEtMWGtYNEdEamYKMmZOSTFpZkx6ekhJMTN3Tk5IUTVRNU9SUC9pell2QzVzZkx4U2ZIUXJiMXJZVkpKWkI5ZjVBUjRmWFpHSVFsbApjMG8xd0JmZFlqMnZxVDlpR09IQnNSSTlSL2M2RzJQcUt3aFRpSzJVR2lmVFNEUVFuUkF6b2tpQVkrbE8vUjQ9Ci0tLS0tRU5EIFJTQSBQUklWQVRFIEtFWS0tLS0tCg==
================================================
FILE: auth/jwt/token/test/sample_key.pub
================================================
LS0tLS1CRUdJTiBQVUJMSUMgS0VZLS0tLS0KTUlJQ0lqQU5CZ2txaGtpRzl3MEJBUUVGQUFPQ0FnOEFNSUlDQ2dLQ0FnRUE4U2JKUDVYYkVpZFJtNWIyc05wTApHbzJlV2ZVNU9KZTBpemdySHdEOEg3RjZQa1BkL1JsOS8xcE1WN01pTzNMSHd0aEhDMkJSWXFyKzF3RmRvWkNHCkJZckxhWHVYRnFLMHZ1WmhQcUUzYXpqdUlIUXUwQkgvbFhRTXF5RXFGNU1JMnplakM0ek16cjE1T04rZ0U0Sm4KaXBqcC9DZGpPUEFEbUpHK0JKOXFlRS9RUGVtL21VZElUL0xhRjdrUXh5WUs1VktuK05nT1d6TWx6S0FBcENuNwpUVEtCVWU4RlpHNldTWDdMVjBlTEdIc29pYnhsbzlqRGpsWTVvQk9jemZxZU5XSEs1R1hCN1F3cExOaDk0NlB6ClpucW9hcFdVZStZL1JPaUhpekpUY3I1Wk1TTDV3bEVxOGhOaG1obTVOTmUvTytHZ2pCRE5TZlVoMDYrcTRuZ20KYm1OWDVoODM4QmJqUmN5YzM2ZHd6NkpVK2R1b1J0UWhnaVk5MTBwUGY5YmF1WFdxd1VDVWE0cXNIempLUjBMLwpOMVhYQXlsQ0RqeWVnWnp6Y093MkNIOFNrZkZVcmdMclBiRUI5ZWdjR2szOCticEtzM1o2UnI1K3RuRDFCSVBJCkZHTGVJMFVPQzAreGlCdjBvenhJRE9GbldhOVVUR0R4VXg4b2o4VkllUm5XRHE2TWMxaUpwOFV5Y2lCSVRSdHcKNGRabzcweG1mbmVJV3pyM0tTTmFoU29nSmRSMGxhUXpBdVAzYWlXWElNcDJzYzhTYytCbCtMalhtQm94QnJhQgpIaDlLa0pKRWNnQUZ3czJib2pDbEpPWXhvRi9YZ0ZLU3NJbkhEckhWT3lXUEJlM2ZhZEVjNzdiK25iL2V4T3pyCjFFcnhoR2c5akZtcmtPK3M0eEdodjZNQ0F3RUFBUT09Ci0tLS0tRU5EIFBVQkxJQyBLRVktLS0tLQo=
================================================
FILE: auth/jwt/token/token.go
================================================
package token
import (
"errors"
"time"
"go-micro.dev/v5/auth"
)
var (
// ErrNotFound is returned when a token cannot be found.
ErrNotFound = errors.New("token not found")
// ErrEncodingToken is returned when the service encounters an error during encoding.
ErrEncodingToken = errors.New("error encoding the token")
// ErrInvalidToken is returned when the token provided is not valid.
ErrInvalidToken = errors.New("invalid token provided")
)
// Provider generates and inspects tokens.
type Provider interface {
Generate(account *auth.Account, opts ...GenerateOption) (*Token, error)
Inspect(token string) (*auth.Account, error)
String() string
}
type Token struct {
// The actual token
Token string `json:"token"`
// Time of token creation
Created time.Time `json:"created"`
// Time of token expiry
Expiry time.Time `json:"expiry"`
}
================================================
FILE: auth/noop/noop.go
================================================
// Package noop provides a no-op auth implementation for testing and development.
//
// The noop auth provider:
// - Accepts any token (always returns a valid account)
// - Grants all permissions (no actual authorization)
// - Generates tokens (but doesn't verify them)
//
// This is useful for:
// - Local development
// - Testing
// - Prototyping
//
// DO NOT use in production. Use JWT auth or implement a custom auth provider instead.
package noop
import (
"go-micro.dev/v5/auth"
)
// NewAuth returns a new noop auth provider.
//
// The noop provider accepts all tokens and grants all permissions.
// This is for development and testing only - DO NOT use in production.
//
// Example:
//
// authProvider := noop.NewAuth()
// account, _ := authProvider.Generate("user123")
// token, _ := authProvider.Token(auth.WithCredentials(account.ID, account.Secret))
func NewAuth(opts ...auth.Option) auth.Auth {
return auth.NewAuth(opts...)
}
// NewRules returns a new noop rules implementation.
//
// The noop rules implementation grants all access and doesn't enforce any rules.
// This is for development and testing only.
//
// Example:
//
// rules := noop.NewRules()
// err := rules.Verify(account, resource) // Always returns nil
func NewRules() auth.Rules {
return auth.NewRules()
}
================================================
FILE: auth/noop.go
================================================
package auth
import (
"github.com/google/uuid"
)
var (
DefaultAuth = NewAuth()
)
func NewAuth(opts ...Option) Auth {
options := Options{}
for _, o := range opts {
o(&options)
}
return &noop{
opts: options,
}
}
func NewRules() Rules {
return new(noopRules)
}
type noop struct {
opts Options
}
type noopRules struct{}
// String returns the name of the implementation.
func (n *noop) String() string {
return "noop"
}
// Init the auth.
func (n *noop) Init(opts ...Option) {
for _, o := range opts {
o(&n.opts)
}
}
// Options set for auth.
func (n *noop) Options() Options {
return n.opts
}
// Generate a new account.
func (n *noop) Generate(id string, opts ...GenerateOption) (*Account, error) {
options := NewGenerateOptions(opts...)
return &Account{
ID: id,
Secret: options.Secret,
Metadata: options.Metadata,
Scopes: options.Scopes,
Issuer: n.Options().Namespace,
}, nil
}
// Grant access to a resource.
func (n *noopRules) Grant(rule *Rule) error {
return nil
}
// Revoke access to a resource.
func (n *noopRules) Revoke(rule *Rule) error {
return nil
}
// Rules used to verify requests
// Verify an account has access to a resource.
func (n *noopRules) Verify(acc *Account, res *Resource, opts ...VerifyOption) error {
return nil
}
func (n *noopRules) List(opts ...ListOption) ([]*Rule, error) {
return []*Rule{}, nil
}
// Inspect a token.
func (n *noop) Inspect(token string) (*Account, error) {
return &Account{ID: uuid.New().String(), Issuer: n.Options().Namespace}, nil
}
// Token generation using an account id and secret.
func (n *noop) Token(opts ...TokenOption) (*Token, error) {
return &Token{}, nil
}
================================================
FILE: auth/options.go
================================================
package auth
import (
"context"
"time"
"go-micro.dev/v5/logger"
)
func NewOptions(opts ...Option) Options {
options := Options{
Logger: logger.DefaultLogger,
}
for _, o := range opts {
o(&options)
}
return options
}
type Options struct {
// Logger is the underline logger
Logger logger.Logger
// Token is the services token used to authenticate itself
Token *Token
// Namespace the service belongs to
Namespace string
// ID is the services auth ID
ID string
// Secret is used to authenticate the service
Secret string
// PublicKey for decoding JWTs
PublicKey string
// PrivateKey for encoding JWTs
PrivateKey string
// Addrs sets the addresses of auth
Addrs []string
}
type Option func(o *Options)
// Addrs is the auth addresses to use.
func Addrs(addrs ...string) Option {
return func(o *Options) {
o.Addrs = addrs
}
}
// Namespace the service belongs to.
func Namespace(n string) Option {
return func(o *Options) {
o.Namespace = n
}
}
// PublicKey is the JWT public key.
func PublicKey(key string) Option {
return func(o *Options) {
o.PublicKey = key
}
}
// PrivateKey is the JWT private key.
func PrivateKey(key string) Option {
return func(o *Options) {
o.PrivateKey = key
}
}
// WithLogger sets the underline logger.
func WithLogger(l logger.Logger) Option {
return func(o *Options) {
o.Logger = l
}
}
// Credentials sets the auth credentials.
func Credentials(id, secret string) Option {
return func(o *Options) {
o.ID = id
o.Secret = secret
}
}
// ClientToken sets the auth token to use when making requests.
func ClientToken(token *Token) Option {
return func(o *Options) {
o.Token = token
}
}
type GenerateOptions struct {
// Metadata associated with the account
Metadata map[string]string
// Provider of the account, e.g. oauth
Provider string
// Type of the account, e.g. user
Type string
// Secret used to authenticate the account
Secret string
// Scopes the account has access too
Scopes []string
}
type GenerateOption func(o *GenerateOptions)
// WithSecret for the generated account.
func WithSecret(s string) GenerateOption {
return func(o *GenerateOptions) {
o.Secret = s
}
}
// WithType for the generated account.
func WithType(t string) GenerateOption {
return func(o *GenerateOptions) {
o.Type = t
}
}
// WithMetadata for the generated account.
func WithMetadata(md map[string]string) GenerateOption {
return func(o *GenerateOptions) {
o.Metadata = md
}
}
// WithProvider for the generated account.
func WithProvider(p string) GenerateOption {
return func(o *GenerateOptions) {
o.Provider = p
}
}
// WithScopes for the generated account.
func WithScopes(s ...string) GenerateOption {
return func(o *GenerateOptions) {
o.Scopes = s
}
}
// NewGenerateOptions from a slice of options.
func NewGenerateOptions(opts ...GenerateOption) GenerateOptions {
var options GenerateOptions
for _, o := range opts {
o(&options)
}
return options
}
type TokenOptions struct {
// ID for the account
ID string
// Secret for the account
Secret string
// RefreshToken is used to refesh a token
RefreshToken string
// Expiry is the time the token should live for
Expiry time.Duration
}
type TokenOption func(o *TokenOptions)
// WithExpiry for the token.
func WithExpiry(ex time.Duration) TokenOption {
return func(o *TokenOptions) {
o.Expiry = ex
}
}
func WithCredentials(id, secret string) TokenOption {
return func(o *TokenOptions) {
o.ID = id
o.Secret = secret
}
}
func WithToken(rt string) TokenOption {
return func(o *TokenOptions) {
o.RefreshToken = rt
}
}
// NewTokenOptions from a slice of options.
func NewTokenOptions(opts ...TokenOption) TokenOptions {
var options TokenOptions
for _, o := range opts {
o(&options)
}
// set default expiry of token
if options.Expiry == 0 {
options.Expiry = time.Minute
}
return options
}
type VerifyOptions struct {
Context context.Context
}
type VerifyOption func(o *VerifyOptions)
func VerifyContext(ctx context.Context) VerifyOption {
return func(o *VerifyOptions) {
o.Context = ctx
}
}
type ListOptions struct {
Context context.Context
}
type ListOption func(o *ListOptions)
func RulesContext(ctx context.Context) ListOption {
return func(o *ListOptions) {
o.Context = ctx
}
}
================================================
FILE: auth/rules.go
================================================
package auth
import (
"fmt"
"sort"
"strings"
)
// Verify an account has access to a resource using the rules provided. If the account does not have
// access an error will be returned. If there are no rules provided which match the resource, an error
// will be returned.
func Verify(rules []*Rule, acc *Account, res *Resource) error {
// the rule is only to be applied if the type matches the resource or is catch-all (*)
validTypes := []string{"*", res.Type}
// the rule is only to be applied if the name matches the resource or is catch-all (*)
validNames := []string{"*", res.Name}
// rules can have wildcard excludes on endpoints since this can also be a path for web services,
// e.g. /foo/* would include /foo/bar. We also want to check for wildcards and the exact endpoint
validEndpoints := []string{"*", res.Endpoint}
if comps := strings.Split(res.Endpoint, "/"); len(comps) > 1 {
for i := 1; i < len(comps)+1; i++ {
wildcard := fmt.Sprintf("%v/*", strings.Join(comps[0:i], "/"))
validEndpoints = append(validEndpoints, wildcard)
}
}
// filter the rules to the ones which match the criteria above
filteredRules := make([]*Rule, 0)
for _, rule := range rules {
if !include(validTypes, rule.Resource.Type) {
continue
}
if !include(validNames, rule.Resource.Name) {
continue
}
if !include(validEndpoints, rule.Resource.Endpoint) {
continue
}
filteredRules = append(filteredRules, rule)
}
// sort the filtered rules by priority, highest to lowest
sort.SliceStable(filteredRules, func(i, j int) bool {
return filteredRules[i].Priority > filteredRules[j].Priority
})
// loop through the rules and check for a rule which applies to this account
for _, rule := range filteredRules {
// a blank scope indicates the rule applies to everyone, even nil accounts
if rule.Scope == ScopePublic && rule.Access == AccessDenied {
return ErrForbidden
} else if rule.Scope == ScopePublic && rule.Access == AccessGranted {
return nil
}
// all further checks require an account
if acc == nil {
continue
}
// this rule applies to any account
if rule.Scope == ScopeAccount && rule.Access == AccessDenied {
return ErrForbidden
} else if rule.Scope == ScopeAccount && rule.Access == AccessGranted {
return nil
}
// if the account has the necessary scope
if include(acc.Scopes, rule.Scope) && rule.Access == AccessDenied {
return ErrForbidden
} else if include(acc.Scopes, rule.Scope) && rule.Access == AccessGranted {
return nil
}
}
// if no rules matched then return forbidden
return ErrForbidden
}
// include is a helper function which checks to see if the slice contains the value. includes is
// not case sensitive.
func include(slice []string, val string) bool {
for _, s := range slice {
if strings.EqualFold(s, val) {
return true
}
}
return false
}
================================================
FILE: auth/rules_test.go
================================================
package auth
import (
"testing"
)
func TestVerify(t *testing.T) {
srvResource := &Resource{
Type: "service",
Name: "go.micro.service.foo",
Endpoint: "Foo.Bar",
}
webResource := &Resource{
Type: "service",
Name: "go.micro.web.foo",
Endpoint: "/foo/bar",
}
catchallResource := &Resource{
Type: "*",
Name: "*",
Endpoint: "*",
}
tt := []struct {
Name string
Rules []*Rule
Account *Account
Resource *Resource
Error error
}{
{
Name: "NoRules",
Rules: []*Rule{},
Account: nil,
Resource: srvResource,
Error: ErrForbidden,
},
{
Name: "CatchallPublicAccount",
Account: &Account{},
Resource: srvResource,
Rules: []*Rule{
{
Scope: "",
Resource: catchallResource,
},
},
},
{
Name: "CatchallPublicNoAccount",
Resource: srvResource,
Rules: []*Rule{
{
Scope: "",
Resource: catchallResource,
},
},
},
{
Name: "CatchallPrivateAccount",
Account: &Account{},
Resource: srvResource,
Rules: []*Rule{
{
Scope: "*",
Resource: catchallResource,
},
},
},
{
Name: "CatchallPrivateNoAccount",
Resource: srvResource,
Rules: []*Rule{
{
Scope: "*",
Resource: catchallResource,
},
},
Error: ErrForbidden,
},
{
Name: "CatchallServiceRuleMatch",
Resource: srvResource,
Account: &Account{},
Rules: []*Rule{
{
Scope: "*",
Resource: &Resource{
Type: srvResource.Type,
Name: srvResource.Name,
Endpoint: "*",
},
},
},
},
{
Name: "CatchallServiceRuleNoMatch",
Resource: srvResource,
Account: &Account{},
Rules: []*Rule{
{
Scope: "*",
Resource: &Resource{
Type: srvResource.Type,
Name: "wrongname",
Endpoint: "*",
},
},
},
Error: ErrForbidden,
},
{
Name: "ExactRuleValidScope",
Resource: srvResource,
Account: &Account{
Scopes: []string{"neededscope"},
},
Rules: []*Rule{
{
Scope: "neededscope",
Resource: srvResource,
},
},
},
{
Name: "ExactRuleInvalidScope",
Resource: srvResource,
Account: &Account{
Scopes: []string{"neededscope"},
},
Rules: []*Rule{
{
Scope: "invalidscope",
Resource: srvResource,
},
},
Error: ErrForbidden,
},
{
Name: "CatchallDenyWithAccount",
Resource: srvResource,
Account: &Account{},
Rules: []*Rule{
{
Scope: "*",
Resource: catchallResource,
Access: AccessDenied,
},
},
Error: ErrForbidden,
},
{
Name: "CatchallDenyWithNoAccount",
Resource: srvResource,
Account: &Account{},
Rules: []*Rule{
{
Scope: "*",
Resource: catchallResource,
Access: AccessDenied,
},
},
Error: ErrForbidden,
},
{
Name: "RulePriorityGrantFirst",
Resource: srvResource,
Account: &Account{},
Rules: []*Rule{
{
Scope: "*",
Resource: catchallResource,
Access: AccessGranted,
Priority: 1,
},
{
Scope: "*",
Resource: catchallResource,
Access: AccessDenied,
Priority: 0,
},
},
},
{
Name: "RulePriorityDenyFirst",
Resource: srvResource,
Account: &Account{},
Rules: []*Rule{
{
Scope: "*",
Resource: catchallResource,
Access: AccessGranted,
Priority: 0,
},
{
Scope: "*",
Resource: catchallResource,
Access: AccessDenied,
Priority: 1,
},
},
Error: ErrForbidden,
},
{
Name: "WebExactEndpointValid",
Resource: webResource,
Account: &Account{},
Rules: []*Rule{
{
Scope: "*",
Resource: webResource,
},
},
},
{
Name: "WebExactEndpointInalid",
Resource: webResource,
Account: &Account{},
Rules: []*Rule{
{
Scope: "*",
Resource: &Resource{
Type: webResource.Type,
Name: webResource.Name,
Endpoint: "invalidendpoint",
},
},
},
Error: ErrForbidden,
},
{
Name: "WebWildcardEndpoint",
Resource: webResource,
Account: &Account{},
Rules: []*Rule{
{
Scope: "*",
Resource: &Resource{
Type: webResource.Type,
Name: webResource.Name,
Endpoint: "*",
},
},
},
},
{
Name: "WebWildcardPathEndpointValid",
Resource: webResource,
Account: &Account{},
Rules: []*Rule{
{
Scope: "*",
Resource: &Resource{
Type: webResource.Type,
Name: webResource.Name,
Endpoint: "/foo/*",
},
},
},
},
{
Name: "WebWildcardPathEndpointInvalid",
Resource: webResource,
Account: &Account{},
Rules: []*Rule{
{
Scope: "*",
Resource: &Resource{
Type: webResource.Type,
Name: webResource.Name,
Endpoint: "/bar/*",
},
},
},
Error: ErrForbidden,
},
}
for _, tc := range tt {
t.Run(tc.Name, func(t *testing.T) {
if err := Verify(tc.Rules, tc.Account, tc.Resource); err != tc.Error {
t.Errorf("Expected %v but got %v", tc.Error, err)
}
})
}
}
================================================
FILE: broker/broker.go
================================================
// Package broker is an interface used for asynchronous messaging
package broker
// Broker is an interface used for asynchronous messaging.
type Broker interface {
Init(...Option) error
Options() Options
Address() string
Connect() error
Disconnect() error
Publish(topic string, m *Message, opts ...PublishOption) error
Subscribe(topic string, h Handler, opts ...SubscribeOption) (Subscriber, error)
String() string
}
// Handler is used to process messages via a subscription of a topic.
// The handler is passed a publication interface which contains the
// message and optional Ack method to acknowledge receipt of the message.
type Handler func(Event) error
// Message is a message send/received from the broker.
type Message struct {
Header map[string]string
Body []byte
}
// Event is given to a subscription handler for processing.
type Event interface {
Topic() string
Message() *Message
Ack() error
Error() error
}
// Subscriber is a convenience return type for the Subscribe method.
type Subscriber interface {
Options() SubscribeOptions
Topic() string
Unsubscribe() error
}
var (
// DefaultBroker is the default Broker.
DefaultBroker = NewHttpBroker()
)
func Init(opts ...Option) error {
return DefaultBroker.Init(opts...)
}
func Connect() error {
return DefaultBroker.Connect()
}
func Disconnect() error {
return DefaultBroker.Disconnect()
}
func Publish(topic string, msg *Message, opts ...PublishOption) error {
return DefaultBroker.Publish(topic, msg, opts...)
}
func Subscribe(topic string, handler Handler, opts ...SubscribeOption) (Subscriber, error) {
return DefaultBroker.Subscribe(topic, handler, opts...)
}
// String returns the name of the Broker.
func String() string {
return DefaultBroker.String()
}
================================================
FILE: broker/http.go
================================================
package broker
import (
"bytes"
"crypto/tls"
"errors"
"fmt"
"io"
"math/rand"
"net"
"net/http"
"net/url"
"runtime"
"sync"
"time"
"github.com/google/uuid"
"go-micro.dev/v5/codec/json"
merr "go-micro.dev/v5/errors"
"go-micro.dev/v5/registry"
"go-micro.dev/v5/registry/cache"
"go-micro.dev/v5/transport/headers"
maddr "go-micro.dev/v5/internal/util/addr"
mnet "go-micro.dev/v5/internal/util/net"
mls "go-micro.dev/v5/internal/util/tls"
"golang.org/x/net/http2"
)
// HTTP Broker is a point to point async broker.
type httpBroker struct {
opts Options
r registry.Registry
mux *http.ServeMux
c *http.Client
subscribers map[string][]*httpSubscriber
exit chan chan error
inbox map[string][][]byte
id string
address string
sync.RWMutex
// offline message inbox
mtx sync.RWMutex
running bool
}
type httpSubscriber struct {
opts SubscribeOptions
fn Handler
svc *registry.Service
hb *httpBroker
id string
topic string
}
type httpEvent struct {
err error
m *Message
t string
}
var (
DefaultPath = "/"
DefaultAddress = "127.0.0.1:0"
serviceName = "micro.http.broker"
broadcastVersion = "ff.http.broadcast"
registerTTL = time.Minute
registerInterval = time.Second * 30
)
func init() {
}
func newTransport(config *tls.Config) *http.Transport {
if config == nil {
// Use environment-based config - secure by default
config = mls.Config()
}
dialTLS := func(network string, addr string) (net.Conn, error) {
return tls.Dial(network, addr, config)
}
t := &http.Transport{
Proxy: http.ProxyFromEnvironment,
Dial: (&net.Dialer{
Timeout: 30 * time.Second,
KeepAlive: 30 * time.Second,
}).Dial,
TLSHandshakeTimeout: 10 * time.Second,
DialTLS: dialTLS,
}
runtime.SetFinalizer(&t, func(tr **http.Transport) {
(*tr).CloseIdleConnections()
})
// setup http2
http2.ConfigureTransport(t)
return t
}
func newHttpBroker(opts ...Option) Broker {
options := *NewOptions(opts...)
options.Registry = registry.DefaultRegistry
options.Codec = json.Marshaler{}
for _, o := range opts {
o(&options)
}
// set address
addr := DefaultAddress
if len(options.Addrs) > 0 && len(options.Addrs[0]) > 0 {
addr = options.Addrs[0]
}
h := &httpBroker{
id: uuid.New().String(),
address: addr,
opts: options,
r: options.Registry,
c: &http.Client{Transport: newTransport(options.TLSConfig)},
subscribers: make(map[string][]*httpSubscriber),
exit: make(chan chan error),
mux: http.NewServeMux(),
inbox: make(map[string][][]byte),
}
// specify the message handler
h.mux.Handle(DefaultPath, h)
// get optional handlers
if h.opts.Context != nil {
handlers, ok := h.opts.Context.Value("http_handlers").(map[string]http.Handler)
if ok {
for pattern, handler := range handlers {
h.mux.Handle(pattern, handler)
}
}
}
return h
}
func (h *httpEvent) Ack() error {
return nil
}
func (h *httpEvent) Error() error {
return h.err
}
func (h *httpEvent) Message() *Message {
return h.m
}
func (h *httpEvent) Topic() string {
return h.t
}
func (h *httpSubscriber) Options() SubscribeOptions {
return h.opts
}
func (h *httpSubscriber) Topic() string {
return h.topic
}
func (h *httpSubscriber) Unsubscribe() error {
return h.hb.unsubscribe(h)
}
func (h *httpBroker) saveMessage(topic string, msg []byte) {
h.mtx.Lock()
defer h.mtx.Unlock()
// get messages
c := h.inbox[topic]
// save message
c = append(c, msg)
// max length 64
if len(c) > 64 {
c = c[:64]
}
// save inbox
h.inbox[topic] = c
}
func (h *httpBroker) getMessage(topic string, num int) [][]byte {
h.mtx.Lock()
defer h.mtx.Unlock()
// get messages
c, ok := h.inbox[topic]
if !ok {
return nil
}
// more message than requests
if len(c) >= num {
msg := c[:num]
h.inbox[topic] = c[num:]
return msg
}
// reset inbox
h.inbox[topic] = nil
// return all messages
return c
}
func (h *httpBroker) subscribe(s *httpSubscriber) error {
h.Lock()
defer h.Unlock()
if err := h.r.Register(s.svc, registry.RegisterTTL(registerTTL)); err != nil {
return err
}
h.subscribers[s.topic] = append(h.subscribers[s.topic], s)
return nil
}
func (h *httpBroker) unsubscribe(s *httpSubscriber) error {
h.Lock()
defer h.Unlock()
//nolint:prealloc
var subscribers []*httpSubscriber
// look for subscriber
for _, sub := range h.subscribers[s.topic] {
// deregister and skip forward
if sub == s {
_ = h.r.Deregister(sub.svc)
continue
}
// keep subscriber
subscribers = append(subscribers, sub)
}
// set subscribers
h.subscribers[s.topic] = subscribers
return nil
}
func (h *httpBroker) run(l net.Listener) {
t := time.NewTicker(registerInterval)
defer t.Stop()
for {
select {
// heartbeat for each subscriber
case <-t.C:
h.RLock()
for _, subs := range h.subscribers {
for _, sub := range subs {
_ = h.r.Register(sub.svc, registry.RegisterTTL(registerTTL))
}
}
h.RUnlock()
// received exit signal
case ch := <-h.exit:
ch <- l.Close()
h.RLock()
for _, subs := range h.subscribers {
for _, sub := range subs {
_ = h.r.Deregister(sub.svc)
}
}
h.RUnlock()
return
}
}
}
func (h *httpBroker) ServeHTTP(w http.ResponseWriter, req *http.Request) {
if req.Method != "POST" {
err := merr.BadRequest("go.micro.broker", "Method not allowed")
http.Error(w, err.Error(), http.StatusMethodNotAllowed)
return
}
defer req.Body.Close()
req.ParseForm()
b, err := io.ReadAll(req.Body)
if err != nil {
errr := merr.InternalServerError("go.micro.broker", "Error reading request body: %v", err)
w.WriteHeader(500)
w.Write([]byte(errr.Error()))
return
}
var m *Message
if err = h.opts.Codec.Unmarshal(b, &m); err != nil {
errr := merr.InternalServerError("go.micro.broker", "Error parsing request body: %v", err)
w.WriteHeader(500)
w.Write([]byte(errr.Error()))
return
}
topic := m.Header[headers.Message]
// delete(m.Header, ":topic")
if len(topic) == 0 {
errr := merr.InternalServerError("go.micro.broker", "Topic not found")
w.WriteHeader(500)
w.Write([]byte(errr.Error()))
return
}
p := &httpEvent{m: m, t: topic}
id := req.Form.Get("id")
//nolint:prealloc
var subs []Handler
h.RLock()
for _, subscriber := range h.subscribers[topic] {
if id != subscriber.id {
continue
}
subs = append(subs, subscriber.fn)
}
h.RUnlock()
// execute the handler
for _, fn := range subs {
p.err = fn(p)
}
}
func (h *httpBroker) Address() string {
h.RLock()
defer h.RUnlock()
return h.address
}
func (h *httpBroker) Connect() error {
h.RLock()
if h.running {
h.RUnlock()
return nil
}
h.RUnlock()
h.Lock()
defer h.Unlock()
var l net.Listener
var err error
if h.opts.Secure || h.opts.TLSConfig != nil {
config := h.opts.TLSConfig
fn := func(addr string) (net.Listener, error) {
if config == nil {
hosts := []string{addr}
// check if its a valid host:port
if host, _, err := net.SplitHostPort(addr); err == nil {
if len(host) == 0 {
hosts = maddr.IPs()
} else {
hosts = []string{host}
}
}
// generate a certificate
cert, err := mls.Certificate(hosts...)
if err != nil {
return nil, err
}
config = &tls.Config{Certificates: []tls.Certificate{cert}}
}
return tls.Listen("tcp", addr, config)
}
l, err = mnet.Listen(h.address, fn)
} else {
fn := func(addr string) (net.Listener, error) {
return net.Listen("tcp", addr)
}
l, err = mnet.Listen(h.address, fn)
}
if err != nil {
return err
}
addr := h.address
h.address = l.Addr().String()
go http.Serve(l, h.mux)
go func() {
h.run(l)
h.Lock()
h.opts.Addrs = []string{addr}
h.address = addr
h.Unlock()
}()
// get registry
reg := h.opts.Registry
if reg == nil {
reg = registry.DefaultRegistry
}
// set cache
h.r = cache.New(reg)
// set running
h.running = true
return nil
}
func (h *httpBroker) Disconnect() error {
h.RLock()
if !h.running {
h.RUnlock()
return nil
}
h.RUnlock()
h.Lock()
defer h.Unlock()
// stop cache
rc, ok := h.r.(cache.Cache)
if ok {
rc.Stop()
}
// exit and return err
ch := make(chan error)
h.exit <- ch
err := <-ch
// set not running
h.running = false
return err
}
func (h *httpBroker) Init(opts ...Option) error {
h.RLock()
if h.running {
h.RUnlock()
return errors.New("cannot init while connected")
}
h.RUnlock()
h.Lock()
defer h.Unlock()
for _, o := range opts {
o(&h.opts)
}
if len(h.opts.Addrs) > 0 && len(h.opts.Addrs[0]) > 0 {
h.address = h.opts.Addrs[0]
}
if len(h.id) == 0 {
h.id = "go.micro.http.broker-" + uuid.New().String()
}
// get registry
reg := h.opts.Registry
if reg == nil {
reg = registry.DefaultRegistry
}
// get cache
if rc, ok := h.r.(cache.Cache); ok {
rc.Stop()
}
// set registry
h.r = cache.New(reg)
// reconfigure tls config
if c := h.opts.TLSConfig; c != nil {
h.c = &http.Client{
Transport: newTransport(c),
}
}
return nil
}
func (h *httpBroker) Options() Options {
return h.opts
}
func (h *httpBroker) Publish(topic string, msg *Message, opts ...PublishOption) error {
// create the message first
m := &Message{
Header: make(map[string]string),
Body: msg.Body,
}
for k, v := range msg.Header {
m.Header[k] = v
}
m.Header[headers.Message] = topic
// encode the message
b, err := h.opts.Codec.Marshal(m)
if err != nil {
return err
}
// save the message
h.saveMessage(topic, b)
// now attempt to get the service
h.RLock()
s, err := h.r.GetService(serviceName)
if err != nil {
h.RUnlock()
return err
}
h.RUnlock()
pub := func(node *registry.Node, t string, b []byte) error {
scheme := "http"
// check if secure is added in metadata
if node.Metadata["secure"] == "true" {
scheme = "https"
}
vals := url.Values{}
vals.Add("id", node.Id)
uri := fmt.Sprintf("%s://%s%s?%s", scheme, node.Address, DefaultPath, vals.Encode())
r, err := h.c.Post(uri, "application/json", bytes.NewReader(b))
if err != nil {
return err
}
// discard response body
io.Copy(io.Discard, r.Body)
r.Body.Close()
return nil
}
srv := func(s []*registry.Service, b []byte) {
for _, service := range s {
var nodes []*registry.Node
for _, node := range service.Nodes {
// only use nodes tagged with broker http
if node.Metadata["broker"] != "http" {
continue
}
// look for nodes for the topic
if node.Metadata["topic"] != topic {
continue
}
nodes = append(nodes, node)
}
// only process if we have nodes
if len(nodes) == 0 {
continue
}
switch service.Version {
// broadcast version means broadcast to all nodes
case broadcastVersion:
var success bool
// publish to all nodes
for _, node := range nodes {
// publish async
if err := pub(node, topic, b); err == nil {
success = true
}
}
// save if it failed to publish at least once
if !success {
h.saveMessage(topic, b)
}
default:
// select node to publish to
node := nodes[rand.Int()%len(nodes)]
// publish async to one node
if err := pub(node, topic, b); err != nil {
// if failed save it
h.saveMessage(topic, b)
}
}
}
}
// do the rest async
go func() {
// get a third of the backlog
messages := h.getMessage(topic, 8)
delay := (len(messages) > 1)
// publish all the messages
for _, msg := range messages {
// serialize here
srv(s, msg)
// sending a backlog of messages
if delay {
time.Sleep(time.Millisecond * 100)
}
}
}()
return nil
}
func (h *httpBroker) Subscribe(topic string, handler Handler, opts ...SubscribeOption) (Subscriber, error) {
var err error
var host, port string
options := NewSubscribeOptions(opts...)
// parse address for host, port
host, port, err = net.SplitHostPort(h.Address())
if err != nil {
return nil, err
}
addr, err := maddr.Extract(host)
if err != nil {
return nil, err
}
var secure bool
if h.opts.Secure || h.opts.TLSConfig != nil {
secure = true
}
// register service
node := ®istry.Node{
Id: topic + "-" + h.id,
Address: mnet.HostPort(addr, port),
Metadata: map[string]string{
"secure": fmt.Sprintf("%t", secure),
"broker": "http",
"topic": topic,
},
}
// check for queue group or broadcast queue
version := options.Queue
if len(version) == 0 {
version = broadcastVersion
}
service := ®istry.Service{
Name: serviceName,
Version: version,
Nodes: []*registry.Node{node},
}
// generate subscriber
subscriber := &httpSubscriber{
opts: options,
hb: h,
id: node.Id,
topic: topic,
fn: handler,
svc: service,
}
// subscribe now
if err := h.subscribe(subscriber); err != nil {
return nil, err
}
// return the subscriber
return subscriber, nil
}
func (h *httpBroker) String() string {
return "http"
}
// NewHttpBroker returns a new http broker.
func NewHttpBroker(opts ...Option) Broker {
return newHttpBroker(opts...)
}
================================================
FILE: broker/http_test.go
================================================
package broker_test
import (
"sync"
"testing"
"time"
"github.com/google/uuid"
"go-micro.dev/v5/broker"
"go-micro.dev/v5/registry"
)
var (
// mock data.
testData = map[string][]*registry.Service{
"foo": {
{
Name: "foo",
Version: "1.0.0",
Nodes: []*registry.Node{
{
Id: "foo-1.0.0-123",
Address: "localhost:9999",
},
{
Id: "foo-1.0.0-321",
Address: "localhost:9999",
},
},
},
{
Name: "foo",
Version: "1.0.1",
Nodes: []*registry.Node{
{
Id: "foo-1.0.1-321",
Address: "localhost:6666",
},
},
},
{
Name: "foo",
Version: "1.0.3",
Nodes: []*registry.Node{
{
Id: "foo-1.0.3-345",
Address: "localhost:8888",
},
},
},
},
}
)
func newTestRegistry() registry.Registry {
return registry.NewMemoryRegistry(registry.Services(testData))
}
func sub(b *testing.B, c int) {
b.StopTimer()
m := newTestRegistry()
brker := broker.NewHttpBroker(broker.Registry(m))
topic := uuid.New().String()
if err := brker.Init(); err != nil {
b.Fatalf("Unexpected init error: %v", err)
}
if err := brker.Connect(); err != nil {
b.Fatalf("Unexpected connect error: %v", err)
}
msg := &broker.Message{
Header: map[string]string{
"Content-Type": "application/json",
},
Body: []byte(`{"message": "Hello World"}`),
}
var subs []broker.Subscriber
done := make(chan bool, c)
for i := 0; i < c; i++ {
sub, err := brker.Subscribe(topic, func(p broker.Event) error {
done <- true
m := p.Message()
if string(m.Body) != string(msg.Body) {
b.Fatalf("Unexpected msg %s, expected %s", string(m.Body), string(msg.Body))
}
return nil
}, broker.Queue("shared"))
if err != nil {
b.Fatalf("Unexpected subscribe error: %v", err)
}
subs = append(subs, sub)
}
for i := 0; i < b.N; i++ {
b.StartTimer()
if err := brker.Publish(topic, msg); err != nil {
b.Fatalf("Unexpected publish error: %v", err)
}
<-done
b.StopTimer()
}
for _, sub := range subs {
if err := sub.Unsubscribe(); err != nil {
b.Fatalf("Unexpected unsubscribe error: %v", err)
}
}
if err := brker.Disconnect(); err != nil {
b.Fatalf("Unexpected disconnect error: %v", err)
}
}
func pub(b *testing.B, c int) {
b.StopTimer()
m := newTestRegistry()
brk := broker.NewHttpBroker(broker.Registry(m))
topic := uuid.New().String()
if err := brk.Init(); err != nil {
b.Fatalf("Unexpected init error: %v", err)
}
if err := brk.Connect(); err != nil {
b.Fatalf("Unexpected connect error: %v", err)
}
msg := &broker.Message{
Header: map[string]string{
"Content-Type": "application/json",
},
Body: []byte(`{"message": "Hello World"}`),
}
done := make(chan bool, c*4)
sub, err := brk.Subscribe(topic, func(p broker.Event) error {
done <- true
m := p.Message()
if string(m.Body) != string(msg.Body) {
b.Fatalf("Unexpected msg %s, expected %s", string(m.Body), string(msg.Body))
}
return nil
}, broker.Queue("shared"))
if err != nil {
b.Fatalf("Unexpected subscribe error: %v", err)
}
var wg sync.WaitGroup
ch := make(chan int, c*4)
b.StartTimer()
for i := 0; i < c; i++ {
go func() {
for range ch {
if err := brk.Publish(topic, msg); err != nil {
b.Fatalf("Unexpected publish error: %v", err)
}
select {
case <-done:
case <-time.After(time.Second):
}
wg.Done()
}
}()
}
for i := 0; i < b.N; i++ {
wg.Add(1)
ch <- i
}
wg.Wait()
b.StopTimer()
sub.Unsubscribe()
close(ch)
close(done)
if err := brk.Disconnect(); err != nil {
b.Fatalf("Unexpected disconnect error: %v", err)
}
}
func TestBroker(t *testing.T) {
m := newTestRegistry()
b := broker.NewHttpBroker(broker.Registry(m))
if err := b.Init(); err != nil {
t.Fatalf("Unexpected init error: %v", err)
}
if err := b.Connect(); err != nil {
t.Fatalf("Unexpected connect error: %v", err)
}
msg := &broker.Message{
Header: map[string]string{
"Content-Type": "application/json",
},
Body: []byte(`{"message": "Hello World"}`),
}
done := make(chan bool)
sub, err := b.Subscribe("test", func(p broker.Event) error {
m := p.Message()
if string(m.Body) != string(msg.Body) {
t.Fatalf("Unexpected msg %s, expected %s", string(m.Body), string(msg.Body))
}
close(done)
return nil
})
if err != nil {
t.Fatalf("Unexpected subscribe error: %v", err)
}
if err := b.Publish("test", msg); err != nil {
t.Fatalf("Unexpected publish error: %v", err)
}
<-done
if err := sub.Unsubscribe(); err != nil {
t.Fatalf("Unexpected unsubscribe error: %v", err)
}
if err := b.Disconnect(); err != nil {
t.Fatalf("Unexpected disconnect error: %v", err)
}
}
func TestConcurrentSubBroker(t *testing.T) {
m := newTestRegistry()
b := broker.NewHttpBroker(broker.Registry(m))
if err := b.Init(); err != nil {
t.Fatalf("Unexpected init error: %v", err)
}
if err := b.Connect(); err != nil {
t.Fatalf("Unexpected connect error: %v", err)
}
msg := &broker.Message{
Header: map[string]string{
"Content-Type": "application/json",
},
Body: []byte(`{"message": "Hello World"}`),
}
var subs []broker.Subscriber
var wg sync.WaitGroup
for i := 0; i < 10; i++ {
sub, err := b.Subscribe("test", func(p broker.Event) error {
defer wg.Done()
m := p.Message()
if string(m.Body) != string(msg.Body) {
t.Fatalf("Unexpected msg %s, expected %s", string(m.Body), string(msg.Body))
}
return nil
})
if err != nil {
t.Fatalf("Unexpected subscribe error: %v", err)
}
wg.Add(1)
subs = append(subs, sub)
}
if err := b.Publish("test", msg); err != nil {
t.Fatalf("Unexpected publish error: %v", err)
}
wg.Wait()
for _, sub := range subs {
if err := sub.Unsubscribe(); err != nil {
t.Fatalf("Unexpected unsubscribe error: %v", err)
}
}
if err := b.Disconnect(); err != nil {
t.Fatalf("Unexpected disconnect error: %v", err)
}
}
func TestConcurrentPubBroker(t *testing.T) {
m := newTestRegistry()
b := broker.NewHttpBroker(broker.Registry(m))
if err := b.Init(); err != nil {
t.Fatalf("Unexpected init error: %v", err)
}
if err := b.Connect(); err != nil {
t.Fatalf("Unexpected connect error: %v", err)
}
msg := &broker.Message{
Header: map[string]string{
"Content-Type": "application/json",
},
Body: []byte(`{"message": "Hello World"}`),
}
var wg sync.WaitGroup
sub, err := b.Subscribe("test", func(p broker.Event) error {
defer wg.Done()
m := p.Message()
if string(m.Body) != string(msg.Body) {
t.Fatalf("Unexpected msg %s, expected %s", string(m.Body), string(msg.Body))
}
return nil
})
if err != nil {
t.Fatalf("Unexpected subscribe error: %v", err)
}
for i := 0; i < 10; i++ {
wg.Add(1)
if err := b.Publish("test", msg); err != nil {
t.Fatalf("Unexpected publish error: %v", err)
}
}
wg.Wait()
if err := sub.Unsubscribe(); err != nil {
t.Fatalf("Unexpected unsubscribe error: %v", err)
}
if err := b.Disconnect(); err != nil {
t.Fatalf("Unexpected disconnect error: %v", err)
}
}
func BenchmarkSub1(b *testing.B) {
sub(b, 1)
}
func BenchmarkSub8(b *testing.B) {
sub(b, 8)
}
func BenchmarkSub32(b *testing.B) {
sub(b, 32)
}
func BenchmarkPub1(b *testing.B) {
pub(b, 1)
}
func BenchmarkPub8(b *testing.B) {
pub(b, 8)
}
func BenchmarkPub32(b *testing.B) {
pub(b, 32)
}
================================================
FILE: broker/memory.go
================================================
// Package memory provides a memory broker
package broker
import (
"errors"
"math/rand"
"sync"
"github.com/google/uuid"
log "go-micro.dev/v5/logger"
maddr "go-micro.dev/v5/internal/util/addr"
mnet "go-micro.dev/v5/internal/util/net"
)
type memoryBroker struct {
opts *Options
Subscribers map[string][]*memorySubscriber
addr string
sync.RWMutex
connected bool
}
type memoryEvent struct {
err error
message interface{}
opts *Options
topic string
}
type memorySubscriber struct {
opts SubscribeOptions
exit chan bool
handler Handler
id string
topic string
}
func (m *memoryBroker) Options() Options {
return *m.opts
}
func (m *memoryBroker) Address() string {
return m.addr
}
func (m *memoryBroker) Connect() error {
m.Lock()
defer m.Unlock()
if m.connected {
return nil
}
// use 127.0.0.1 to avoid scan of all network interfaces
addr, err := maddr.Extract("127.0.0.1")
if err != nil {
return err
}
i := rand.Intn(20000)
// set addr with port
addr = mnet.HostPort(addr, 10000+i)
m.addr = addr
m.connected = true
return nil
}
func (m *memoryBroker) Disconnect() error {
m.Lock()
defer m.Unlock()
if !m.connected {
return nil
}
m.connected = false
return nil
}
func (m *memoryBroker) Init(opts ...Option) error {
for _, o := range opts {
o(m.opts)
}
return nil
}
func (m *memoryBroker) Publish(topic string, msg *Message, opts ...PublishOption) error {
m.RLock()
if !m.connected {
m.RUnlock()
return errors.New("not connected")
}
subs, ok := m.Subscribers[topic]
m.RUnlock()
if !ok {
return nil
}
var v interface{}
if m.opts.Codec != nil {
buf, err := m.opts.Codec.Marshal(msg)
if err != nil {
return err
}
v = buf
} else {
v = msg
}
p := &memoryEvent{
topic: topic,
message: v,
opts: m.opts,
}
for _, sub := range subs {
if err := sub.handler(p); err != nil {
p.err = err
if eh := m.opts.ErrorHandler; eh != nil {
eh(p)
continue
}
return err
}
}
return nil
}
func (m *memoryBroker) Subscribe(topic string, handler Handler, opts ...SubscribeOption) (Subscriber, error) {
m.RLock()
if !m.connected {
m.RUnlock()
return nil, errors.New("not connected")
}
m.RUnlock()
var options SubscribeOptions
for _, o := range opts {
o(&options)
}
sub := &memorySubscriber{
exit: make(chan bool, 1),
id: uuid.New().String(),
topic: topic,
handler: handler,
opts: options,
}
m.Lock()
m.Subscribers[topic] = append(m.Subscribers[topic], sub)
m.Unlock()
go func() {
<-sub.exit
m.Lock()
var newSubscribers []*memorySubscriber
for _, sb := range m.Subscribers[topic] {
if sb.id == sub.id {
continue
}
newSubscribers = append(newSubscribers, sb)
}
m.Subscribers[topic] = newSubscribers
m.Unlock()
}()
return sub, nil
}
func (m *memoryBroker) String() string {
return "memory"
}
func (m *memoryEvent) Topic() string {
return m.topic
}
func (m *memoryEvent) Message() *Message {
switch v := m.message.(type) {
case *Message:
return v
case []byte:
msg := &Message{}
if err := m.opts.Codec.Unmarshal(v, msg); err != nil {
m.opts.Logger.Logf(log.ErrorLevel, "[memory]: failed to unmarshal: %v\n", err)
return nil
}
return msg
}
return nil
}
func (m *memoryEvent) Ack() error {
return nil
}
func (m *memoryEvent) Error() error {
return m.err
}
func (m *memorySubscriber) Options() SubscribeOptions {
return m.opts
}
func (m *memorySubscriber) Topic() string {
return m.topic
}
func (m *memorySubscriber) Unsubscribe() error {
m.exit <- true
return nil
}
func NewMemoryBroker(opts ...Option) Broker {
options := NewOptions(opts...)
return &memoryBroker{
opts: options,
Subscribers: make(map[string][]*memorySubscriber),
}
}
================================================
FILE: broker/memory_test.go
================================================
package broker_test
import (
"fmt"
"testing"
"go-micro.dev/v5/broker"
)
func TestMemoryBroker(t *testing.T) {
b := broker.NewMemoryBroker()
if err := b.Connect(); err != nil {
t.Fatalf("Unexpected connect error %v", err)
}
topic := "test"
count := 10
fn := func(p broker.Event) error {
return nil
}
sub, err := b.Subscribe(topic, fn)
if err != nil {
t.Fatalf("Unexpected error subscribing %v", err)
}
for i := 0; i < count; i++ {
message := &broker.Message{
Header: map[string]string{
"foo": "bar",
"id": fmt.Sprintf("%d", i),
},
Body: []byte(`hello world`),
}
if err := b.Publish(topic, message); err != nil {
t.Fatalf("Unexpected error publishing %d", i)
}
}
if err := sub.Unsubscribe(); err != nil {
t.Fatalf("Unexpected error unsubscribing from %s: %v", topic, err)
}
if err := b.Disconnect(); err != nil {
t.Fatalf("Unexpected connect error %v", err)
}
}
================================================
FILE: broker/nats/context.go
================================================
package nats
import (
"context"
"go-micro.dev/v5/broker"
)
// setBrokerOption returns a function to setup a context with given value.
func setBrokerOption(k, v interface{}) broker.Option {
return func(o *broker.Options) {
if o.Context == nil {
o.Context = context.Background()
}
o.Context = context.WithValue(o.Context, k, v)
}
}
================================================
FILE: broker/nats/nats.go
================================================
// Package nats provides a NATS broker
package nats
import (
"context"
"errors"
"strings"
"sync"
"time"
natsp "github.com/nats-io/nats.go"
"go-micro.dev/v5/broker"
"go-micro.dev/v5/codec/json"
"go-micro.dev/v5/logger"
"go-micro.dev/v5/registry"
)
type natsBroker struct {
sync.Once
sync.RWMutex
// indicate if we're connected
connected bool
addrs []string
conn *natsp.Conn // single connection (used when pool is disabled)
pool *connectionPool // connection pool (used when pooling is enabled)
opts broker.Options
nopts natsp.Options
// pool configuration
poolSize int
poolIdleTimeout time.Duration
// should we drain the connection
drain bool
closeCh chan (error)
}
type subscriber struct {
s *natsp.Subscription
opts broker.SubscribeOptions
}
type publication struct {
t string
err error
m *broker.Message
}
func (p *publication) Topic() string {
return p.t
}
func (p *publication) Message() *broker.Message {
return p.m
}
func (p *publication) Ack() error {
// nats does not support acking
return nil
}
func (p *publication) Error() error {
return p.err
}
func (s *subscriber) Options() broker.SubscribeOptions {
return s.opts
}
func (s *subscriber) Topic() string {
return s.s.Subject
}
func (s *subscriber) Unsubscribe() error {
return s.s.Unsubscribe()
}
func (n *natsBroker) Address() string {
if n.conn != nil && n.conn.IsConnected() {
return n.conn.ConnectedUrl()
}
if len(n.addrs) > 0 {
return n.addrs[0]
}
return ""
}
func (n *natsBroker) setAddrs(addrs []string) []string {
//nolint:prealloc
var cAddrs []string
for _, addr := range addrs {
if len(addr) == 0 {
continue
}
if !strings.HasPrefix(addr, "nats://") {
addr = "nats://" + addr
}
cAddrs = append(cAddrs, addr)
}
if len(cAddrs) == 0 {
cAddrs = []string{natsp.DefaultURL}
}
return cAddrs
}
func (n *natsBroker) Connect() error {
n.Lock()
defer n.Unlock()
if n.connected {
return nil
}
// Check if we should use connection pooling
if n.poolSize > 1 {
// Initialize connection pool
factory := func() (*natsp.Conn, error) {
opts := n.nopts
opts.Servers = n.addrs
opts.Secure = n.opts.Secure
opts.TLSConfig = n.opts.TLSConfig
// secure might not be set
if n.opts.TLSConfig != nil {
opts.Secure = true
}
return opts.Connect()
}
pool, err := newConnectionPool(n.poolSize, factory)
if err != nil {
return err
}
// Set idle timeout if configured
if n.poolIdleTimeout > 0 {
pool.idleTimeout = n.poolIdleTimeout
}
n.pool = pool
n.connected = true
return nil
}
// Single connection mode (original behavior)
status := natsp.CLOSED
if n.conn != nil {
status = n.conn.Status()
}
switch status {
case natsp.CONNECTED, natsp.RECONNECTING, natsp.CONNECTING:
n.connected = true
return nil
default: // DISCONNECTED or CLOSED or DRAINING
opts := n.nopts
opts.Servers = n.addrs
opts.Secure = n.opts.Secure
opts.TLSConfig = n.opts.TLSConfig
// secure might not be set
if n.opts.TLSConfig != nil {
opts.Secure = true
}
c, err := opts.Connect()
if err != nil {
return err
}
n.conn = c
n.connected = true
return nil
}
}
func (n *natsBroker) Disconnect() error {
n.Lock()
defer n.Unlock()
// Close connection pool if it exists
if n.pool != nil {
if err := n.pool.Close(); err != nil {
n.opts.Logger.Log(logger.ErrorLevel, "error closing connection pool:", err)
}
n.pool = nil
}
// Close single connection if it exists
if n.conn != nil {
// drain the connection if specified
if n.drain {
n.conn.Drain()
n.closeCh <- nil
}
// close the client connection
n.conn.Close()
n.conn = nil
}
// set not connected
n.connected = false
return nil
}
func (n *natsBroker) Init(opts ...broker.Option) error {
n.setOption(opts...)
return nil
}
func (n *natsBroker) Options() broker.Options {
return n.opts
}
func (n *natsBroker) Publish(topic string, msg *broker.Message, opts ...broker.PublishOption) error {
n.RLock()
defer n.RUnlock()
b, err := n.opts.Codec.Marshal(msg)
if err != nil {
return err
}
// Use connection pool if enabled
if n.pool != nil {
poolConn, err := n.pool.Get()
if err != nil {
return err
}
defer n.pool.Put(poolConn)
conn := poolConn.Conn()
if conn == nil {
return errors.New("invalid connection from pool")
}
return conn.Publish(topic, b)
}
// Use single connection (original behavior)
if n.conn == nil {
return errors.New("not connected")
}
return n.conn.Publish(topic, b)
}
func (n *natsBroker) Subscribe(topic string, handler broker.Handler, opts ...broker.SubscribeOption) (broker.Subscriber, error) {
n.RLock()
hasConnection := n.conn != nil || n.pool != nil
n.RUnlock()
if !hasConnection {
return nil, errors.New("not connected")
}
opt := broker.SubscribeOptions{
AutoAck: true,
Context: context.Background(),
}
for _, o := range opts {
o(&opt)
}
fn := func(msg *natsp.Msg) {
var m broker.Message
pub := &publication{t: msg.Subject}
eh := n.opts.ErrorHandler
err := n.opts.Codec.Unmarshal(msg.Data, &m)
pub.err = err
pub.m = &m
if err != nil {
m.Body = msg.Data
n.opts.Logger.Log(logger.ErrorLevel, err)
if eh != nil {
eh(pub)
}
return
}
if err := handler(pub); err != nil {
pub.err = err
n.opts.Logger.Log(logger.ErrorLevel, err)
if eh != nil {
eh(pub)
}
}
}
var sub *natsp.Subscription
var err error
// Use connection pool if enabled
if n.pool != nil {
poolConn, err := n.pool.Get()
if err != nil {
return nil, err
}
conn := poolConn.Conn()
if conn == nil {
n.pool.Put(poolConn)
return nil, errors.New("invalid connection from pool")
}
if len(opt.Queue) > 0 {
sub, err = conn.QueueSubscribe(topic, opt.Queue, fn)
} else {
sub, err = conn.Subscribe(topic, fn)
}
if err != nil {
n.pool.Put(poolConn)
return nil, err
}
// Return connection to pool after subscription is created
// The subscription keeps the connection alive
n.pool.Put(poolConn)
return &subscriber{s: sub, opts: opt}, nil
}
// Use single connection (original behavior)
n.RLock()
if len(opt.Queue) > 0 {
sub, err = n.conn.QueueSubscribe(topic, opt.Queue, fn)
} else {
sub, err = n.conn.Subscribe(topic, fn)
}
n.RUnlock()
if err != nil {
return nil, err
}
return &subscriber{s: sub, opts: opt}, nil
}
func (n *natsBroker) String() string {
return "nats"
}
func (n *natsBroker) setOption(opts ...broker.Option) {
for _, o := range opts {
o(&n.opts)
}
n.Once.Do(func() {
n.nopts = natsp.GetDefaultOptions()
n.poolSize = 1 // Default to single connection (no pooling)
n.poolIdleTimeout = 5 * time.Minute
})
if nopts, ok := n.opts.Context.Value(optionsKey{}).(natsp.Options); ok {
n.nopts = nopts
}
// Set pool size if configured
if poolSize, ok := n.opts.Context.Value(poolSizeKey{}).(int); ok && poolSize > 0 {
n.poolSize = poolSize
}
// Set pool idle timeout if configured
if idleTimeout, ok := n.opts.Context.Value(poolIdleTimeoutKey{}).(time.Duration); ok {
n.poolIdleTimeout = idleTimeout
}
// broker.Options have higher priority than nats.Options
// only if Addrs, Secure or TLSConfig were not set through a broker.Option
// we read them from nats.Option
if len(n.opts.Addrs) == 0 {
n.opts.Addrs = n.nopts.Servers
}
if !n.opts.Secure {
n.opts.Secure = n.nopts.Secure
}
if n.opts.TLSConfig == nil {
n.opts.TLSConfig = n.nopts.TLSConfig
}
n.addrs = n.setAddrs(n.opts.Addrs)
if n.opts.Context.Value(drainConnectionKey{}) != nil {
n.drain = true
n.closeCh = make(chan error)
n.nopts.ClosedCB = n.onClose
n.nopts.AsyncErrorCB = n.onAsyncError
n.nopts.DisconnectedErrCB = n.onDisconnectedError
}
}
func (n *natsBroker) onClose(conn *natsp.Conn) {
n.closeCh <- nil
}
func (n *natsBroker) onAsyncError(conn *natsp.Conn, sub *natsp.Subscription, err error) {
// There are kinds of different async error nats might callback, but we are interested
// in ErrDrainTimeout only here.
if err == natsp.ErrDrainTimeout {
n.closeCh <- err
}
}
func (n *natsBroker) onDisconnectedError(conn *natsp.Conn, err error) {
n.closeCh <- err
}
func NewNatsBroker(opts ...broker.Option) broker.Broker {
options := broker.Options{
// Default codec
Codec: json.Marshaler{},
Context: context.Background(),
Registry: registry.DefaultRegistry,
Logger: logger.DefaultLogger,
}
n := &natsBroker{
opts: options,
}
n.setOption(opts...)
return n
}
================================================
FILE: broker/nats/nats_test.go
================================================
package nats
import (
"fmt"
"testing"
natsp "github.com/nats-io/nats.go"
"go-micro.dev/v5/broker"
)
var addrTestCases = []struct {
name string
description string
addrs map[string]string // expected address : set address
}{
{
"brokerOpts",
"set broker addresses through a broker.Option in constructor",
map[string]string{
"nats://192.168.10.1:5222": "192.168.10.1:5222",
"nats://10.20.10.0:4222": "10.20.10.0:4222"},
},
{
"brokerInit",
"set broker addresses through a broker.Option in broker.Init()",
map[string]string{
"nats://192.168.10.1:5222": "192.168.10.1:5222",
"nats://10.20.10.0:4222": "10.20.10.0:4222"},
},
{
"natsOpts",
"set broker addresses through the nats.Option in constructor",
map[string]string{
"nats://192.168.10.1:5222": "192.168.10.1:5222",
"nats://10.20.10.0:4222": "10.20.10.0:4222"},
},
{
"default",
"check if default Address is set correctly",
map[string]string{
"nats://127.0.0.1:4222": "",
},
},
}
// TestInitAddrs tests issue #100. Ensures that if the addrs is set by an option in init it will be used.
func TestInitAddrs(t *testing.T) {
for _, tc := range addrTestCases {
t.Run(fmt.Sprintf("%s: %s", tc.name, tc.description), func(t *testing.T) {
var br broker.Broker
var addrs []string
for _, addr := range tc.addrs {
addrs = append(addrs, addr)
}
switch tc.name {
case "brokerOpts":
// we know that there are just two addrs in the dict
br = NewNatsBroker(broker.Addrs(addrs[0], addrs[1]))
br.Init()
case "brokerInit":
br = NewNatsBroker()
// we know that there are just two addrs in the dict
gitextract_cdtwe_82/
├── .editorconfig
├── .github/
│ ├── FUNDING.yml
│ ├── ISSUE_TEMPLATE/
│ │ ├── bug_report.md
│ │ ├── feature_request.md
│ │ ├── performance.md
│ │ └── question.md
│ └── workflows/
│ ├── release.yml
│ ├── tests.yaml
│ └── website.yml
├── .gitignore
├── .golangci.yaml
├── .goreleaser.yaml
├── .vscode/
│ └── settings.json
├── CHANGELOG.md
├── CLAUDE.md
├── CONTRIBUTING.md
├── Dockerfile
├── LICENSE
├── Makefile
├── README.md
├── ROADMAP.md
├── SECURITY.md
├── ai/
│ ├── README.md
│ ├── anthropic/
│ │ ├── anthropic.go
│ │ └── anthropic_test.go
│ ├── model.go
│ ├── openai/
│ │ ├── openai.go
│ │ └── openai_test.go
│ └── options.go
├── auth/
│ ├── ANALYSIS.md
│ ├── auth.go
│ ├── jwt/
│ │ ├── jwt.go
│ │ └── token/
│ │ ├── jwt.go
│ │ ├── jwt_test.go
│ │ ├── options.go
│ │ ├── test/
│ │ │ ├── sample_key
│ │ │ ├── sample_key 2
│ │ │ └── sample_key.pub
│ │ └── token.go
│ ├── noop/
│ │ └── noop.go
│ ├── noop.go
│ ├── options.go
│ ├── rules.go
│ └── rules_test.go
├── broker/
│ ├── broker.go
│ ├── http.go
│ ├── http_test.go
│ ├── memory.go
│ ├── memory_test.go
│ ├── nats/
│ │ ├── context.go
│ │ ├── nats.go
│ │ ├── nats_test.go
│ │ ├── options.go
│ │ ├── pool.go
│ │ └── pool_test.go
│ ├── options.go
│ └── rabbitmq/
│ ├── auth.go
│ ├── channel.go
│ ├── connection.go
│ ├── connection_test.go
│ ├── context.go
│ ├── options.go
│ ├── rabbitmq.go
│ └── rabbitmq_test.go
├── cache/
│ ├── cache.go
│ ├── memory.go
│ ├── memory_test.go
│ ├── options.go
│ ├── options_test.go
│ └── redis/
│ ├── options.go
│ ├── options_test.go
│ ├── redis.go
│ └── redis_test.go
├── client/
│ ├── backoff.go
│ ├── backoff_test.go
│ ├── cache.go
│ ├── cache_test.go
│ ├── client.go
│ ├── common_test.go
│ ├── context.go
│ ├── grpc/
│ │ ├── codec.go
│ │ ├── error.go
│ │ ├── grpc.go
│ │ ├── grpc_pool.go
│ │ ├── grpc_pool_test.go
│ │ ├── grpc_test.go
│ │ ├── message.go
│ │ ├── options.go
│ │ ├── request.go
│ │ ├── request_test.go
│ │ ├── response.go
│ │ └── stream.go
│ ├── options.go
│ ├── options_test.go
│ ├── retry.go
│ ├── rpc_client.go
│ ├── rpc_client_test.go
│ ├── rpc_codec.go
│ ├── rpc_message.go
│ ├── rpc_request.go
│ ├── rpc_request_test.go
│ ├── rpc_response.go
│ ├── rpc_stream.go
│ └── wrapper.go
├── cmd/
│ ├── cmd.go
│ ├── micro/
│ │ ├── README.md
│ │ ├── cli/
│ │ │ ├── README.md
│ │ │ ├── build/
│ │ │ │ └── build.go
│ │ │ ├── cli.go
│ │ │ ├── deploy/
│ │ │ │ └── deploy.go
│ │ │ ├── gen/
│ │ │ │ └── generate.go
│ │ │ ├── init/
│ │ │ │ └── init.go
│ │ │ ├── new/
│ │ │ │ ├── new.go
│ │ │ │ └── template/
│ │ │ │ ├── handler.go
│ │ │ │ ├── ignore.go
│ │ │ │ ├── main.go
│ │ │ │ ├── makefile.go
│ │ │ │ ├── module.go
│ │ │ │ ├── proto.go
│ │ │ │ └── readme.go
│ │ │ ├── remote/
│ │ │ │ └── remote.go
│ │ │ └── util/
│ │ │ ├── dynamic.go
│ │ │ ├── dynamic_test.go
│ │ │ └── util.go
│ │ ├── main.go
│ │ ├── mcp/
│ │ │ ├── EXAMPLES.md
│ │ │ ├── mcp.go
│ │ │ └── mcp_test.go
│ │ ├── run/
│ │ │ ├── config/
│ │ │ │ ├── config.go
│ │ │ │ └── config_test.go
│ │ │ ├── run.go
│ │ │ └── watcher/
│ │ │ └── watcher.go
│ │ ├── server/
│ │ │ ├── gateway.go
│ │ │ ├── server.go
│ │ │ └── util_jwt.go
│ │ └── web/
│ │ ├── main.js
│ │ ├── styles.css
│ │ └── templates/
│ │ ├── api.html
│ │ ├── auth_login.html
│ │ ├── auth_tokens.html
│ │ ├── auth_users.html
│ │ ├── base.html
│ │ ├── form.html
│ │ ├── home.html
│ │ ├── log.html
│ │ ├── logs.html
│ │ ├── playground.html
│ │ ├── scopes.html
│ │ ├── service.html
│ │ └── status.html
│ ├── micro-mcp-gateway/
│ │ ├── Dockerfile
│ │ └── main.go
│ ├── options.go
│ └── protoc-gen-micro/
│ ├── README.md
│ ├── examples/
│ │ ├── greeter/
│ │ │ ├── greeter.pb.go
│ │ │ ├── greeter.pb.micro.go
│ │ │ └── greeter.proto
│ │ └── user/
│ │ ├── user.pb.micro.go.example
│ │ └── user.proto
│ ├── generator/
│ │ ├── Makefile
│ │ ├── generator.go
│ │ └── name_test.go
│ ├── main.go
│ └── plugin/
│ └── micro/
│ ├── micro.go
│ └── micro_test.go
├── codec/
│ ├── bytes/
│ │ ├── bytes.go
│ │ └── marshaler.go
│ ├── codec.go
│ ├── grpc/
│ │ ├── grpc.go
│ │ └── util.go
│ ├── json/
│ │ ├── any_test.go
│ │ ├── codec_test.go
│ │ ├── json.go
│ │ └── marshaler.go
│ ├── jsonrpc/
│ │ ├── client.go
│ │ ├── jsonrpc.go
│ │ └── server.go
│ ├── proto/
│ │ ├── marshaler.go
│ │ ├── message.go
│ │ └── proto.go
│ ├── protorpc/
│ │ ├── envelope.pb.go
│ │ ├── envelope.pb.micro.go
│ │ ├── envelope.proto
│ │ ├── netstring.go
│ │ └── protorpc.go
│ └── text/
│ └── text.go
├── config/
│ ├── README.md
│ ├── config.go
│ ├── default.go
│ ├── default_test.go
│ ├── encoder/
│ │ ├── encoder.go
│ │ └── json/
│ │ └── json.go
│ ├── loader/
│ │ ├── loader.go
│ │ └── memory/
│ │ ├── memory.go
│ │ └── options.go
│ ├── options.go
│ ├── reader/
│ │ ├── json/
│ │ │ ├── json.go
│ │ │ ├── json_test.go
│ │ │ ├── values.go
│ │ │ └── values_test.go
│ │ ├── options.go
│ │ ├── preprocessor.go
│ │ ├── preprocessor_test.go
│ │ └── reader.go
│ ├── secrets/
│ │ ├── box/
│ │ │ ├── box.go
│ │ │ └── box_test.go
│ │ ├── secretbox/
│ │ │ ├── secretbox.go
│ │ │ └── secretbox_test.go
│ │ └── secrets.go
│ ├── source/
│ │ ├── changeset.go
│ │ ├── cli/
│ │ │ ├── README.md
│ │ │ ├── cli.go
│ │ │ ├── cli_test.go
│ │ │ ├── options.go
│ │ │ └── util.go
│ │ ├── env/
│ │ │ ├── README.md
│ │ │ ├── env.go
│ │ │ ├── env_test.go
│ │ │ ├── options.go
│ │ │ └── watcher.go
│ │ ├── file/
│ │ │ ├── README.md
│ │ │ ├── file.go
│ │ │ ├── file_test.go
│ │ │ ├── format.go
│ │ │ ├── format_test.go
│ │ │ ├── options.go
│ │ │ ├── watcher.go
│ │ │ ├── watcher_linux.go
│ │ │ └── watcher_test.go
│ │ ├── flag/
│ │ │ ├── README.md
│ │ │ ├── flag.go
│ │ │ ├── flag_test.go
│ │ │ └── options.go
│ │ ├── memory/
│ │ │ ├── README.md
│ │ │ ├── memory.go
│ │ │ ├── options.go
│ │ │ └── watcher.go
│ │ ├── nats/
│ │ │ ├── README.md
│ │ │ ├── nats.go
│ │ │ ├── options.go
│ │ │ └── watcher.go
│ │ ├── noop.go
│ │ ├── options.go
│ │ └── source.go
│ └── value.go
├── contrib/
│ ├── go-micro-llamaindex/
│ │ ├── .gitignore
│ │ ├── README.md
│ │ ├── examples/
│ │ │ ├── basic_agent.py
│ │ │ └── rag_with_services.py
│ │ ├── go_micro_llamaindex/
│ │ │ ├── __init__.py
│ │ │ ├── exceptions.py
│ │ │ └── toolkit.py
│ │ ├── pyproject.toml
│ │ └── tests/
│ │ ├── __init__.py
│ │ └── test_toolkit.py
│ └── langchain-go-micro/
│ ├── .gitignore
│ ├── CONTRIBUTING.md
│ ├── README.md
│ ├── examples/
│ │ ├── basic_agent.py
│ │ └── multi_agent.py
│ ├── langchain_go_micro/
│ │ ├── __init__.py
│ │ ├── exceptions.py
│ │ └── toolkit.py
│ ├── pyproject.toml
│ └── tests/
│ └── test_toolkit.py
├── debug/
│ ├── handler/
│ │ └── debug.go
│ ├── log/
│ │ ├── log.go
│ │ ├── memory/
│ │ │ ├── memory.go
│ │ │ ├── memory_test.go
│ │ │ └── stream.go
│ │ ├── noop/
│ │ │ └── noop.go
│ │ ├── options.go
│ │ └── os.go
│ ├── profile/
│ │ ├── http/
│ │ │ └── http.go
│ │ ├── pprof/
│ │ │ └── pprof.go
│ │ └── profile.go
│ ├── proto/
│ │ ├── debug.pb.go
│ │ ├── debug.pb.micro.go
│ │ └── debug.proto
│ ├── stats/
│ │ ├── default.go
│ │ └── stats.go
│ └── trace/
│ ├── default.go
│ ├── noop.go
│ ├── options.go
│ └── trace.go
├── errors/
│ ├── errors.go
│ ├── errors.pb.go
│ ├── errors.pb.micro.go
│ ├── errors.proto
│ └── errors_test.go
├── event.go
├── events/
│ ├── events.go
│ ├── memory.go
│ ├── natsjs/
│ │ ├── README.md
│ │ ├── helpers_test.go
│ │ ├── nats.go
│ │ ├── nats_test.go
│ │ └── options.go
│ ├── options.go
│ ├── store.go
│ ├── store_test.go
│ └── stream_test.go
├── examples/
│ ├── README.md
│ ├── agent-demo/
│ │ ├── README.md
│ │ └── main.go
│ ├── auth/
│ │ ├── .gitignore
│ │ ├── README.md
│ │ ├── client/
│ │ │ └── main.go
│ │ ├── proto/
│ │ │ ├── greeter.pb.go
│ │ │ └── greeter.proto
│ │ └── server/
│ │ └── main.go
│ ├── deployment/
│ │ ├── Dockerfile
│ │ ├── Dockerfile.gateway
│ │ ├── README.md
│ │ └── docker-compose.yml
│ ├── hello-world/
│ │ ├── README.md
│ │ ├── go.mod
│ │ ├── go.sum
│ │ └── main.go
│ ├── mcp/
│ │ ├── README.md
│ │ ├── crud/
│ │ │ ├── README.md
│ │ │ └── main.go
│ │ ├── documented/
│ │ │ ├── README.md
│ │ │ └── main.go
│ │ ├── hello/
│ │ │ ├── README.md
│ │ │ └── main.go
│ │ ├── platform/
│ │ │ ├── README.md
│ │ │ └── main.go
│ │ └── workflow/
│ │ ├── README.md
│ │ └── main.go
│ ├── multi-service/
│ │ └── main.go
│ └── web-service/
│ ├── README.md
│ ├── go.mod
│ ├── go.sum
│ └── main.go
├── gateway/
│ ├── api/
│ │ ├── README.md
│ │ └── gateway.go
│ └── mcp/
│ ├── DOCUMENTATION.md
│ ├── benchmark_test.go
│ ├── circuitbreaker.go
│ ├── circuitbreaker_test.go
│ ├── deploy/
│ │ └── helm/
│ │ └── mcp-gateway/
│ │ ├── Chart.yaml
│ │ ├── README.md
│ │ ├── templates/
│ │ │ ├── NOTES.txt
│ │ │ ├── _helpers.tpl
│ │ │ ├── deployment.yaml
│ │ │ ├── hpa.yaml
│ │ │ ├── ingress.yaml
│ │ │ ├── service.yaml
│ │ │ └── serviceaccount.yaml
│ │ └── values.yaml
│ ├── example_test.go
│ ├── mcp.go
│ ├── mcp_test.go
│ ├── option.go
│ ├── otel.go
│ ├── otel_test.go
│ ├── parser.go
│ ├── ratelimit.go
│ ├── stdio.go
│ ├── websocket.go
│ └── websocket_test.go
├── go.mod
├── go.sum
├── health/
│ ├── health.go
│ └── health_test.go
├── internal/
│ ├── README.md
│ ├── docs/
│ │ ├── CURRENT_STATUS_SUMMARY.md
│ │ ├── IMPLEMENTATION_SUMMARY.md
│ │ ├── PROJECT_STATUS_2026.md
│ │ └── ROADMAP_2026.md
│ ├── scripts/
│ │ └── install.sh
│ ├── test/
│ │ ├── service.go
│ │ ├── testing.go
│ │ └── testing_test.go
│ ├── util/
│ │ ├── addr/
│ │ │ ├── addr.go
│ │ │ └── addr_test.go
│ │ ├── backoff/
│ │ │ └── backoff.go
│ │ ├── buf/
│ │ │ └── buf.go
│ │ ├── grpc/
│ │ │ ├── grpc.go
│ │ │ └── grpc_test.go
│ │ ├── http/
│ │ │ ├── http.go
│ │ │ ├── http_test.go
│ │ │ ├── options.go
│ │ │ └── roundtripper.go
│ │ ├── jitter/
│ │ │ └── jitter.go
│ │ ├── mdns/
│ │ │ ├── .gitignore
│ │ │ ├── client.go
│ │ │ ├── dns_sd.go
│ │ │ ├── dns_sd_test.go
│ │ │ ├── server.go
│ │ │ ├── server_test.go
│ │ │ ├── zone.go
│ │ │ └── zone_test.go
│ │ ├── net/
│ │ │ ├── net.go
│ │ │ └── net_test.go
│ │ ├── pool/
│ │ │ ├── default.go
│ │ │ ├── default_test.go
│ │ │ ├── options.go
│ │ │ └── pool.go
│ │ ├── registry/
│ │ │ ├── util.go
│ │ │ └── util_test.go
│ │ ├── ring/
│ │ │ ├── buffer.go
│ │ │ └── buffer_test.go
│ │ ├── signal/
│ │ │ └── signal.go
│ │ ├── socket/
│ │ │ ├── pool.go
│ │ │ └── socket.go
│ │ ├── test/
│ │ │ └── test.go
│ │ ├── tls/
│ │ │ ├── tls.go
│ │ │ └── tls_test.go
│ │ └── wrapper/
│ │ ├── wrapper.go
│ │ └── wrapper_test.go
│ └── website/
│ ├── .gitignore
│ ├── Gemfile
│ ├── README.md
│ ├── _config.yml
│ ├── _data/
│ │ └── navigation.yml
│ ├── _layouts/
│ │ ├── blog.html
│ │ └── default.html
│ ├── badge.html
│ ├── blog/
│ │ ├── 1.md
│ │ ├── 2.md
│ │ ├── 3.md
│ │ ├── 4.md
│ │ ├── 5.md
│ │ ├── 6.md
│ │ ├── 7.md
│ │ ├── 8.md
│ │ └── index.html
│ ├── docs/
│ │ ├── REFLECTION-EVALUATION-SUMMARY.md
│ │ ├── SECURITY_MIGRATION.md
│ │ ├── TLS_SECURITY_UPDATE.md
│ │ ├── architecture/
│ │ │ ├── adr-001-plugin-architecture.md
│ │ │ ├── adr-004-mdns-default-registry.md
│ │ │ ├── adr-009-progressive-configuration.md
│ │ │ ├── adr-010-unified-gateway.md
│ │ │ ├── adr-template.md
│ │ │ └── index.md
│ │ ├── architecture.md
│ │ ├── broker.md
│ │ ├── client-server.md
│ │ ├── config.md
│ │ ├── contributing.md
│ │ ├── deployment.md
│ │ ├── examples/
│ │ │ ├── hello-service.md
│ │ │ ├── index.md
│ │ │ ├── pubsub-nats.md
│ │ │ ├── realworld/
│ │ │ │ ├── api-gateway.md
│ │ │ │ ├── graceful-shutdown.md
│ │ │ │ └── index.md
│ │ │ ├── registry-consul.md
│ │ │ ├── rpc-client.md
│ │ │ ├── store-postgres.md
│ │ │ └── transport-nats.md
│ │ ├── getting-started.md
│ │ ├── guides/
│ │ │ ├── agent-patterns.md
│ │ │ ├── ai-native-services.md
│ │ │ ├── cli-gateway.md
│ │ │ ├── comparison.md
│ │ │ ├── deployment.md
│ │ │ ├── error-handling.md
│ │ │ ├── grpc-compatibility.md
│ │ │ ├── health.md
│ │ │ ├── mcp-security.md
│ │ │ ├── micro-run.md
│ │ │ ├── migration/
│ │ │ │ ├── add-mcp.md
│ │ │ │ ├── from-grpc.md
│ │ │ │ └── index.md
│ │ │ ├── testing.md
│ │ │ ├── tool-descriptions.md
│ │ │ └── troubleshooting.md
│ │ ├── hosting.md
│ │ ├── index.md
│ │ ├── mcp.md
│ │ ├── model.md
│ │ ├── observability.md
│ │ ├── performance.md
│ │ ├── plugins.md
│ │ ├── quickstart.md
│ │ ├── reflection-removal-analysis.md
│ │ ├── registry.md
│ │ ├── roadmap-2026.md
│ │ ├── roadmap.md
│ │ ├── search.md
│ │ ├── server.md
│ │ ├── store.md
│ │ └── transport.md
│ ├── index.html
│ └── install.sh
├── logger/
│ ├── context.go
│ ├── debug_handler.go
│ ├── debug_test.go
│ ├── default.go
│ ├── helper.go
│ ├── level.go
│ ├── logger.go
│ ├── logger_test.go
│ └── options.go
├── metadata/
│ ├── metadata.go
│ └── metadata_test.go
├── micro.go
├── model/
│ ├── README.md
│ ├── memory/
│ │ ├── memory.go
│ │ └── memory_test.go
│ ├── memory.go
│ ├── model.go
│ ├── model_test.go
│ ├── options.go
│ ├── postgres/
│ │ └── postgres.go
│ ├── query.go
│ ├── schema.go
│ └── sqlite/
│ ├── sqlite.go
│ └── sqlite_test.go
├── options.go
├── registry/
│ ├── cache/
│ │ ├── README.md
│ │ ├── cache.go
│ │ ├── cache_test.go
│ │ └── options.go
│ ├── consul/
│ │ ├── consul.go
│ │ ├── encoding.go
│ │ ├── encoding_test.go
│ │ ├── options.go
│ │ ├── registry_test.go
│ │ ├── watcher.go
│ │ └── watcher_test.go
│ ├── etcd/
│ │ ├── PERFORMANCE.md
│ │ ├── etcd.go
│ │ ├── etcd_test.go
│ │ ├── options.go
│ │ └── watcher.go
│ ├── mdns_registry.go
│ ├── mdns_test.go
│ ├── memory.go
│ ├── memory_test.go
│ ├── memory_util.go
│ ├── memory_watcher.go
│ ├── nats/
│ │ ├── nats.go
│ │ ├── nats_assert_test.go
│ │ ├── nats_environment_test.go
│ │ ├── nats_options.go
│ │ ├── nats_registry.go
│ │ ├── nats_test.go
│ │ ├── nats_util.go
│ │ └── nats_watcher.go
│ ├── options.go
│ ├── options_test.go
│ ├── registry.go
│ └── watcher.go
├── selector/
│ ├── common_test.go
│ ├── default.go
│ ├── default_test.go
│ ├── filter.go
│ ├── filter_test.go
│ ├── options.go
│ ├── selector.go
│ ├── strategy.go
│ └── strategy_test.go
├── server/
│ ├── comments.go
│ ├── comments_test.go
│ ├── context.go
│ ├── doc.go
│ ├── extractor.go
│ ├── extractor_test.go
│ ├── grpc/
│ │ ├── codec.go
│ │ ├── context.go
│ │ ├── error.go
│ │ ├── extractor.go
│ │ ├── extractor_test.go
│ │ ├── grpc.go
│ │ ├── handler.go
│ │ ├── options.go
│ │ ├── request.go
│ │ ├── response.go
│ │ ├── server.go
│ │ ├── stream.go
│ │ ├── subscriber.go
│ │ └── util.go
│ ├── handler.go
│ ├── mock/
│ │ ├── mock.go
│ │ ├── mock_handler.go
│ │ ├── mock_subscriber.go
│ │ └── mock_test.go
│ ├── options.go
│ ├── proto/
│ │ ├── server.pb.go
│ │ ├── server.pb.micro.go
│ │ └── server.proto
│ ├── rpc_codec.go
│ ├── rpc_codec_test.go
│ ├── rpc_event.go
│ ├── rpc_events.go
│ ├── rpc_events_test.go
│ ├── rpc_handler.go
│ ├── rpc_helper.go
│ ├── rpc_request.go
│ ├── rpc_response.go
│ ├── rpc_router.go
│ ├── rpc_server.go
│ ├── rpc_stream.go
│ ├── rpc_stream_test.go
│ ├── rpc_util.go
│ ├── server.go
│ ├── subscriber.go
│ └── wrapper.go
├── service/
│ ├── group.go
│ ├── options.go
│ ├── profile/
│ │ └── profile.go
│ └── service.go
├── store/
│ ├── file.go
│ ├── file_test.go
│ ├── memory.go
│ ├── mysql/
│ │ ├── mysql.go
│ │ └── mysql_test.go
│ ├── nats-js-kv/
│ │ ├── README.md
│ │ ├── context.go
│ │ ├── helpers_test.go
│ │ ├── keys.go
│ │ ├── nats.go
│ │ ├── nats_test.go
│ │ ├── options.go
│ │ └── test_data.go
│ ├── noop.go
│ ├── options.go
│ ├── postgres/
│ │ ├── README.md
│ │ ├── metadata.go
│ │ ├── pgx/
│ │ │ ├── README.md
│ │ │ ├── db.go
│ │ │ ├── metadata.go
│ │ │ ├── pgx.go
│ │ │ ├── pgx_test.go
│ │ │ ├── queries.go
│ │ │ └── templates.go
│ │ ├── postgres.go
│ │ └── postgres_test.go
│ └── store.go
├── transport/
│ ├── context.go
│ ├── grpc/
│ │ ├── grpc.go
│ │ ├── grpc_test.go
│ │ ├── handler.go
│ │ ├── proto/
│ │ │ ├── transport.pb.go
│ │ │ ├── transport.pb.micro.go
│ │ │ ├── transport.proto
│ │ │ └── transport_grpc.pb.go
│ │ └── socket.go
│ ├── headers/
│ │ └── headers.go
│ ├── http2_buf_pool.go
│ ├── http_client.go
│ ├── http_client_test.go
│ ├── http_listener.go
│ ├── http_proxy.go
│ ├── http_socket.go
│ ├── http_transport.go
│ ├── http_transport_test.go
│ ├── memory.go
│ ├── memory_test.go
│ ├── nats/
│ │ ├── nats.go
│ │ ├── nats_test.go
│ │ ├── options.go
│ │ ├── pool.go
│ │ └── pool_test.go
│ ├── options.go
│ └── transport.go
├── web/
│ ├── options.go
│ ├── service.go
│ ├── service_test.go
│ ├── sse.go
│ ├── sse_test.go
│ ├── web.go
│ └── web_test.go
└── wrapper/
├── auth/
│ ├── README.md
│ ├── client.go
│ ├── metadata.go
│ └── server.go
└── trace/
└── opentelemetry/
├── README.md
├── opentelemetry.go
├── options.go
└── wrapper.go
Showing preview only (359K chars total). Download the full file or copy to clipboard to get everything.
SYMBOL INDEX (4401 symbols across 463 files)
FILE: ai/anthropic/anthropic.go
function init (line 16) | func init() {
type Provider (line 23) | type Provider struct
method Init (line 45) | func (p *Provider) Init(opts ...ai.Option) error {
method Options (line 53) | func (p *Provider) Options() ai.Options {
method String (line 58) | func (p *Provider) String() string {
method Generate (line 63) | func (p *Provider) Generate(ctx context.Context, req *ai.Request, opts...
method Stream (line 145) | func (p *Provider) Stream(ctx context.Context, req *ai.Request, opts ....
method callAPI (line 150) | func (p *Provider) callAPI(ctx context.Context, req map[string]any) (*...
function NewProvider (line 28) | func NewProvider(opts ...ai.Option) *Provider {
FILE: ai/anthropic/anthropic_test.go
function TestProvider_String (line 10) | func TestProvider_String(t *testing.T) {
function TestProvider_Init (line 17) | func TestProvider_Init(t *testing.T) {
function TestProvider_Options (line 42) | func TestProvider_Options(t *testing.T) {
function TestProvider_Defaults (line 57) | func TestProvider_Defaults(t *testing.T) {
function TestProvider_Generate_NoAPIKey (line 69) | func TestProvider_Generate_NoAPIKey(t *testing.T) {
function TestProvider_Stream_NotImplemented (line 83) | func TestProvider_Stream_NotImplemented(t *testing.T) {
FILE: ai/model.go
type Model (line 10) | type Model interface
type Tool (line 24) | type Tool struct
type Request (line 32) | type Request struct
type Message (line 44) | type Message struct
type Response (line 50) | type Response struct
type ToolCall (line 60) | type ToolCall struct
type ToolResult (line 67) | type ToolResult struct
type Stream (line 73) | type Stream interface
type ToolHandler (line 81) | type ToolHandler
type NewFunc (line 84) | type NewFunc
function Register (line 89) | func Register(name string, fn NewFunc) {
function New (line 94) | func New(provider string, opts ...Option) Model {
function AutoDetectProvider (line 110) | func AutoDetectProvider(baseURL string) string {
function Generate (line 125) | func Generate(ctx context.Context, req *Request, opts ...GenerateOption)...
FILE: ai/openai/openai.go
function init (line 16) | func init() {
type Provider (line 23) | type Provider struct
method Init (line 45) | func (p *Provider) Init(opts ...ai.Option) error {
method Options (line 53) | func (p *Provider) Options() ai.Options {
method String (line 58) | func (p *Provider) String() string {
method Generate (line 63) | func (p *Provider) Generate(ctx context.Context, req *ai.Request, opts...
method Stream (line 141) | func (p *Provider) Stream(ctx context.Context, req *ai.Request, opts ....
method callAPI (line 146) | func (p *Provider) callAPI(ctx context.Context, req map[string]any) (*...
function NewProvider (line 28) | func NewProvider(opts ...ai.Option) *Provider {
FILE: ai/openai/openai_test.go
function TestProvider_String (line 10) | func TestProvider_String(t *testing.T) {
function TestProvider_Init (line 17) | func TestProvider_Init(t *testing.T) {
function TestProvider_Options (line 42) | func TestProvider_Options(t *testing.T) {
function TestProvider_Defaults (line 57) | func TestProvider_Defaults(t *testing.T) {
function TestProvider_Generate_NoAPIKey (line 69) | func TestProvider_Generate_NoAPIKey(t *testing.T) {
function TestProvider_Stream_NotImplemented (line 83) | func TestProvider_Stream_NotImplemented(t *testing.T) {
FILE: ai/options.go
type Options (line 8) | type Options struct
type GenerateOptions (line 22) | type GenerateOptions struct
type Option (line 28) | type Option
type GenerateOption (line 31) | type GenerateOption
function NewOptions (line 34) | func NewOptions(opts ...Option) Options {
function WithModel (line 45) | func WithModel(m string) Option {
function WithAPIKey (line 52) | func WithAPIKey(key string) Option {
function WithBaseURL (line 59) | func WithBaseURL(url string) Option {
function WithContext (line 66) | func WithContext(ctx context.Context) Option {
function WithToolHandler (line 73) | func WithToolHandler(handler ToolHandler) Option {
FILE: auth/auth.go
constant BearerScheme (line 12) | BearerScheme = "Bearer "
constant ScopePublic (line 14) | ScopePublic = ""
constant ScopeAccount (line 16) | ScopeAccount = "*"
type Auth (line 27) | type Auth interface
type Rules (line 43) | type Rules interface
type Account (line 55) | type Account struct
type Token (line 71) | type Token struct
method Expired (line 83) | func (t *Token) Expired() bool {
type Resource (line 88) | type Resource struct
type Access (line 98) | type Access
constant AccessGranted (line 102) | AccessGranted Access = iota
constant AccessDenied (line 104) | AccessDenied
type Rule (line 108) | type Rule struct
type accountKey (line 123) | type accountKey struct
function AccountFromContext (line 129) | func AccountFromContext(ctx context.Context) (*Account, bool) {
function ContextWithAccount (line 135) | func ContextWithAccount(ctx context.Context, account *Account) context.C...
FILE: auth/jwt/jwt.go
function init (line 12) | func init() {
function NewAuth (line 17) | func NewAuth(opts ...auth.Option) auth.Auth {
function NewRules (line 23) | func NewRules() auth.Rules {
type jwt (line 27) | type jwt struct
method String (line 38) | func (j *jwt) String() string {
method Init (line 42) | func (j *jwt) Init(opts ...auth.Option) {
method Options (line 56) | func (j *jwt) Options() auth.Options {
method Generate (line 62) | func (j *jwt) Generate(id string, opts ...auth.GenerateOption) (*auth....
method Inspect (line 124) | func (j *jwt) Inspect(token string) (*auth.Account, error) {
method Token (line 128) | func (j *jwt) Token(opts ...auth.TokenOption) (*auth.Token, error) {
type jwtRules (line 33) | type jwtRules struct
method Grant (line 84) | func (j *jwtRules) Grant(rule *auth.Rule) error {
method Revoke (line 91) | func (j *jwtRules) Revoke(rule *auth.Rule) error {
method Verify (line 106) | func (j *jwtRules) Verify(acc *auth.Account, res *auth.Resource, opts ...
method List (line 118) | func (j *jwtRules) List(opts ...auth.ListOption) ([]*auth.Rule, error) {
FILE: auth/jwt/token/jwt.go
type authClaims (line 12) | type authClaims struct
type JWT (line 21) | type JWT struct
method Generate (line 33) | func (j *JWT) Generate(acc *auth.Account, opts ...GenerateOption) (*To...
method Inspect (line 72) | func (j *JWT) Inspect(t string) (*auth.Account, error) {
method String (line 107) | func (j *JWT) String() string {
function New (line 26) | func New(opts ...Option) Provider {
FILE: auth/jwt/token/jwt_test.go
function TestGenerate (line 11) | func TestGenerate(t *testing.T) {
function TestInspect (line 27) | func TestInspect(t *testing.T) {
FILE: auth/jwt/token/options.go
type Options (line 9) | type Options struct
type Option (line 18) | type Option
function WithStore (line 21) | func WithStore(s store.Store) Option {
function WithPublicKey (line 28) | func WithPublicKey(key string) Option {
function WithPrivateKey (line 35) | func WithPrivateKey(key string) Option {
function NewOptions (line 41) | func NewOptions(opts ...Option) Options {
type GenerateOptions (line 53) | type GenerateOptions struct
type GenerateOption (line 58) | type GenerateOption
function WithExpiry (line 61) | func WithExpiry(d time.Duration) GenerateOption {
function NewGenerateOptions (line 68) | func NewGenerateOptions(opts ...GenerateOption) GenerateOptions {
FILE: auth/jwt/token/token.go
type Provider (line 20) | type Provider interface
type Token (line 26) | type Token struct
FILE: auth/noop.go
function NewAuth (line 11) | func NewAuth(opts ...Option) Auth {
function NewRules (line 23) | func NewRules() Rules {
type noop (line 27) | type noop struct
method String (line 34) | func (n *noop) String() string {
method Init (line 39) | func (n *noop) Init(opts ...Option) {
method Options (line 46) | func (n *noop) Options() Options {
method Generate (line 51) | func (n *noop) Generate(id string, opts ...GenerateOption) (*Account, ...
method Inspect (line 84) | func (n *noop) Inspect(token string) (*Account, error) {
method Token (line 89) | func (n *noop) Token(opts ...TokenOption) (*Token, error) {
type noopRules (line 31) | type noopRules struct
method Grant (line 64) | func (n *noopRules) Grant(rule *Rule) error {
method Revoke (line 69) | func (n *noopRules) Revoke(rule *Rule) error {
method Verify (line 75) | func (n *noopRules) Verify(acc *Account, res *Resource, opts ...Verify...
method List (line 79) | func (n *noopRules) List(opts ...ListOption) ([]*Rule, error) {
FILE: auth/noop/noop.go
function NewAuth (line 30) | func NewAuth(opts ...auth.Option) auth.Auth {
function NewRules (line 43) | func NewRules() auth.Rules {
FILE: auth/options.go
function NewOptions (line 10) | func NewOptions(opts ...Option) Options {
type Options (line 22) | type Options struct
type Option (line 41) | type Option
function Addrs (line 44) | func Addrs(addrs ...string) Option {
function Namespace (line 51) | func Namespace(n string) Option {
function PublicKey (line 58) | func PublicKey(key string) Option {
function PrivateKey (line 65) | func PrivateKey(key string) Option {
function WithLogger (line 72) | func WithLogger(l logger.Logger) Option {
function Credentials (line 79) | func Credentials(id, secret string) Option {
function ClientToken (line 87) | func ClientToken(token *Token) Option {
type GenerateOptions (line 93) | type GenerateOptions struct
type GenerateOption (line 106) | type GenerateOption
function WithSecret (line 109) | func WithSecret(s string) GenerateOption {
function WithType (line 116) | func WithType(t string) GenerateOption {
function WithMetadata (line 123) | func WithMetadata(md map[string]string) GenerateOption {
function WithProvider (line 130) | func WithProvider(p string) GenerateOption {
function WithScopes (line 137) | func WithScopes(s ...string) GenerateOption {
function NewGenerateOptions (line 144) | func NewGenerateOptions(opts ...GenerateOption) GenerateOptions {
type TokenOptions (line 152) | type TokenOptions struct
type TokenOption (line 163) | type TokenOption
function WithExpiry (line 166) | func WithExpiry(ex time.Duration) TokenOption {
function WithCredentials (line 172) | func WithCredentials(id, secret string) TokenOption {
function WithToken (line 179) | func WithToken(rt string) TokenOption {
function NewTokenOptions (line 186) | func NewTokenOptions(opts ...TokenOption) TokenOptions {
type VerifyOptions (line 200) | type VerifyOptions struct
type VerifyOption (line 204) | type VerifyOption
function VerifyContext (line 206) | func VerifyContext(ctx context.Context) VerifyOption {
type ListOptions (line 212) | type ListOptions struct
type ListOption (line 216) | type ListOption
function RulesContext (line 218) | func RulesContext(ctx context.Context) ListOption {
FILE: auth/rules.go
function Verify (line 12) | func Verify(rules []*Rule, acc *Account, res *Resource) error {
function include (line 84) | func include(slice []string, val string) bool {
FILE: auth/rules_test.go
function TestVerify (line 7) | func TestVerify(t *testing.T) {
FILE: broker/broker.go
type Broker (line 5) | type Broker interface
type Handler (line 19) | type Handler
type Message (line 22) | type Message struct
type Event (line 28) | type Event interface
type Subscriber (line 36) | type Subscriber interface
function Init (line 47) | func Init(opts ...Option) error {
function Connect (line 51) | func Connect() error {
function Disconnect (line 55) | func Disconnect() error {
function Publish (line 59) | func Publish(topic string, msg *Message, opts ...PublishOption) error {
function Subscribe (line 63) | func Subscribe(topic string, handler Handler, opts ...SubscribeOption) (...
function String (line 68) | func String() string {
FILE: broker/http.go
type httpBroker (line 30) | type httpBroker struct
method saveMessage (line 181) | func (h *httpBroker) saveMessage(topic string, msg []byte) {
method getMessage (line 200) | func (h *httpBroker) getMessage(topic string, num int) [][]byte {
method subscribe (line 224) | func (h *httpBroker) subscribe(s *httpSubscriber) error {
method unsubscribe (line 236) | func (h *httpBroker) unsubscribe(s *httpSubscriber) error {
method run (line 260) | func (h *httpBroker) run(l net.Listener) {
method ServeHTTP (line 290) | func (h *httpBroker) ServeHTTP(w http.ResponseWriter, req *http.Reques...
method Address (line 347) | func (h *httpBroker) Address() string {
method Connect (line 353) | func (h *httpBroker) Connect() error {
method Disconnect (line 431) | func (h *httpBroker) Disconnect() error {
method Init (line 458) | func (h *httpBroker) Init(opts ...Option) error {
method Options (line 505) | func (h *httpBroker) Options() Options {
method Publish (line 509) | func (h *httpBroker) Publish(topic string, msg *Message, opts ...Publi...
method Subscribe (line 637) | func (h *httpBroker) Subscribe(topic string, handler Handler, opts ......
method String (line 701) | func (h *httpBroker) String() string {
type httpSubscriber (line 52) | type httpSubscriber struct
method Options (line 169) | func (h *httpSubscriber) Options() SubscribeOptions {
method Topic (line 173) | func (h *httpSubscriber) Topic() string {
method Unsubscribe (line 177) | func (h *httpSubscriber) Unsubscribe() error {
type httpEvent (line 61) | type httpEvent struct
method Ack (line 153) | func (h *httpEvent) Ack() error {
method Error (line 157) | func (h *httpEvent) Error() error {
method Message (line 161) | func (h *httpEvent) Message() *Message {
method Topic (line 165) | func (h *httpEvent) Topic() string {
function init (line 76) | func init() {
function newTransport (line 79) | func newTransport(config *tls.Config) *http.Transport {
function newHttpBroker (line 108) | func newHttpBroker(opts ...Option) Broker {
function NewHttpBroker (line 706) | func NewHttpBroker(opts ...Option) Broker {
FILE: broker/http_test.go
function newTestRegistry (line 55) | func newTestRegistry() registry.Registry {
function sub (line 59) | func sub(b *testing.B, c int) {
function pub (line 121) | func pub(b *testing.B, c int) {
function TestBroker (line 191) | func TestBroker(t *testing.T) {
function TestConcurrentSubBroker (line 240) | func TestConcurrentSubBroker(t *testing.T) {
function TestConcurrentPubBroker (line 299) | func TestConcurrentPubBroker(t *testing.T) {
function BenchmarkSub1 (line 354) | func BenchmarkSub1(b *testing.B) {
function BenchmarkSub8 (line 357) | func BenchmarkSub8(b *testing.B) {
function BenchmarkSub32 (line 361) | func BenchmarkSub32(b *testing.B) {
function BenchmarkPub1 (line 365) | func BenchmarkPub1(b *testing.B) {
function BenchmarkPub8 (line 369) | func BenchmarkPub8(b *testing.B) {
function BenchmarkPub32 (line 373) | func BenchmarkPub32(b *testing.B) {
FILE: broker/memory.go
type memoryBroker (line 15) | type memoryBroker struct
method Options (line 40) | func (m *memoryBroker) Options() Options {
method Address (line 44) | func (m *memoryBroker) Address() string {
method Connect (line 48) | func (m *memoryBroker) Connect() error {
method Disconnect (line 71) | func (m *memoryBroker) Disconnect() error {
method Init (line 84) | func (m *memoryBroker) Init(opts ...Option) error {
method Publish (line 91) | func (m *memoryBroker) Publish(topic string, msg *Message, opts ...Pub...
method Subscribe (line 135) | func (m *memoryBroker) Subscribe(topic string, handler Handler, opts ....
method String (line 177) | func (m *memoryBroker) String() string {
type memoryEvent (line 25) | type memoryEvent struct
method Topic (line 181) | func (m *memoryEvent) Topic() string {
method Message (line 185) | func (m *memoryEvent) Message() *Message {
method Ack (line 201) | func (m *memoryEvent) Ack() error {
method Error (line 205) | func (m *memoryEvent) Error() error {
type memorySubscriber (line 32) | type memorySubscriber struct
method Options (line 209) | func (m *memorySubscriber) Options() SubscribeOptions {
method Topic (line 213) | func (m *memorySubscriber) Topic() string {
method Unsubscribe (line 217) | func (m *memorySubscriber) Unsubscribe() error {
function NewMemoryBroker (line 222) | func NewMemoryBroker(opts ...Option) Broker {
FILE: broker/memory_test.go
function TestMemoryBroker (line 10) | func TestMemoryBroker(t *testing.T) {
FILE: broker/nats/context.go
function setBrokerOption (line 10) | func setBrokerOption(k, v interface{}) broker.Option {
FILE: broker/nats/nats.go
type natsBroker (line 18) | type natsBroker struct
method Address (line 80) | func (n *natsBroker) Address() string {
method setAddrs (line 92) | func (n *natsBroker) setAddrs(addrs []string) []string {
method Connect (line 110) | func (n *natsBroker) Connect() error {
method Disconnect (line 181) | func (n *natsBroker) Disconnect() error {
method Init (line 212) | func (n *natsBroker) Init(opts ...broker.Option) error {
method Options (line 217) | func (n *natsBroker) Options() broker.Options {
method Publish (line 221) | func (n *natsBroker) Publish(topic string, msg *broker.Message, opts ....
method Subscribe (line 253) | func (n *natsBroker) Subscribe(topic string, handler broker.Handler, o...
method String (line 343) | func (n *natsBroker) String() string {
method setOption (line 347) | func (n *natsBroker) setOption(opts ...broker.Option) {
method onClose (line 397) | func (n *natsBroker) onClose(conn *natsp.Conn) {
method onAsyncError (line 401) | func (n *natsBroker) onAsyncError(conn *natsp.Conn, sub *natsp.Subscri...
method onDisconnectedError (line 409) | func (n *natsBroker) onDisconnectedError(conn *natsp.Conn, err error) {
type subscriber (line 40) | type subscriber struct
method Options (line 68) | func (s *subscriber) Options() broker.SubscribeOptions {
method Topic (line 72) | func (s *subscriber) Topic() string {
method Unsubscribe (line 76) | func (s *subscriber) Unsubscribe() error {
type publication (line 45) | type publication struct
method Topic (line 51) | func (p *publication) Topic() string {
method Message (line 55) | func (p *publication) Message() *broker.Message {
method Ack (line 59) | func (p *publication) Ack() error {
method Error (line 64) | func (p *publication) Error() error {
function NewNatsBroker (line 413) | func NewNatsBroker(opts ...broker.Option) broker.Broker {
FILE: broker/nats/nats_test.go
function TestInitAddrs (line 47) | func TestInitAddrs(t *testing.T) {
FILE: broker/nats/options.go
type optionsKey (line 10) | type optionsKey struct
type drainConnectionKey (line 11) | type drainConnectionKey struct
type poolSizeKey (line 12) | type poolSizeKey struct
type poolIdleTimeoutKey (line 13) | type poolIdleTimeoutKey struct
function Options (line 16) | func Options(opts natsp.Options) broker.Option {
function DrainConnection (line 21) | func DrainConnection() broker.Option {
function PoolSize (line 28) | func PoolSize(size int) broker.Option {
function PoolIdleTimeout (line 35) | func PoolIdleTimeout(timeout time.Duration) broker.Option {
FILE: broker/nats/pool.go
type connectionPool (line 19) | type connectionPool struct
method Get (line 54) | func (p *connectionPool) Get() (*pooledConnection, error) {
method Put (line 80) | func (p *connectionPool) Put(conn *pooledConnection) error {
method Close (line 106) | func (p *connectionPool) Close() error {
method createConnection (line 126) | func (p *connectionPool) createConnection() (*pooledConnection, error) {
type pooledConnection (line 29) | type pooledConnection struct
method isValid (line 140) | func (pc *pooledConnection) isValid() bool {
method isExpired (line 153) | func (pc *pooledConnection) isExpired(timeout time.Duration) bool {
method close (line 165) | func (pc *pooledConnection) close() error {
method Conn (line 177) | func (pc *pooledConnection) Conn() *natsp.Conn {
method updateLastUsed (line 184) | func (pc *pooledConnection) updateLastUsed() {
function newConnectionPool (line 37) | func newConnectionPool(size int, factory func() (*natsp.Conn, error)) (*...
FILE: broker/nats/pool_test.go
function TestConnectionPool_GetPut (line 11) | func TestConnectionPool_GetPut(t *testing.T) {
function TestConnectionPool_Concurrent (line 53) | func TestConnectionPool_Concurrent(t *testing.T) {
function TestConnectionPool_Close (line 98) | func TestConnectionPool_Close(t *testing.T) {
function TestPooledConnection_IsValid (line 130) | func TestPooledConnection_IsValid(t *testing.T) {
function TestPooledConnection_IsExpired (line 142) | func TestPooledConnection_IsExpired(t *testing.T) {
function TestNatsBroker_PoolConfiguration (line 165) | func TestNatsBroker_PoolConfiguration(t *testing.T) {
function TestNatsBroker_DefaultSingleConnection (line 193) | func TestNatsBroker_DefaultSingleConnection(t *testing.T) {
FILE: broker/options.go
type Options (line 12) | type Options struct
type PublishOptions (line 33) | type PublishOptions struct
type SubscribeOptions (line 39) | type SubscribeOptions struct
type Option (line 54) | type Option
type PublishOption (line 56) | type PublishOption
function PublishContext (line 59) | func PublishContext(ctx context.Context) PublishOption {
type SubscribeOption (line 65) | type SubscribeOption
function NewOptions (line 67) | func NewOptions(opts ...Option) *Options {
function NewSubscribeOptions (line 80) | func NewSubscribeOptions(opts ...SubscribeOption) SubscribeOptions {
function Addrs (line 93) | func Addrs(addrs ...string) Option {
function Codec (line 101) | func Codec(c codec.Marshaler) Option {
function DisableAutoAck (line 109) | func DisableAutoAck() SubscribeOption {
function ErrorHandler (line 117) | func ErrorHandler(h Handler) Option {
function Queue (line 124) | func Queue(name string) SubscribeOption {
function Registry (line 130) | func Registry(r registry.Registry) Option {
function Secure (line 137) | func Secure(b bool) Option {
function TLSConfig (line 144) | func TLSConfig(t *tls.Config) Option {
function Logger (line 151) | func Logger(l logger.Logger) Option {
function SubscribeContext (line 158) | func SubscribeContext(ctx context.Context) SubscribeOption {
FILE: broker/rabbitmq/auth.go
type ExternalAuthentication (line 3) | type ExternalAuthentication struct
method Mechanism (line 6) | func (auth *ExternalAuthentication) Mechanism() string {
method Response (line 10) | func (auth *ExternalAuthentication) Response() string {
FILE: broker/rabbitmq/channel.go
type rabbitMQChannel (line 15) | type rabbitMQChannel struct
method Connect (line 38) | func (r *rabbitMQChannel) Connect(prefetchCount int, prefetchGlobal bo...
method Close (line 62) | func (r *rabbitMQChannel) Close() error {
method Publish (line 69) | func (r *rabbitMQChannel) Publish(exchange, key string, message amqp.P...
method DeclareExchange (line 98) | func (r *rabbitMQChannel) DeclareExchange(ex Exchange) error {
method DeclareDurableExchange (line 110) | func (r *rabbitMQChannel) DeclareDurableExchange(ex Exchange) error {
method DeclareQueue (line 122) | func (r *rabbitMQChannel) DeclareQueue(queue string, args amqp.Table) ...
method DeclareDurableQueue (line 134) | func (r *rabbitMQChannel) DeclareDurableQueue(queue string, args amqp....
method DeclareReplyQueue (line 146) | func (r *rabbitMQChannel) DeclareReplyQueue(queue string) error {
method ConsumeQueue (line 158) | func (r *rabbitMQChannel) ConsumeQueue(queue string, autoAck bool) (<-...
method BindQueue (line 170) | func (r *rabbitMQChannel) BindQueue(queue, key, exchange string, args ...
function newRabbitChannel (line 23) | func newRabbitChannel(conn *amqp.Connection, prefetchCount int, prefetch...
FILE: broker/rabbitmq/connection.go
type MQExchangeType (line 18) | type MQExchangeType
constant ExchangeTypeFanout (line 21) | ExchangeTypeFanout MQExchangeType = "fanout"
constant ExchangeTypeTopic (line 22) | ExchangeTypeTopic = "topic"
constant ExchangeTypeDirect (line 23) | ExchangeTypeDirect = "direct"
type rabbitMQConn (line 54) | type rabbitMQConn struct
method connect (line 109) | func (r *rabbitMQConn) connect(secure bool, config *amqp.Config) error {
method reconnect (line 125) | func (r *rabbitMQConn) reconnect(secure bool, config *amqp.Config) {
method Connect (line 186) | func (r *rabbitMQConn) Connect(secure bool, config *amqp.Config) error {
method Close (line 209) | func (r *rabbitMQConn) Close() error {
method tryConnect (line 224) | func (r *rabbitMQConn) tryConnect(secure bool, config *amqp.Config) er...
method Consume (line 263) | func (r *rabbitMQConn) Consume(queue, key string, headers amqp.Table, ...
method Publish (line 294) | func (r *rabbitMQConn) Publish(exchange, key string, msg amqp.Publishi...
type Exchange (line 75) | type Exchange struct
function newRabbitMQConn (line 84) | func newRabbitMQConn(ex Exchange, urls []string, prefetchCount int, pref...
FILE: broker/rabbitmq/connection_test.go
function TestNewRabbitMQConnURL (line 12) | func TestNewRabbitMQConnURL(t *testing.T) {
function TestTryToConnectTLS (line 34) | func TestTryToConnectTLS(t *testing.T) {
function TestNewRabbitMQPrefetchConfirmPublish (line 81) | func TestNewRabbitMQPrefetchConfirmPublish(t *testing.T) {
FILE: broker/rabbitmq/context.go
function setSubscribeOption (line 11) | func setSubscribeOption(k, v interface{}) broker.SubscribeOption {
function setBrokerOption (line 21) | func setBrokerOption(k, v interface{}) broker.Option {
function setServerSubscriberOption (line 31) | func setServerSubscriberOption(k, v interface{}) server.SubscriberOption {
function setPublishOption (line 41) | func setPublishOption(k, v interface{}) broker.PublishOption {
FILE: broker/rabbitmq/options.go
type durableQueueKey (line 12) | type durableQueueKey struct
type headersKey (line 13) | type headersKey struct
type queueArgumentsKey (line 14) | type queueArgumentsKey struct
type prefetchCountKey (line 15) | type prefetchCountKey struct
type prefetchGlobalKey (line 16) | type prefetchGlobalKey struct
type confirmPublishKey (line 17) | type confirmPublishKey struct
type exchangeKey (line 18) | type exchangeKey struct
type exchangeTypeKey (line 19) | type exchangeTypeKey struct
type withoutExchangeKey (line 20) | type withoutExchangeKey struct
type requeueOnErrorKey (line 21) | type requeueOnErrorKey struct
type deliveryMode (line 22) | type deliveryMode struct
type priorityKey (line 23) | type priorityKey struct
type contentType (line 24) | type contentType struct
type contentEncoding (line 25) | type contentEncoding struct
type correlationID (line 26) | type correlationID struct
type replyTo (line 27) | type replyTo struct
type expiration (line 28) | type expiration struct
type messageID (line 29) | type messageID struct
type timestamp (line 30) | type timestamp struct
type typeMsg (line 31) | type typeMsg struct
type userID (line 32) | type userID struct
type appID (line 33) | type appID struct
type externalAuth (line 34) | type externalAuth struct
type durableExchange (line 35) | type durableExchange struct
function ServerDurableQueue (line 38) | func ServerDurableQueue() server.SubscriberOption {
function ServerAckOnSuccess (line 43) | func ServerAckOnSuccess() server.SubscriberOption {
function DurableQueue (line 48) | func DurableQueue() broker.SubscribeOption {
function DurableExchange (line 53) | func DurableExchange() broker.Option {
function Headers (line 58) | func Headers(h map[string]interface{}) broker.SubscribeOption {
function QueueArguments (line 63) | func QueueArguments(h map[string]interface{}) broker.SubscribeOption {
function RequeueOnError (line 67) | func RequeueOnError() broker.SubscribeOption {
function ExchangeName (line 72) | func ExchangeName(e string) broker.Option {
function WithoutExchange (line 78) | func WithoutExchange() broker.Option {
function ExchangeType (line 83) | func ExchangeType(t MQExchangeType) broker.Option {
function PrefetchCount (line 88) | func PrefetchCount(c int) broker.Option {
function PrefetchGlobal (line 93) | func PrefetchGlobal() broker.Option {
function ConfirmPublish (line 98) | func ConfirmPublish() broker.Option {
function DeliveryMode (line 103) | func DeliveryMode(value uint8) broker.PublishOption {
function Priority (line 108) | func Priority(value uint8) broker.PublishOption {
function ContentType (line 113) | func ContentType(value string) broker.PublishOption {
function ContentEncoding (line 118) | func ContentEncoding(value string) broker.PublishOption {
function CorrelationID (line 123) | func CorrelationID(value string) broker.PublishOption {
function ReplyTo (line 128) | func ReplyTo(value string) broker.PublishOption {
function Expiration (line 133) | func Expiration(value string) broker.PublishOption {
function MessageId (line 138) | func MessageId(value string) broker.PublishOption {
function Timestamp (line 143) | func Timestamp(value time.Time) broker.PublishOption {
function TypeMsg (line 148) | func TypeMsg(value string) broker.PublishOption {
function UserID (line 153) | func UserID(value string) broker.PublishOption {
function AppID (line 158) | func AppID(value string) broker.PublishOption {
function ExternalAuth (line 162) | func ExternalAuth() broker.Option {
type subscribeContextKey (line 166) | type subscribeContextKey struct
function SubscribeContext (line 169) | func SubscribeContext(ctx context.Context) broker.SubscribeOption {
type ackSuccessKey (line 173) | type ackSuccessKey struct
function AckOnSuccess (line 176) | func AckOnSuccess() broker.SubscribeOption {
function PublishDeliveryMode (line 182) | func PublishDeliveryMode(mode uint8) client.PublishOption {
FILE: broker/rabbitmq/rabbitmq.go
type rbroker (line 17) | type rbroker struct
method Publish (line 165) | func (r *rbroker) Publish(topic string, msg *broker.Message, opts ...b...
method Subscribe (line 242) | func (r *rbroker) Subscribe(topic string, handler broker.Handler, opts...
method Options (line 322) | func (r *rbroker) Options() broker.Options {
method String (line 326) | func (r *rbroker) String() string {
method Address (line 330) | func (r *rbroker) Address() string {
method Init (line 342) | func (r *rbroker) Init(opts ...broker.Option) error {
method Connect (line 350) | func (r *rbroker) Connect() error {
method Disconnect (line 374) | func (r *rbroker) Disconnect() error {
method getExchange (line 399) | func (r *rbroker) getExchange() Exchange {
method getPrefetchCount (line 417) | func (r *rbroker) getPrefetchCount() int {
method getPrefetchGlobal (line 424) | func (r *rbroker) getPrefetchGlobal() bool {
method getConfirmPublish (line 431) | func (r *rbroker) getConfirmPublish() bool {
method getWithoutExchange (line 438) | func (r *rbroker) getWithoutExchange() bool {
type subscriber (line 27) | type subscriber struct
method Options (line 64) | func (s *subscriber) Options() broker.SubscribeOptions {
method Topic (line 68) | func (s *subscriber) Topic() string {
method Unsubscribe (line 72) | func (s *subscriber) Unsubscribe() error {
method resubscribe (line 90) | func (s *subscriber) resubscribe() {
type publication (line 41) | type publication struct
method Ack (line 48) | func (p *publication) Ack() error {
method Error (line 52) | func (p *publication) Error() error {
method Topic (line 56) | func (p *publication) Topic() string {
method Message (line 60) | func (p *publication) Message() *broker.Message {
function NewBroker (line 383) | func NewBroker(opts ...broker.Option) broker.Broker {
FILE: broker/rabbitmq/rabbitmq_test.go
type Example (line 18) | type Example struct
method Handler (line 30) | func (e *Example) Handler(ctx context.Context, r interface{}) error {
function init (line 20) | func init() {
type TestEvent (line 24) | type TestEvent struct
function TestDurable (line 34) | func TestDurable(t *testing.T) {
function TestWithoutExchange (line 74) | func TestWithoutExchange(t *testing.T) {
function TestFanoutExchange (line 133) | func TestFanoutExchange(t *testing.T) {
function TestDirectExchange (line 191) | func TestDirectExchange(t *testing.T) {
function TestTopicExchange (line 249) | func TestTopicExchange(t *testing.T) {
FILE: cache/cache.go
type Cache (line 25) | type Cache interface
type Item (line 37) | type Item struct
method Expired (line 43) | func (i *Item) Expired() bool {
function NewCache (line 52) | func NewCache(opts ...Option) Cache {
FILE: cache/memory.go
type memCache (line 9) | type memCache struct
method Get (line 16) | func (c *memCache) Get(ctx context.Context, key string) (interface{}, ...
method Put (line 31) | func (c *memCache) Put(ctx context.Context, key string, val interface{...
method Delete (line 51) | func (c *memCache) Delete(ctx context.Context, key string) error {
method String (line 64) | func (m *memCache) String() string {
FILE: cache/memory_test.go
function TestCache (line 16) | func TestCache(t *testing.T) {
function TestCacheWithOptions (line 88) | func TestCacheWithOptions(t *testing.T) {
FILE: cache/options.go
type Options (line 11) | type Options struct
type Option (line 23) | type Option
function Expiration (line 26) | func Expiration(d time.Duration) Option {
function Items (line 33) | func Items(i map[string]Item) Option {
function WithAddress (line 40) | func WithAddress(addr string) Option {
function WithContext (line 47) | func WithContext(c context.Context) Option {
function WithLogger (line 54) | func WithLogger(l logger.Logger) Option {
function NewOptions (line 61) | func NewOptions(opts ...Option) Options {
FILE: cache/options_test.go
function TestOptions (line 8) | func TestOptions(t *testing.T) {
FILE: cache/redis/options.go
type redisOptionsContextKey (line 10) | type redisOptionsContextKey struct
function WithRedisOptions (line 13) | func WithRedisOptions(options rclient.UniversalOptions) cache.Option {
function newUniversalClient (line 23) | func newUniversalClient(options cache.Options) rclient.UniversalClient {
FILE: cache/redis/options_test.go
function Test_newUniversalClient (line 12) | func Test_newUniversalClient(t *testing.T) {
function Test_newUniversalClientCluster (line 92) | func Test_newUniversalClientCluster(t *testing.T) {
FILE: cache/redis/redis.go
function NewRedisCache (line 12) | func NewRedisCache(opts ...cache.Option) cache.Cache {
type redisCache (line 20) | type redisCache struct
method Get (line 25) | func (c *redisCache) Get(ctx context.Context, key string) (interface{}...
method Put (line 47) | func (c *redisCache) Put(ctx context.Context, key string, val interfac...
method Delete (line 51) | func (c *redisCache) Delete(ctx context.Context, key string) error {
method String (line 55) | func (m *redisCache) String() string {
FILE: cache/redis/redis_test.go
function TestCache (line 20) | func TestCache(t *testing.T) {
FILE: client/backoff.go
type BackoffFunc (line 10) | type BackoffFunc
function exponentialBackoff (line 12) | func exponentialBackoff(ctx context.Context, req Request, attempts int) ...
FILE: client/backoff_test.go
function TestBackoff (line 9) | func TestBackoff(t *testing.T) {
FILE: client/cache.go
function NewCache (line 17) | func NewCache() *Cache {
type Cache (line 24) | type Cache struct
method Get (line 29) | func (c *Cache) Get(ctx context.Context, req *Request) (interface{}, b...
method Set (line 34) | func (c *Cache) Set(ctx context.Context, req *Request, rsp interface{}...
method List (line 39) | func (c *Cache) List() map[string]string {
function key (line 53) | func key(ctx context.Context, req *Request) string {
FILE: client/cache_test.go
function TestCache (line 12) | func TestCache(t *testing.T) {
function TestCacheKey (line 36) | func TestCacheKey(t *testing.T) {
FILE: client/client.go
type Client (line 20) | type Client interface
type Router (line 32) | type Router interface
type Message (line 37) | type Message interface
type Request (line 44) | type Request interface
type Response (line 62) | type Response interface
type Stream (line 72) | type Stream interface
type Closer (line 91) | type Closer interface
type Option (line 97) | type Option
type CallOption (line 100) | type CallOption
type PublishOption (line 103) | type PublishOption
type MessageOption (line 106) | type MessageOption
type RequestOption (line 109) | type RequestOption
function Call (line 112) | func Call(ctx context.Context, request Request, response interface{}, op...
function Publish (line 118) | func Publish(ctx context.Context, msg Message, opts ...PublishOption) er...
function NewMessage (line 123) | func NewMessage(topic string, payload interface{}, opts ...MessageOption...
function NewRequest (line 129) | func NewRequest(service, endpoint string, request interface{}, reqOpts ....
function NewStream (line 135) | func NewStream(ctx context.Context, request Request, opts ...CallOption)...
function String (line 139) | func String() string {
FILE: client/context.go
type clientKey (line 7) | type clientKey struct
function FromContext (line 9) | func FromContext(ctx context.Context) (Client, bool) {
function NewContext (line 14) | func NewContext(ctx context.Context, c Client) context.Context {
FILE: client/grpc/codec.go
type jsonCodec (line 19) | type jsonCodec struct
method Marshal (line 116) | func (jsonCodec) Marshal(v interface{}) ([]byte, error) {
method Unmarshal (line 132) | func (jsonCodec) Unmarshal(data []byte, v interface{}) error {
method Name (line 151) | func (jsonCodec) Name() string {
type protoCodec (line 20) | type protoCodec struct
method Marshal (line 65) | func (protoCodec) Marshal(v interface{}) ([]byte, error) {
method Unmarshal (line 79) | func (protoCodec) Unmarshal(data []byte, v interface{}) error {
method Name (line 91) | func (protoCodec) Name() string {
type bytesCodec (line 21) | type bytesCodec struct
method Marshal (line 95) | func (bytesCodec) Marshal(v interface{}) ([]byte, error) {
method Unmarshal (line 103) | func (bytesCodec) Unmarshal(data []byte, v interface{}) error {
method Name (line 112) | func (bytesCodec) Name() string {
type wrapCodec (line 22) | type wrapCodec struct
method String (line 44) | func (w wrapCodec) String() string {
method Marshal (line 48) | func (w wrapCodec) Marshal(v interface{}) ([]byte, error) {
method Unmarshal (line 56) | func (w wrapCodec) Unmarshal(data []byte, v interface{}) error {
function UseNumber (line 40) | func UseNumber() {
type grpcCodec (line 155) | type grpcCodec struct
method ReadHeader (line 166) | func (g *grpcCodec) ReadHeader(m *codec.Message, mt codec.MessageType)...
method ReadBody (line 187) | func (g *grpcCodec) ReadBody(v interface{}) error {
method Write (line 194) | func (g *grpcCodec) Write(m *codec.Message, v interface{}) error {
method Close (line 203) | func (g *grpcCodec) Close() error {
method String (line 207) | func (g *grpcCodec) String() string {
FILE: client/grpc/error.go
function microError (line 11) | func microError(err error) error {
function microStatusFromGrpcCode (line 42) | func microStatusFromGrpcCode(code codes.Code) int32 {
FILE: client/grpc/grpc.go
type grpcClient (line 29) | type grpcClient struct
method secure (line 44) | func (g *grpcClient) secure(addr string) grpc.DialOption {
method next (line 77) | func (g *grpcClient) next(request client.Request, opts client.CallOpti...
method call (line 101) | func (g *grpcClient) call(ctx context.Context, node *registry.Node, re...
method stream (line 186) | func (g *grpcClient) stream(ctx context.Context, node *registry.Node, ...
method poolMaxStreams (line 305) | func (g *grpcClient) poolMaxStreams() int {
method poolMaxIdle (line 316) | func (g *grpcClient) poolMaxIdle() int {
method maxRecvMsgSizeValue (line 327) | func (g *grpcClient) maxRecvMsgSizeValue() int {
method maxSendMsgSizeValue (line 338) | func (g *grpcClient) maxSendMsgSizeValue() int {
method newGRPCCodec (line 349) | func (g *grpcClient) newGRPCCodec(contentType string) (encoding.Codec,...
method Init (line 365) | func (g *grpcClient) Init(opts ...client.Option) error {
method Options (line 384) | func (g *grpcClient) Options() client.Options {
method NewMessage (line 388) | func (g *grpcClient) NewMessage(topic string, msg interface{}, opts .....
method NewRequest (line 392) | func (g *grpcClient) NewRequest(service, method string, req interface{...
method Call (line 396) | func (g *grpcClient) Call(ctx context.Context, req client.Request, rsp...
method Stream (line 508) | func (g *grpcClient) Stream(ctx context.Context, req client.Request, o...
method Publish (line 605) | func (g *grpcClient) Publish(ctx context.Context, p client.Message, op...
method String (line 657) | func (g *grpcClient) String() string {
method getGrpcDialOptions (line 661) | func (g *grpcClient) getGrpcDialOptions() []grpc.DialOption {
function init (line 35) | func init() {
function newClient (line 681) | func newClient(opts ...client.Option) client.Client {
function NewClient (line 707) | func NewClient(opts ...client.Option) client.Client {
FILE: client/grpc/grpc_pool.go
type pool (line 12) | type pool struct
method getConn (line 70) | func (p *pool) getConn(dialCtx context.Context, addr string, opts ...g...
method release (line 155) | func (p *pool) release(addr string, conn *poolConn, err error) {
type streamsPool (line 25) | type streamsPool struct
type poolConn (line 36) | type poolConn struct
method Close (line 190) | func (conn *poolConn) Close() {
function newPool (line 54) | func newPool(size int, ttl time.Duration, idle int, ms int) *pool {
function removeConn (line 194) | func removeConn(conn *poolConn) {
function addConnAfter (line 208) | func addConnAfter(conn *poolConn, after *poolConn) {
FILE: client/grpc/grpc_pool_test.go
function testPool (line 13) | func testPool(t *testing.T, size int, ttl time.Duration, idle int, ms in...
function TestGRPCPool (line 60) | func TestGRPCPool(t *testing.T) {
FILE: client/grpc/grpc_test.go
type greeterServer (line 17) | type greeterServer struct
method SayHello (line 22) | func (g *greeterServer) SayHello(ctx context.Context, in *pb.HelloRequ...
function TestGRPCClient (line 29) | func TestGRPCClient(t *testing.T) {
FILE: client/grpc/message.go
type grpcEvent (line 7) | type grpcEvent struct
method ContentType (line 30) | func (g *grpcEvent) ContentType() string {
method Topic (line 34) | func (g *grpcEvent) Topic() string {
method Payload (line 38) | func (g *grpcEvent) Payload() interface{} {
function newGRPCEvent (line 13) | func newGRPCEvent(topic string, payload interface{}, contentType string,...
FILE: client/grpc/options.go
type poolMaxStreams (line 31) | type poolMaxStreams struct
type poolMaxIdle (line 32) | type poolMaxIdle struct
type codecsKey (line 33) | type codecsKey struct
type tlsAuth (line 34) | type tlsAuth struct
type maxRecvMsgSizeKey (line 35) | type maxRecvMsgSizeKey struct
type maxSendMsgSizeKey (line 36) | type maxSendMsgSizeKey struct
type grpcDialOptions (line 37) | type grpcDialOptions struct
type grpcCallOptions (line 38) | type grpcCallOptions struct
function PoolMaxStreams (line 41) | func PoolMaxStreams(n int) client.Option {
function PoolMaxIdle (line 51) | func PoolMaxIdle(d int) client.Option {
function Codec (line 61) | func Codec(contentType string, c encoding.Codec) client.Option {
function AuthTLS (line 76) | func AuthTLS(t *tls.Config) client.Option {
function MaxRecvMsgSize (line 86) | func MaxRecvMsgSize(s int) client.Option {
function MaxSendMsgSize (line 96) | func MaxSendMsgSize(s int) client.Option {
function DialOptions (line 106) | func DialOptions(opts ...grpc.DialOption) client.CallOption {
function CallOptions (line 116) | func CallOptions(opts ...grpc.CallOption) client.CallOption {
function callOpts (line 125) | func callOpts(opts client.CallOptions) []grpc.CallOption {
FILE: client/grpc/request.go
type grpcRequest (line 11) | type grpcRequest struct
method ContentType (line 61) | func (g *grpcRequest) ContentType() string {
method Service (line 65) | func (g *grpcRequest) Service() string {
method Method (line 69) | func (g *grpcRequest) Method() string {
method Endpoint (line 73) | func (g *grpcRequest) Endpoint() string {
method Codec (line 77) | func (g *grpcRequest) Codec() codec.Writer {
method Body (line 81) | func (g *grpcRequest) Body() interface{} {
method Stream (line 85) | func (g *grpcRequest) Stream() bool {
function methodToGRPC (line 21) | func methodToGRPC(service, method string) string {
function newGRPCRequest (line 41) | func newGRPCRequest(service, method string, request interface{}, content...
FILE: client/grpc/request_test.go
function TestMethodToGRPC (line 7) | func TestMethodToGRPC(t *testing.T) {
FILE: client/grpc/response.go
type response (line 12) | type response struct
method Codec (line 20) | func (r *response) Codec() codec.Reader {
method Header (line 25) | func (r *response) Header() map[string]string {
method Read (line 38) | func (r *response) Read() ([]byte, error) {
FILE: client/grpc/stream.go
type grpcStream (line 13) | type grpcStream struct
method Context (line 25) | func (g *grpcStream) Context() context.Context {
method Request (line 29) | func (g *grpcStream) Request() client.Request {
method Response (line 33) | func (g *grpcStream) Response() client.Response {
method Send (line 37) | func (g *grpcStream) Send(msg interface{}) error {
method Recv (line 45) | func (g *grpcStream) Recv(msg interface{}) (err error) {
method Error (line 55) | func (g *grpcStream) Error() error {
method setError (line 61) | func (g *grpcStream) setError(e error) {
method CloseSend (line 67) | func (g *grpcStream) CloseSend() error {
method Close (line 71) | func (g *grpcStream) Close() error {
FILE: client/options.go
type Options (line 35) | type Options struct
type CallOptions (line 74) | type CallOptions struct
type PublishOptions (line 110) | type PublishOptions struct
type MessageOptions (line 118) | type MessageOptions struct
type RequestOptions (line 122) | type RequestOptions struct
function NewOptions (line 132) | func NewOptions(options ...Option) Options {
function Broker (line 164) | func Broker(b broker.Broker) Option {
function Codec (line 171) | func Codec(contentType string, c codec.NewCodec) Option {
function ContentType (line 178) | func ContentType(ct string) Option {
function PoolSize (line 185) | func PoolSize(d int) Option {
function PoolTTL (line 192) | func PoolTTL(d time.Duration) Option {
function PoolCloseTimeout (line 199) | func PoolCloseTimeout(d time.Duration) Option {
function Registry (line 206) | func Registry(r registry.Registry) Option {
function Transport (line 215) | func Transport(t transport.Transport) Option {
function Selector (line 222) | func Selector(s selector.Selector) Option {
function Wrap (line 229) | func Wrap(w Wrapper) Option {
function WrapCall (line 236) | func WrapCall(cw ...CallWrapper) Option {
function Backoff (line 244) | func Backoff(fn BackoffFunc) Option {
function Retries (line 251) | func Retries(i int) Option {
function Retry (line 258) | func Retry(fn RetryFunc) Option {
function ConnectionTimeout (line 265) | func ConnectionTimeout(t time.Duration) Option {
function RequestTimeout (line 272) | func RequestTimeout(d time.Duration) Option {
function StreamTimeout (line 279) | func StreamTimeout(d time.Duration) Option {
function DialTimeout (line 286) | func DialTimeout(d time.Duration) Option {
function WithExchange (line 295) | func WithExchange(e string) PublishOption {
function PublishContext (line 302) | func PublishContext(ctx context.Context) PublishOption {
function WithAddress (line 309) | func WithAddress(a ...string) CallOption {
function WithSelectOption (line 315) | func WithSelectOption(so ...selector.SelectOption) CallOption {
function WithCallWrapper (line 322) | func WithCallWrapper(cw ...CallWrapper) CallOption {
function WithBackoff (line 330) | func WithBackoff(fn BackoffFunc) CallOption {
function WithRetry (line 338) | func WithRetry(fn RetryFunc) CallOption {
function WithRetries (line 346) | func WithRetries(i int) CallOption {
function WithRequestTimeout (line 354) | func WithRequestTimeout(d time.Duration) CallOption {
function WithConnClose (line 361) | func WithConnClose() CallOption {
function WithStreamTimeout (line 368) | func WithStreamTimeout(d time.Duration) CallOption {
function WithDialTimeout (line 376) | func WithDialTimeout(d time.Duration) CallOption {
function WithServiceToken (line 384) | func WithServiceToken() CallOption {
function WithCache (line 392) | func WithCache(c time.Duration) CallOption {
function WithMessageContentType (line 398) | func WithMessageContentType(ct string) MessageOption {
function WithConnectionTimeout (line 404) | func WithConnectionTimeout(d time.Duration) CallOption {
function WithContentType (line 412) | func WithContentType(ct string) RequestOption {
function StreamingRequest (line 418) | func StreamingRequest() RequestOption {
function WithRouter (line 425) | func WithRouter(r Router) Option {
function WithLogger (line 432) | func WithLogger(l logger.Logger) Option {
FILE: client/options_test.go
function TestCallOptions (line 10) | func TestCallOptions(t *testing.T) {
FILE: client/retry.go
type RetryFunc (line 10) | type RetryFunc
function RetryAlways (line 13) | func RetryAlways(ctx context.Context, req Request, retryCount int, err e...
function RetryOnError (line 18) | func RetryOnError(ctx context.Context, req Request, retryCount int, err ...
FILE: client/rpc_client.go
constant packageID (line 29) | packageID = "go.micro.client"
type rpcClient (line 32) | type rpcClient struct
method newCodec (line 67) | func (r *rpcClient) newCodec(contentType string) (codec.NewCodec, erro...
method call (line 79) | func (r *rpcClient) call(
method stream (line 236) | func (r *rpcClient) stream(ctx context.Context, node *registry.Node, r...
method Init (line 350) | func (r *rpcClient) Init(opts ...Option) error {
method Options (line 382) | func (r *rpcClient) Options() Options {
method next (line 390) | func (r *rpcClient) next(request Request, opts CallOptions) (selector....
method Call (line 427) | func (r *rpcClient) Call(ctx context.Context, request Request, respons...
method Stream (line 554) | func (r *rpcClient) Stream(ctx context.Context, request Request, opts ...
method Publish (line 655) | func (r *rpcClient) Publish(ctx context.Context, msg Message, opts ......
method NewMessage (line 729) | func (r *rpcClient) NewMessage(topic string, message interface{}, opts...
method NewRequest (line 733) | func (r *rpcClient) NewRequest(service, method string, request interfa...
method String (line 737) | func (r *rpcClient) String() string {
function newRPCClient (line 40) | func newRPCClient(opt ...Option) Client {
FILE: client/rpc_client_test.go
constant serviceName (line 14) | serviceName = "test.service"
constant serviceEndpoint (line 15) | serviceEndpoint = "Test.Endpoint"
function newTestRegistry (line 18) | func newTestRegistry() registry.Registry {
function TestCallAddress (line 22) | func TestCallAddress(t *testing.T) {
function TestCallRetry (line 71) | func TestCallRetry(t *testing.T) {
function TestCallWrapper (line 114) | func TestCallWrapper(t *testing.T) {
FILE: client/rpc_codec.go
constant lastStreamResponseError (line 21) | lastStreamResponseError = "EOS"
type serverError (line 26) | type serverError
method Error (line 28) | func (e serverError) Error() string {
type rpcCodec (line 37) | type rpcCodec struct
method Write (line 176) | func (c *rpcCodec) Write(message *codec.Message, body interface{}) err...
method ReadHeader (line 221) | func (c *rpcCodec) ReadHeader(msg *codec.Message, r codec.MessageType)...
method ReadBody (line 249) | func (c *rpcCodec) ReadBody(b interface{}) error {
method Close (line 264) | func (c *rpcCodec) Close() error {
method String (line 280) | func (c *rpcCodec) String() string {
type readWriteCloser (line 48) | type readWriteCloser struct
method Read (line 79) | func (rwc *readWriteCloser) Read(p []byte) (n int, err error) {
method Write (line 83) | func (rwc *readWriteCloser) Write(p []byte) (n int, err error) {
method Close (line 87) | func (rwc *readWriteCloser) Close() error {
function getHeaders (line 94) | func getHeaders(m *codec.Message) {
function setHeaders (line 116) | func setHeaders(m *codec.Message, stream string) {
function setupProtocol (line 137) | func setupProtocol(msg *transport.Message, node *registry.Node) codec.Ne...
function newRPCCodec (line 161) | func newRPCCodec(req *transport.Message, client transport.Client, c code...
FILE: client/rpc_message.go
type message (line 3) | type message struct
method ContentType (line 26) | func (m *message) ContentType() string {
method Topic (line 30) | func (m *message) Topic() string {
method Payload (line 34) | func (m *message) Payload() interface{} {
function newMessage (line 9) | func newMessage(topic string, payload interface{}, contentType string, o...
FILE: client/rpc_request.go
type rpcRequest (line 7) | type rpcRequest struct
method ContentType (line 39) | func (r *rpcRequest) ContentType() string {
method Service (line 43) | func (r *rpcRequest) Service() string {
method Method (line 47) | func (r *rpcRequest) Method() string {
method Endpoint (line 51) | func (r *rpcRequest) Endpoint() string {
method Body (line 55) | func (r *rpcRequest) Body() interface{} {
method Codec (line 59) | func (r *rpcRequest) Codec() codec.Writer {
method Stream (line 63) | func (r *rpcRequest) Stream() bool {
function newRequest (line 17) | func newRequest(service, endpoint string, request interface{}, contentTy...
FILE: client/rpc_request_test.go
function TestRequestOptions (line 7) | func TestRequestOptions(t *testing.T) {
FILE: client/rpc_response.go
type rpcResponse (line 8) | type rpcResponse struct
method Codec (line 15) | func (r *rpcResponse) Codec() codec.Reader {
method Header (line 19) | func (r *rpcResponse) Header() map[string]string {
method Read (line 23) | func (r *rpcResponse) Read() ([]byte, error) {
FILE: client/rpc_stream.go
type rpcStream (line 13) | type rpcStream struct
method isClosed (line 33) | func (r *rpcStream) isClosed() bool {
method Context (line 42) | func (r *rpcStream) Context() context.Context {
method Request (line 46) | func (r *rpcStream) Request() Request {
method Response (line 50) | func (r *rpcStream) Response() Response {
method Send (line 54) | func (r *rpcStream) Send(msg interface{}) error {
method Recv (line 79) | func (r *rpcStream) Recv(msg interface{}) error {
method Error (line 140) | func (r *rpcStream) Error() error {
method CloseSend (line 147) | func (r *rpcStream) CloseSend() error {
method Close (line 151) | func (r *rpcStream) Close() error {
FILE: client/wrapper.go
type CallFunc (line 10) | type CallFunc
type CallWrapper (line 13) | type CallWrapper
type Wrapper (line 16) | type Wrapper
type StreamWrapper (line 19) | type StreamWrapper
FILE: cmd/cmd.go
type Cmd (line 41) | type Cmd interface
type cmd (line 51) | type cmd struct
method App (line 375) | func (c *cmd) App() *cli.App {
method Options (line 379) | func (c *cmd) Options() Options {
method Before (line 383) | func (c *cmd) Before(ctx *cli.Context) error {
method setRegistry (line 701) | func (c *cmd) setRegistry(r registry.Registry) ([]server.Option, []cli...
method setStream (line 719) | func (c *cmd) setStream(s events.Stream) ([]server.Option, []client.Op...
method setBroker (line 730) | func (c *cmd) setBroker(b broker.Broker) ([]server.Option, []client.Op...
method setStore (line 739) | func (c *cmd) setStore(s store.Store) ([]server.Option, []client.Optio...
method setTransport (line 746) | func (c *cmd) setTransport(t transport.Transport) ([]server.Option, []...
method Init (line 755) | func (c *cmd) Init(opts ...Option) error {
type Option (line 56) | type Option
function init (line 298) | func init() {
function newCmd (line 301) | func newCmd(opts ...Option) Cmd {
function DefaultOptions (line 771) | func DefaultOptions() Options {
function App (line 775) | func App() *cli.App {
function Init (line 779) | func Init(opts ...Option) error {
function NewCmd (line 783) | func NewCmd(opts ...Option) Cmd {
function Register (line 788) | func Register(cmds ...*cli.Command) {
FILE: cmd/micro-mcp-gateway/main.go
function main (line 46) | func main() {
function run (line 114) | func run(c *cli.Context) error {
function newRegistry (line 206) | func newRegistry(name, address string) (registry.Registry, error) {
function parseScopes (line 224) | func parseScopes(raw []string) map[string][]string {
FILE: cmd/micro/cli/build/build.go
function Build (line 18) | func Build(c *cli.Context) error {
function buildService (line 79) | func buildService(name, dir, outDir, targetOS, targetArch string) error {
function Docker (line 108) | func Docker(c *cli.Context) error {
constant dockerfileTemplate (line 148) | dockerfileTemplate = `FROM golang:1.22-alpine AS builder
function buildDockerImage (line 162) | func buildDockerImage(name, dir string, port int, tag, registry string, ...
function Compose (line 208) | func Compose(c *cli.Context) error {
function init (line 275) | func init() {
FILE: cmd/micro/cli/cli.go
function genProtoHandler (line 32) | func genProtoHandler(c *cli.Context) error {
function init (line 39) | func init() {
FILE: cmd/micro/cli/deploy/deploy.go
constant defaultRemotePath (line 19) | defaultRemotePath = "/opt/micro"
function Deploy (line 23) | func Deploy(c *cli.Context) error {
function showDeployHelp (line 55) | func showDeployHelp() error {
function showDeployTargets (line 75) | func showDeployTargets(cfg *config.Config) error {
function deploySSH (line 85) | func deploySSH(c *cli.Context, target string, cfg *config.Config) error {
function prefixServices (line 218) | func prefixServices(services []string) []string {
function checkSSH (line 226) | func checkSSH(host string) error {
function checkServerInit (line 248) | func checkServerInit(host, remotePath string) error {
function buildBinaries (line 268) | func buildBinaries(absDir string, cfg *config.Config, forceBuild bool, s...
function copyBinaries (line 341) | func copyBinaries(target, binDir, remotePath string) error {
function setupSystemdServices (line 386) | func setupSystemdServices(target, remotePath string, services []string) ...
function restartServices (line 403) | func restartServices(target string, services []string) error {
function checkServicesHealth (line 414) | func checkServicesHealth(target string, services []string) (healthy, unh...
function checkPlatform (line 428) | func checkPlatform() error {
function init (line 435) | func init() {
FILE: cmd/micro/cli/gen/generate.go
type handlerData (line 107) | type handlerData struct
type methodData (line 112) | type methodData struct
type endpointData (line 118) | type endpointData struct
type modelData (line 124) | type modelData struct
function generateHandler (line 128) | func generateHandler(c *cli.Context) error {
function generateEndpoint (line 160) | func generateEndpoint(c *cli.Context) error {
function generateModel (line 179) | func generateModel(c *cli.Context) error {
function generateFile (line 192) | func generateFile(dir, filename, tmplStr string, data interface{}) error {
function init (line 229) | func init() {
FILE: cmd/micro/cli/init/init.go
constant systemdTemplate (line 17) | systemdTemplate = `[Unit]
function Init (line 47) | func Init(c *cli.Context) error {
function createMicroUser (line 152) | func createMicroUser() error {
function initRemote (line 171) | func initRemote(c *cli.Context, host string) error {
function checkSSH (line 196) | func checkSSH(host string) error {
function getHostname (line 219) | func getHostname() string {
function init (line 227) | func init() {
FILE: cmd/micro/cli/new/new.go
function protoComments (line 21) | func protoComments(goDir, alias string) []string {
type config (line 32) | type config struct
type file (line 49) | type file struct
function write (line 54) | func write(c config, file, tmpl string) error {
function create (line 81) | func create(c config) error {
function addFileToTree (line 121) | func addFileToTree(root treeprint.Tree, file string) {
function Run (line 137) | func Run(ctx *cli.Context) error {
function runInDir (line 240) | func runInDir(dir, cmd string) error {
function printTree (line 249) | func printTree(dir string) {
FILE: cmd/micro/cli/remote/remote.go
constant defaultRemotePath (line 17) | defaultRemotePath = "/opt/micro"
function Status (line 20) | func Status(c *cli.Context) error {
function localStatus (line 28) | func localStatus(c *cli.Context) error {
function remoteStatus (line 87) | func remoteStatus(host string) error {
function Logs (line 143) | func Logs(c *cli.Context) error {
function localLogs (line 155) | func localLogs(c *cli.Context, service string, follow bool, lines int) e...
function remoteLogs (line 202) | func remoteLogs(host, service string, follow bool, lines int) error {
function Stop (line 230) | func Stop(c *cli.Context) error {
function localStop (line 244) | func localStop(service string) error {
function remoteStop (line 286) | func remoteStop(host, service string) error {
function init (line 296) | func init() {
FILE: cmd/micro/cli/util/dynamic.go
function AddMetadataToContext (line 23) | func AddMetadataToContext(ctx context.Context, metadataStrings []string)...
function LookupService (line 46) | func LookupService(name string) (*registry.Service, error) {
function FormatServiceUsage (line 52) | func FormatServiceUsage(srv *registry.Service, c *cli.Context) string {
function lowercaseInitial (line 102) | func lowercaseInitial(str string) string {
function renderFlags (line 109) | func renderFlags(endpoint *registry.Endpoint) string {
function renderValue (line 117) | func renderValue(path []string, value *registry.Value) string {
function CallService (line 131) | func CallService(srv *registry.Service, args []string) error {
function splitCmdArgs (line 200) | func splitCmdArgs(arguments []string) ([]string, map[string][]string, er...
function constructEndpoint (line 243) | func constructEndpoint(args []string) (string, error) {
function ShouldRenderHelp (line 262) | func ShouldRenderHelp(args []string) bool {
function FlagsToRequest (line 285) | func FlagsToRequest(flags map[string][]string, req *registry.Value) (map...
function serviceWithName (line 436) | func serviceWithName(name string) (*registry.Service, error) {
FILE: cmd/micro/cli/util/dynamic_test.go
type parseCase (line 14) | type parseCase struct
function TestDynamicFlagParsing (line 20) | func TestDynamicFlagParsing(t *testing.T) {
function TestAddMetadataToContext (line 383) | func TestAddMetadataToContext(t *testing.T) {
FILE: cmd/micro/cli/util/util.go
type Exec (line 14) | type Exec
function Print (line 16) | func Print(e Exec) func(*cli.Context) error {
function CliError (line 30) | func CliError(err error) cli.ExitCoder {
FILE: cmd/micro/main.go
function init (line 20) | func init() {
function main (line 24) | func main() {
FILE: cmd/micro/mcp/mcp.go
function init (line 23) | func init() {
function serveAction (line 218) | func serveAction(ctx *cli.Context) error {
function listAction (line 253) | func listAction(ctx *cli.Context) error {
function testAction (line 320) | func testAction(ctx *cli.Context) error {
function parseTool (line 435) | func parseTool(toolName string) []string {
function docsAction (line 440) | func docsAction(ctx *cli.Context) error {
function exportAction (line 564) | func exportAction(ctx *cli.Context) error {
function exportLangChain (line 613) | func exportLangChain(writer *os.File, services []*registry.Service, opts...
function exportOpenAPI (line 675) | func exportOpenAPI(writer *os.File, services []*registry.Service, opts m...
function exportJSON (line 768) | func exportJSON(writer *os.File, services []*registry.Service, opts mcp....
FILE: cmd/micro/mcp/mcp_test.go
function TestParseTool (line 8) | func TestParseTool(t *testing.T) {
function TestExportFormats (line 51) | func TestExportFormats(t *testing.T) {
function TestDocsFormats (line 66) | func TestDocsFormats(t *testing.T) {
FILE: cmd/micro/run/config/config.go
type Config (line 15) | type Config struct
method TopologicalSort (line 224) | func (c *Config) TopologicalSort() ([]*Service, error) {
method GetEnv (line 279) | func (c *Config) GetEnv(name string) map[string]string {
type DeployTarget (line 22) | type DeployTarget struct
type Service (line 29) | type Service struct
function Load (line 37) | func Load(dir string) (*Config, error) {
function ParseJSON (line 54) | func ParseJSON(path string) (*Config, error) {
function ParseMu (line 88) | func ParseMu(path string) (*Config, error) {
FILE: cmd/micro/run/config/config_test.go
function TestParseMu (line 9) | func TestParseMu(t *testing.T) {
function TestParseJSON (line 93) | func TestParseJSON(t *testing.T) {
function TestTopologicalSort (line 137) | func TestTopologicalSort(t *testing.T) {
function TestCircularDependency (line 173) | func TestCircularDependency(t *testing.T) {
function TestLoad (line 187) | func TestLoad(t *testing.T) {
FILE: cmd/micro/run/run.go
constant colorReset (line 37) | colorReset = "\033[0m"
function colorFor (line 39) | func colorFor(idx int) string {
type serviceProcess (line 44) | type serviceProcess struct
method start (line 60) | func (s *serviceProcess) start(logDir string) error {
method stop (line 118) | func (s *serviceProcess) stop() {
method restart (line 152) | func (s *serviceProcess) restart(logDir string) error {
function waitForHealth (line 158) | func waitForHealth(port int, timeout time.Duration) bool {
function Run (line 177) | func Run(c *cli.Context) error {
function parsePid (line 413) | func parsePid(pidStr string) int {
function processRunning (line 418) | func processRunning(pidStr string) bool {
function printBanner (line 430) | func printBanner(services []*serviceProcess, gw *server.Gateway, watchin...
function init (line 472) | func init() {
FILE: cmd/micro/run/watcher/watcher.go
type Event (line 13) | type Event struct
type Watcher (line 19) | type Watcher struct
method Events (line 66) | func (w *Watcher) Events() <-chan Event {
method Start (line 71) | func (w *Watcher) Start() {
method Stop (line 79) | func (w *Watcher) Stop() {
method watch (line 83) | func (w *Watcher) watch() {
method scan (line 120) | func (w *Watcher) scan(notify bool) []string {
type Option (line 31) | type Option
function WithInterval (line 34) | func WithInterval(d time.Duration) Option {
function WithDebounce (line 41) | func WithDebounce(d time.Duration) Option {
function New (line 48) | func New(dirs []string, opts ...Option) *Watcher {
FILE: cmd/micro/server/gateway.go
function StartGateway (line 26) | func StartGateway(opts GatewayOptions) (*Gateway, error) {
function RunGateway (line 66) | func RunGateway(opts GatewayOptions) error {
FILE: cmd/micro/server/server.go
constant agentSystemPrompt (line 42) | agentSystemPrompt = "You are an agent that helps users interact with mic...
type templates (line 52) | type templates struct
type TemplateUser (line 66) | type TemplateUser struct
function parseTemplates (line 75) | func parseTemplates() *templates {
function getUser (line 93) | func getUser(r *http.Request) string {
function decodeSegment (line 121) | func decodeSegment(seg string) ([]byte, error) {
function decodeBase64Url (line 130) | func decodeBase64Url(s string) ([]byte, error) {
function storeJWTToken (line 135) | func storeJWTToken(storeInst store.Store, token, userID string) {
function isTokenRevoked (line 140) | func isTokenRevoked(storeInst store.Store, token string) bool {
function deleteUserTokens (line 146) | func deleteUserTokens(storeInst store.Store, userID string) {
function authRequired (line 156) | func authRequired(storeInst store.Store) func(http.HandlerFunc) http.Han...
function wrapAuth (line 243) | func wrapAuth(authRequired func(http.HandlerFunc) http.HandlerFunc) func...
function getDashboardData (line 257) | func getDashboardData() (serviceCount, runningCount, stoppedCount int, s...
function getSidebarEndpoints (line 306) | func getSidebarEndpoints() ([]map[string]string, error) {
function registerHandlers (line 331) | func registerHandlers(mux *http.ServeMux, tmpls *templates, storeInst st...
function Run (line 1507) | func Run(c *cli.Context) error {
function mapGoTypeToJSON (line 1528) | func mapGoTypeToJSON(goType string) string {
function parsePid (line 1544) | func parsePid(pidStr string) int {
function processRunning (line 1548) | func processRunning(pid string) bool {
function generateKeyPair (line 1557) | func generateKeyPair(bits int) (*rsa.PrivateKey, error) {
function exportPrivateKeyAsPEM (line 1564) | func exportPrivateKeyAsPEM(priv *rsa.PrivateKey) ([]byte, error) {
function exportPublicKeyAsPEM (line 1577) | func exportPublicKeyAsPEM(pub *rsa.PublicKey) ([]byte, error) {
function importPrivateKeyFromPEM (line 1590) | func importPrivateKeyFromPEM(privKeyPEM []byte) (*rsa.PrivateKey, error) {
function importPublicKeyFromPEM (line 1597) | func importPublicKeyFromPEM(pubKeyPEM []byte) (*rsa.PublicKey, error) {
function initAuth (line 1604) | func initAuth() error {
function parseStartTime (line 1648) | func parseStartTime(s string) (time.Time, error) {
function init (line 1651) | func init() {
FILE: cmd/micro/server/util_jwt.go
function InitJWTKeys (line 21) | func InitJWTKeys(privPath, pubPath string) error {
function GenerateJWT (line 65) | func GenerateJWT(userID, userType string, scopes []string, expiry time.D...
function ParseJWT (line 77) | func ParseJWT(tokenStr string) (jwt.MapClaims, error) {
FILE: cmd/options.go
type Options (line 21) | type Options struct
function Name (line 64) | func Name(n string) Option {
function Description (line 71) | func Description(d string) Option {
function Version (line 78) | func Version(v string) Option {
function Broker (line 84) | func Broker(b *broker.Broker) Option {
function Cache (line 90) | func Cache(c *cache.Cache) Option {
function Config (line 96) | func Config(c *config.Config) Option {
function Selector (line 102) | func Selector(s *selector.Selector) Option {
function Registry (line 108) | func Registry(r *registry.Registry) Option {
function Transport (line 114) | func Transport(t *transport.Transport) Option {
function Client (line 120) | func Client(c *client.Client) Option {
function Server (line 126) | func Server(s *server.Server) Option {
function Store (line 132) | func Store(s *store.Store) Option {
function Stream (line 138) | func Stream(s *events.Stream) Option {
function Tracer (line 144) | func Tracer(t *trace.Tracer) Option {
function Auth (line 150) | func Auth(a *auth.Auth) Option {
function Profile (line 156) | func Profile(p *profile.Profile) Option {
function NewBroker (line 163) | func NewBroker(name string, b func(...broker.Option) broker.Broker) Opti...
function NewStream (line 170) | func NewStream(name string, b func(...events.Option) events.Stream) Opti...
function NewCache (line 177) | func NewCache(name string, c func(...cache.Option) cache.Cache) Option {
function NewClient (line 184) | func NewClient(name string, b func(...client.Option) client.Client) Opti...
function NewRegistry (line 191) | func NewRegistry(name string, r func(...registry.Option) registry.Regist...
function NewSelector (line 198) | func NewSelector(name string, s func(...selector.Option) selector.Select...
function NewServer (line 205) | func NewServer(name string, s func(...server.Option) server.Server) Opti...
function NewTransport (line 212) | func NewTransport(name string, t func(...transport.Option) transport.Tra...
function NewTracer (line 219) | func NewTracer(name string, t func(...trace.Option) trace.Tracer) Option {
function NewAuth (line 226) | func NewAuth(name string, t func(...auth.Option) auth.Auth) Option {
function NewConfig (line 233) | func NewConfig(name string, t func(...config.Option) (config.Config, err...
function NewProfile (line 240) | func NewProfile(name string, t func(...profile.Option) profile.Profile) ...
FILE: cmd/protoc-gen-micro/examples/greeter/greeter.pb.go
constant _ (line 18) | _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
constant _ (line 20) | _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
type Request (line 23) | type Request struct
method Reset (line 32) | func (x *Request) Reset() {
method String (line 41) | func (x *Request) String() string {
method ProtoMessage (line 45) | func (*Request) ProtoMessage() {}
method ProtoReflect (line 47) | func (x *Request) ProtoReflect() protoreflect.Message {
method Descriptor (line 60) | func (*Request) Descriptor() ([]byte, []int) {
method GetName (line 64) | func (x *Request) GetName() string {
method GetMsg (line 71) | func (x *Request) GetMsg() string {
type Response (line 78) | type Response struct
method Reset (line 86) | func (x *Response) Reset() {
method String (line 95) | func (x *Response) String() string {
method ProtoMessage (line 99) | func (*Response) ProtoMessage() {}
method ProtoReflect (line 101) | func (x *Response) ProtoReflect() protoreflect.Message {
method Descriptor (line 114) | func (*Response) Descriptor() ([]byte, []int) {
method GetMsg (line 118) | func (x *Response) GetMsg() string {
function file_greeter_proto_rawDescGZIP (line 149) | func file_greeter_proto_rawDescGZIP() []byte {
function init (line 173) | func init() { file_greeter_proto_init() }
function file_greeter_proto_init (line 174) | func file_greeter_proto_init() {
FILE: cmd/protoc-gen-micro/examples/greeter/greeter.pb.micro.go
type GreeterService (line 30) | type GreeterService interface
type greeterService (line 35) | type greeterService struct
method Hello (line 47) | func (c *greeterService) Hello(ctx context.Context, in *Request, opts ...
method Stream (line 57) | func (c *greeterService) Stream(ctx context.Context, opts ...client.Ca...
function NewGreeterService (line 40) | func NewGreeterService(name string, c client.Client) GreeterService {
type Greeter_StreamService (line 66) | type Greeter_StreamService interface
type greeterServiceStream (line 76) | type greeterServiceStream struct
method CloseSend (line 80) | func (x *greeterServiceStream) CloseSend() error {
method Close (line 84) | func (x *greeterServiceStream) Close() error {
method Context (line 88) | func (x *greeterServiceStream) Context() context.Context {
method SendMsg (line 92) | func (x *greeterServiceStream) SendMsg(m interface{}) error {
method RecvMsg (line 96) | func (x *greeterServiceStream) RecvMsg(m interface{}) error {
method Send (line 100) | func (x *greeterServiceStream) Send(m *Request) error {
method Recv (line 104) | func (x *greeterServiceStream) Recv() (*Response, error) {
type GreeterHandler (line 115) | type GreeterHandler interface
function RegisterGreeterHandler (line 120) | func RegisterGreeterHandler(s server.Server, hdlr GreeterHandler, opts ....
type greeterHandler (line 132) | type greeterHandler struct
method Hello (line 136) | func (h *greeterHandler) Hello(ctx context.Context, in *Request, out *...
method Stream (line 140) | func (h *greeterHandler) Stream(ctx context.Context, stream server.Str...
type Greeter_StreamStream (line 144) | type Greeter_StreamStream interface
type greeterStreamStream (line 153) | type greeterStreamStream struct
method Close (line 157) | func (x *greeterStreamStream) Close() error {
method Context (line 161) | func (x *greeterStreamStream) Context() context.Context {
method SendMsg (line 165) | func (x *greeterStreamStream) SendMsg(m interface{}) error {
method RecvMsg (line 169) | func (x *greeterStreamStream) RecvMsg(m interface{}) error {
method Send (line 173) | func (x *greeterStreamStream) Send(m *Response) error {
method Recv (line 177) | func (x *greeterStreamStream) Recv() (*Request, error) {
FILE: cmd/protoc-gen-micro/generator/generator.go
type Plugin (line 71) | type Plugin interface
function RegisterPlugin (line 89) | func RegisterPlugin(p Plugin) {
type GoImportPath (line 94) | type GoImportPath
method String (line 96) | func (p GoImportPath) String() string { return strconv.Quote(string(p)) }
type GoPackageName (line 99) | type GoPackageName
type common (line 108) | type common struct
method GoImportPath (line 113) | func (c *common) GoImportPath() GoImportPath {
method File (line 117) | func (c *common) File() *FileDescriptor { return c.file }
method proto3 (line 123) | func (c *common) proto3() bool { return fileIsProto3(c.file.FileDescri...
function fileIsProto3 (line 119) | func fileIsProto3(file *descriptor.FileDescriptorProto) bool {
type Descriptor (line 126) | type Descriptor struct
method TypeName (line 141) | func (d *Descriptor) TypeName() []string {
type EnumDescriptor (line 160) | type EnumDescriptor struct
method TypeName (line 171) | func (e *EnumDescriptor) TypeName() (s []string) {
method prefix (line 190) | func (e *EnumDescriptor) prefix() string {
method integerValueAsString (line 200) | func (e *EnumDescriptor) integerValueAsString(name string) string {
type ExtensionDescriptor (line 212) | type ExtensionDescriptor struct
method TypeName (line 220) | func (e *ExtensionDescriptor) TypeName() (s []string) {
method DescName (line 235) | func (e *ExtensionDescriptor) DescName() string {
type ImportedDescriptor (line 246) | type ImportedDescriptor struct
method TypeName (line 251) | func (id *ImportedDescriptor) TypeName() []string { return id.o.TypeNa...
type FileDescriptor (line 256) | type FileDescriptor struct
method VarName (line 280) | func (d *FileDescriptor) VarName() string {
method goPackageOption (line 289) | func (d *FileDescriptor) goPackageOption() (impPath GoImportPath, pkg ...
method goFileName (line 308) | func (d *FileDescriptor) goFileName(pathType pathType, moduleRoot stri...
method addExport (line 340) | func (d *FileDescriptor) addExport(obj Object, sym symbol) {
type symbol (line 345) | type symbol interface
type messageSymbol (line 351) | type messageSymbol struct
method GenerateAlias (line 364) | func (ms *messageSymbol) GenerateAlias(g *Generator, filename string, ...
type getterSymbol (line 357) | type getterSymbol struct
type enumSymbol (line 372) | type enumSymbol struct
method GenerateAlias (line 377) | func (es enumSymbol) GenerateAlias(g *Generator, filename string, pkg ...
type constOrVarSymbol (line 385) | type constOrVarSymbol struct
method GenerateAlias (line 391) | func (cs constOrVarSymbol) GenerateAlias(g *Generator, filename string...
type Object (line 400) | type Object interface
type Generator (line 407) | type Generator struct
method Error (line 455) | func (g *Generator) Error(err error, msgs ...string) {
method Fail (line 462) | func (g *Generator) Fail(msgs ...string) {
method CommandLineParameters (line 471) | func (g *Generator) CommandLineParameters(parameter string) {
method DefaultPackageName (line 536) | func (g *Generator) DefaultPackageName(obj Object) string {
method GoPackageName (line 545) | func (g *Generator) GoPackageName(importPath GoImportPath) GoPackageNa...
method AddImport (line 560) | func (g *Generator) AddImport(importPath GoImportPath) GoPackageName {
method defaultGoPackage (line 667) | func (g *Generator) defaultGoPackage() GoPackageName {
method SetPackageNames (line 678) | func (g *Generator) SetPackageNames() {
method WrapTypes (line 735) | func (g *Generator) WrapTypes() {
method buildNestedDescriptors (line 796) | func (g *Generator) buildNestedDescriptors(descs []*Descriptor) {
method buildNestedEnums (line 811) | func (g *Generator) buildNestedEnums(descs []*Descriptor, enums []*Enu...
method BuildTypeNameMap (line 960) | func (g *Generator) BuildTypeNameMap() {
method ObjectNamed (line 983) | func (g *Generator) ObjectNamed(typeName string) Object {
method printAtom (line 1005) | func (g *Generator) printAtom(v interface{}) {
method P (line 1038) | func (g *Generator) P(str ...interface{}) {
method addInitf (line 1058) | func (g *Generator) addInitf(stmt string, a ...interface{}) {
method In (line 1063) | func (g *Generator) In() { g.indent += "\t" }
method Out (line 1066) | func (g *Generator) Out() {
method GenerateAllFiles (line 1073) | func (g *Generator) GenerateAllFiles() {
method runPlugins (line 1102) | func (g *Generator) runPlugins(file *FileDescriptor) {
method generate (line 1110) | func (g *Generator) generate(file *FileDescriptor) {
method generateHeader (line 1163) | func (g *Generator) generateHeader() {
method PrintComments (line 1185) | func (g *Generator) PrintComments(path string) bool {
method GetComments (line 1197) | func (g *Generator) GetComments(path string) (string, bool) {
method makeComments (line 1206) | func (g *Generator) makeComments(path string) (string, bool) {
method fileByName (line 1220) | func (g *Generator) fileByName(filename string) *FileDescriptor {
method weak (line 1225) | func (g *Generator) weak(i int32) bool {
method generateImports (line 1235) | func (g *Generator) generateImports() {
method generateImported (line 1288) | func (g *Generator) generateImported(id *ImportedDescriptor) {
method generateEnum (line 1308) | func (g *Generator) generateEnum(enum *EnumDescriptor) {
method goTag (line 1416) | func (g *Generator) goTag(message *Descriptor, field *descriptor.Field...
method TypeName (line 1547) | func (g *Generator) TypeName(obj Object) string {
method GoType (line 1552) | func (g *Generator) GoType(message *Descriptor, field *descriptor.Fiel...
method RecordTypeUse (line 1609) | func (g *Generator) RecordTypeUse(t string) {
method getterDefault (line 1660) | func (g *Generator) getterDefault(field *descriptor.FieldDescriptorPro...
method defaultConstantName (line 1703) | func (g *Generator) defaultConstantName(goMessageType, protoFieldName ...
method generateDefaultConstants (line 1927) | func (g *Generator) generateDefaultConstants(mc *msgCtx, topLevelField...
method generateInternalStructFields (line 2002) | func (g *Generator) generateInternalStructFields(mc *msgCtx, topLevelF...
method generateOneofFuncs (line 2017) | func (g *Generator) generateOneofFuncs(mc *msgCtx, topLevelFields []to...
method generateMessageStruct (line 2043) | func (g *Generator) generateMessageStruct(mc *msgCtx, topLevelFields [...
method generateGetters (line 2065) | func (g *Generator) generateGetters(mc *msgCtx, topLevelFields []topLe...
method generateSetters (line 2072) | func (g *Generator) generateSetters(mc *msgCtx, topLevelFields []topLe...
method generateCommonMethods (line 2079) | func (g *Generator) generateCommonMethods(mc *msgCtx) {
method generateMessage (line 2146) | func (g *Generator) generateMessage(message *Descriptor) {
method generateExtension (line 2473) | func (g *Generator) generateExtension(ext *ExtensionDescriptor) {
method generateInitFunction (line 2532) | func (g *Generator) generateInitFunction() {
method generateFileDescriptor (line 2544) | func (g *Generator) generateFileDescriptor(file *FileDescriptor) {
method generateEnumRegistration (line 2583) | func (g *Generator) generateEnumRegistration(enum *EnumDescriptor) {
type pathType (line 437) | type pathType
constant pathTypeImport (line 440) | pathTypeImport pathType = iota
constant pathTypeSourceRelative (line 441) | pathTypeSourceRelative
constant pathModuleRoot (line 442) | pathModuleRoot
function New (line 446) | func New() *Generator {
function RegisterUniquePackageName (line 573) | func RegisterUniquePackageName(pkg string, f *FileDescriptor) string {
function cleanPackageName (line 652) | func cleanPackageName(name string) GoPackageName {
function newDescriptor (line 827) | func newDescriptor(desc *descriptor.DescriptorProto, parent *Descriptor,...
function wrapDescriptors (line 864) | func wrapDescriptors(file *FileDescriptor) []*Descriptor {
function wrapThisDescriptor (line 873) | func wrapThisDescriptor(sl []*Descriptor, desc *descriptor.DescriptorPro...
function newEnumDescriptor (line 883) | func newEnumDescriptor(desc *descriptor.EnumDescriptorProto, parent *Des...
function wrapEnumDescriptors (line 899) | func wrapEnumDescriptors(file *FileDescriptor, descs []*Descriptor) []*E...
function wrapExtensions (line 915) | func wrapExtensions(file *FileDescriptor) []*ExtensionDescriptor {
function wrapImported (line 924) | func wrapImported(file *FileDescriptor, g *Generator) (sl []*ImportedDes...
function extractComments (line 943) | func extractComments(file *FileDescriptor) {
type AnnotatedAtoms (line 992) | type AnnotatedAtoms struct
function Annotate (line 1000) | func Annotate(file *FileDescriptor, path string, atoms ...interface{}) *...
function needsStar (line 1530) | func needsStar(typ descriptor.FieldDescriptorProto_Type) bool {
type msgCtx (line 1720) | type msgCtx struct
type fieldCommon (line 1726) | type fieldCommon struct
method getProtoName (line 1736) | func (f *fieldCommon) getProtoName() string {
method getGoType (line 1741) | func (f *fieldCommon) getGoType() string {
type simpleField (line 1746) | type simpleField struct
method decl (line 1757) | func (f *simpleField) decl(g *Generator, mc *msgCtx) {
method getter (line 1762) | func (f *simpleField) getter(g *Generator, mc *msgCtx) {
method setter (line 1795) | func (f *simpleField) setter(g *Generator, mc *msgCtx) {
method getProtoDef (line 1800) | func (f *simpleField) getProtoDef() string {
method getProtoTypeName (line 1805) | func (f *simpleField) getProtoTypeName() string {
method getProtoType (line 1810) | func (f *simpleField) getProtoType() descriptor.FieldDescriptorProto_T...
type oneofSubField (line 1815) | type oneofSubField struct
method typedNil (line 1828) | func (f *oneofSubField) typedNil(g *Generator) {
method getProtoDef (line 1833) | func (f *oneofSubField) getProtoDef() string {
method getProtoTypeName (line 1838) | func (f *oneofSubField) getProtoTypeName() string {
method getProtoType (line 1843) | func (f *oneofSubField) getProtoType() descriptor.FieldDescriptorProto...
type oneofField (line 1849) | type oneofField struct
method decl (line 1856) | func (f *oneofField) decl(g *Generator, mc *msgCtx) {
method getter (line 1866) | func (f *oneofField) getter(g *Generator, mc *msgCtx) {
method setter (line 1905) | func (f *oneofField) setter(g *Generator, mc *msgCtx) {
type topLevelField (line 1910) | type topLevelField interface
type defField (line 1917) | type defField interface
type byTypeName (line 2396) | type byTypeName
method Len (line 2398) | func (a byTypeName) Len() int { return len(a) }
method Swap (line 2399) | func (a byTypeName) Swap(i, j int) { a[i], a[j] = a[j], a[i] }
method Less (line 2400) | func (a byTypeName) Less(i, j int) bool { return *a[i].TypeName < *a[j...
function mapFieldKeys (line 2403) | func mapFieldKeys(m map[*descriptor.FieldDescriptorProto]string) []*desc...
function unescape (line 2419) | func unescape(s string) string {
function isASCIILower (line 2599) | func isASCIILower(c byte) bool {
function isASCIIDigit (line 2604) | func isASCIIDigit(c byte) bool {
function CamelCase (line 2616) | func CamelCase(s string) string {
function CamelCaseSlice (line 2657) | func CamelCaseSlice(elem []string) string { return CamelCase(strings.Joi...
function dottedSlice (line 2660) | func dottedSlice(elem []string) string { return strings.Join(elem, ".") }
function isOptional (line 2663) | func isOptional(field *descriptor.FieldDescriptorProto) bool {
function isRequired (line 2668) | func isRequired(field *descriptor.FieldDescriptorProto) bool {
function isRepeated (line 2673) | func isRepeated(field *descriptor.FieldDescriptorProto) bool {
function isScalar (line 2678) | func isScalar(field *descriptor.FieldDescriptorProto) bool {
function badToUnderscore (line 2706) | func badToUnderscore(r rune) rune {
function baseName (line 2714) | func baseName(name string) string {
constant packagePath (line 2736) | packagePath = 2
constant messagePath (line 2737) | messagePath = 4
constant enumPath (line 2738) | enumPath = 5
constant messageFieldPath (line 2740) | messageFieldPath = 2
constant messageMessagePath (line 2741) | messageMessagePath = 3
constant messageEnumPath (line 2742) | messageEnumPath = 4
constant messageOneofPath (line 2743) | messageOneofPath = 8
constant enumValuePath (line 2745) | enumValuePath = 2
function init (line 2750) | func init() {
FILE: cmd/protoc-gen-micro/generator/name_test.go
function TestCamelCase (line 40) | func TestCamelCase(t *testing.T) {
function TestGoPackageOption (line 60) | func TestGoPackageOption(t *testing.T) {
function TestPackageNames (line 89) | func TestPackageNames(t *testing.T) {
function TestUnescape (line 108) | func TestUnescape(t *testing.T) {
FILE: cmd/protoc-gen-micro/main.go
function main (line 66) | func main() {
FILE: cmd/protoc-gen-micro/plugin/micro/micro.go
constant contextPkgPath (line 18) | contextPkgPath = "context"
constant clientPkgPath (line 19) | clientPkgPath = "go-micro.dev/v5/client"
constant serverPkgPath (line 20) | serverPkgPath = "go-micro.dev/v5/server"
constant modelPkgPath (line 21) | modelPkgPath = "go-micro.dev/v5/model"
function init (line 24) | func init() {
type micro (line 30) | type micro struct
method Name (line 35) | func (g *micro) Name() string {
method Init (line 51) | func (g *micro) Init(gen *generator.Generator) {
method objectNamed (line 61) | func (g *micro) objectNamed(name string) generator.Object {
method typeName (line 67) | func (g *micro) typeName(str string) string {
method P (line 72) | func (g *micro) P(args ...interface{}) { g.gen.P(args...) }
method Generate (line 75) | func (g *micro) Generate(file *generator.FileDescriptor) {
method GenerateImports (line 113) | func (g *micro) GenerateImports(file *generator.FileDescriptor, import...
method generateService (line 164) | func (g *micro) generateService(file *generator.FileDescriptor, servic...
method generateEndpoint (line 285) | func (g *micro) generateEndpoint(servName string, method *pb.MethodDes...
method generateClientSignature (line 325) | func (g *micro) generateClientSignature(servName string, method *pb.Me...
method generateClientMethod (line 343) | func (g *micro) generateClientMethod(pkg, reqServ, servName, serviceDe...
method generateServerSignature (line 459) | func (g *micro) generateServerSignature(servName string, method *pb.Me...
method generateServerMethod (line 482) | func (g *micro) generateServerMethod(servName string, method *pb.Metho...
method isModelMessage (line 575) | func (g *micro) isModelMessage(msgIndex int) bool {
method generateModel (line 644) | func (g *micro) generateModel(msg *pb.DescriptorProto, msgIndex int) {
function unexport (line 152) | func unexport(s string) string {
function parseModelOptions (line 586) | func parseModelOptions(comment string) (table string, key string) {
function protoFieldGoType (line 618) | func protoFieldGoType(field *pb.FieldDescriptorProto) string {
FILE: cmd/protoc-gen-micro/plugin/micro/micro_test.go
function TestParseModelOptions (line 5) | func TestParseModelOptions(t *testing.T) {
function TestProtoFieldGoType (line 30) | func TestProtoFieldGoType(t *testing.T) {
FILE: codec/bytes/bytes.go
type Codec (line 11) | type Codec struct
method ReadHeader (line 20) | func (c *Codec) ReadHeader(m *codec.Message, t codec.MessageType) error {
method ReadBody (line 24) | func (c *Codec) ReadBody(b interface{}) error {
method Write (line 43) | func (c *Codec) Write(m *codec.Message, b interface{}) error {
method Close (line 59) | func (c *Codec) Close() error {
method String (line 63) | func (c *Codec) String() string {
type Frame (line 16) | type Frame struct
function NewCodec (line 67) | func NewCodec(c io.ReadWriteCloser) codec.Codec {
FILE: codec/bytes/marshaler.go
type Marshaler (line 7) | type Marshaler struct
method Marshal (line 14) | func (n Marshaler) Marshal(v interface{}) ([]byte, error) {
method Unmarshal (line 26) | func (n Marshaler) Unmarshal(d []byte, v interface{}) error {
method String (line 38) | func (n Marshaler) String() string {
type Message (line 9) | type Message struct
FILE: codec/codec.go
constant Error (line 10) | Error MessageType = iota
constant Request (line 11) | Request
constant Response (line 12) | Response
constant Event (line 13) | Event
type MessageType (line 20) | type MessageType
type NewCodec (line 23) | type NewCodec
type Codec (line 30) | type Codec interface
type Reader (line 37) | type Reader interface
type Writer (line 42) | type Writer interface
type Marshaler (line 48) | type Marshaler interface
type Message (line 57) | type Message struct
FILE: codec/grpc/grpc.go
type Codec (line 16) | type Codec struct
method ReadHeader (line 21) | func (c *Codec) ReadHeader(m *codec.Message, t codec.MessageType) error {
method ReadBody (line 49) | func (c *Codec) ReadBody(b interface{}) error {
method Write (line 70) | func (c *Codec) Write(m *codec.Message, b interface{}) error {
method Close (line 137) | func (c *Codec) Close() error {
method String (line 141) | func (c *Codec) String() string {
function NewCodec (line 145) | func NewCodec(c io.ReadWriteCloser) codec.Codec {
FILE: codec/grpc/util.go
function decode (line 14) | func decode(r io.Reader) (uint8, []byte, error) {
function encode (line 53) | func encode(cf uint8, buf []byte, w io.Writer) error {
FILE: codec/json/any_test.go
function TestAnyTypeMarshaling (line 12) | func TestAnyTypeMarshaling(t *testing.T) {
function TestAnyTypeUnmarshaling (line 57) | func TestAnyTypeUnmarshaling(t *testing.T) {
FILE: codec/json/codec_test.go
type mockReadWriteCloser (line 14) | type mockReadWriteCloser struct
method Close (line 18) | func (m *mockReadWriteCloser) Close() error {
function TestCodecAnyTypeWrite (line 23) | func TestCodecAnyTypeWrite(t *testing.T) {
function TestCodecAnyTypeRead (line 66) | func TestCodecAnyTypeRead(t *testing.T) {
FILE: codec/json/json.go
type Codec (line 13) | type Codec struct
method ReadHeader (line 19) | func (c *Codec) ReadHeader(m *codec.Message, t codec.MessageType) error {
method ReadBody (line 23) | func (c *Codec) ReadBody(b interface{}) error {
method Write (line 38) | func (c *Codec) Write(m *codec.Message, b interface{}) error {
method Close (line 54) | func (c *Codec) Close() error {
method String (line 58) | func (c *Codec) String() string {
function NewCodec (line 62) | func NewCodec(c io.ReadWriteCloser) codec.Codec {
FILE: codec/json/marshaler.go
type Marshaler (line 14) | type Marshaler struct
method Marshal (line 16) | func (j Marshaler) Marshal(v interface{}) ([]byte, error) {
method Unmarshal (line 23) | func (j Marshaler) Unmarshal(d []byte, v interface{}) error {
method String (line 30) | func (j Marshaler) String() string {
FILE: codec/jsonrpc/client.go
type clientCodec (line 12) | type clientCodec struct
method Write (line 48) | func (c *clientCodec) Write(m *codec.Message, b interface{}) error {
method ReadHeader (line 64) | func (c *clientCodec) ReadHeader(m *codec.Message) error {
method ReadBody (line 90) | func (c *clientCodec) ReadBody(x interface{}) error {
method Close (line 97) | func (c *clientCodec) Close() error {
type clientRequest (line 27) | type clientRequest struct
type clientResponse (line 33) | type clientResponse struct
method reset (line 58) | func (r *clientResponse) reset() {
function newClientCodec (line 39) | func newClientCodec(conn io.ReadWriteCloser) *clientCodec {
FILE: codec/jsonrpc/jsonrpc.go
type jsonCodec (line 13) | type jsonCodec struct
method Close (line 21) | func (j *jsonCodec) Close() error {
method String (line 26) | func (j *jsonCodec) String() string {
method Write (line 30) | func (j *jsonCodec) Write(m *codec.Message, b interface{}) error {
method ReadHeader (line 48) | func (j *jsonCodec) ReadHeader(m *codec.Message, mt codec.MessageType)...
method ReadBody (line 65) | func (j *jsonCodec) ReadBody(b interface{}) error {
function NewCodec (line 81) | func NewCodec(rwc io.ReadWriteCloser) codec.Codec {
FILE: codec/jsonrpc/server.go
type serverCodec (line 11) | type serverCodec struct
method ReadHeader (line 51) | func (c *serverCodec) ReadHeader(m *codec.Message) error {
method ReadBody (line 62) | func (c *serverCodec) ReadBody(x interface{}) error {
method Write (line 73) | func (c *serverCodec) Write(m *codec.Message, x interface{}) error {
method Close (line 85) | func (c *serverCodec) Close() error {
type serverRequest (line 21) | type serverRequest struct
method reset (line 41) | func (r *serverRequest) reset() {
type serverResponse (line 27) | type serverResponse struct
function newServerCodec (line 33) | func newServerCodec(conn io.ReadWriteCloser) *serverCodec {
FILE: codec/proto/marshaler.go
type Marshaler (line 14) | type Marshaler struct
method Marshal (line 16) | func (Marshaler) Marshal(v interface{}) ([]byte, error) {
method Unmarshal (line 36) | func (Marshaler) Unmarshal(data []byte, v interface{}) error {
method String (line 45) | func (Marshaler) String() string {
FILE: codec/proto/message.go
type Message (line 3) | type Message struct
method MarshalJSON (line 7) | func (m *Message) MarshalJSON() ([]byte, error) {
method UnmarshalJSON (line 11) | func (m *Message) UnmarshalJSON(data []byte) error {
method ProtoMessage (line 16) | func (m *Message) ProtoMessage() {}
method Reset (line 18) | func (m *Message) Reset() {
method String (line 22) | func (m *Message) String() string {
method Marshal (line 26) | func (m *Message) Marshal() ([]byte, error) {
method Unmarshal (line 30) | func (m *Message) Unmarshal(data []byte) error {
function NewMessage (line 35) | func NewMessage(data []byte) *Message {
FILE: codec/proto/proto.go
type Codec (line 11) | type Codec struct
method ReadHeader (line 15) | func (c *Codec) ReadHeader(m *codec.Message, t codec.MessageType) error {
method ReadBody (line 19) | func (c *Codec) ReadBody(b interface{}) error {
method Write (line 34) | func (c *Codec) Write(m *codec.Message, b interface{}) error {
method Close (line 51) | func (c *Codec) Close() error {
method String (line 55) | func (c *Codec) String() string {
function NewCodec (line 59) | func NewCodec(c io.ReadWriteCloser) codec.Codec {
FILE: codec/protorpc/envelope.pb.go
constant _ (line 21) | _ = proto.ProtoPackageIsVersion3
type Request (line 23) | type Request struct
method Reset (line 31) | func (m *Request) Reset() { *m = Request{} }
method String (line 32) | func (m *Request) String() string { return proto.CompactTextString(m) }
method ProtoMessage (line 33) | func (*Request) ProtoMessage() {}
method Descriptor (line 34) | func (*Request) Descriptor() ([]byte, []int) {
method XXX_Unmarshal (line 38) | func (m *Request) XXX_Unmarshal(b []byte) error {
method XXX_Marshal (line 41) | func (m *Request) XXX_Marshal(b []byte, deterministic bool) ([]byte, e...
method XXX_Merge (line 44) | func (m *Request) XXX_Merge(src proto.Message) {
method XXX_Size (line 47) | func (m *Request) XXX_Size() int {
method XXX_DiscardUnknown (line 50) | func (m *Request) XXX_DiscardUnknown() {
method GetServiceMethod (line 56) | func (m *Request) GetServiceMethod() string {
method GetSeq (line 63) | func (m *Request) GetSeq() uint64 {
type Response (line 70) | type Response struct
method Reset (line 79) | func (m *Response) Reset() { *m = Response{} }
method String (line 80) | func (m *Response) String() string { return proto.CompactTextString(m) }
method ProtoMessage (line 81) | func (*Response) ProtoMessage() {}
method Descriptor (line 82) | func (*Response) Descriptor() ([]byte, []int) {
method XXX_Unmarshal (line 86) | func (m *Response) XXX_Unmarshal(b []byte) error {
method XXX_Marshal (line 89) | func (m *Response) XXX_Marshal(b []byte, deterministic bool) ([]byte, ...
method XXX_Merge (line 92) | func (m *Response) XXX_Merge(src proto.Message) {
method XXX_Size (line 95) | func (m *Response) XXX_Size() int {
method XXX_DiscardUnknown (line 98) | func (m *Response) XXX_DiscardUnknown() {
method GetServiceMethod (line 104) | func (m *Response) GetServiceMethod() string {
method GetSeq (line 111) | func (m *Response) GetSeq() uint64 {
method GetError (line 118) | func (m *Response) GetError() string {
function init (line 125) | func init() {
function init (line 130) | func init() { proto.RegisterFile("codec/protorpc/envelope.proto", fileDe...
FILE: codec/protorpc/envelope.pb.micro.go
constant _ (line 21) | _ = proto.ProtoPackageIsVersion3
FILE: codec/protorpc/netstring.go
function WriteNetString (line 10) | func WriteNetString(w io.Writer, data []byte) (written int, err error) {
function ReadNetString (line 20) | func ReadNetString(r io.Reader) (data []byte, err error) {
FILE: codec/protorpc/protorpc.go
type flusher (line 15) | type flusher interface
type protoCodec (line 19) | type protoCodec struct
method Close (line 26) | func (c *protoCodec) Close() error {
method String (line 31) | func (c *protoCodec) String() string {
method Write (line 44) | func (c *protoCodec) Write(m *codec.Message, b interface{}) error {
method ReadHeader (line 122) | func (c *protoCodec) ReadHeader(m *codec.Message, mt codec.MessageType...
method ReadBody (line 161) | func (c *protoCodec) ReadBody(b interface{}) error {
function id (line 35) | func id(id string) uint64 {
function NewCodec (line 181) | func NewCodec(rwc io.ReadWriteCloser) codec.Codec {
FILE: codec/text/text.go
type Codec (line 11) | type Codec struct
method ReadHeader (line 20) | func (c *Codec) ReadHeader(m *codec.Message, t codec.MessageType) error {
method ReadBody (line 24) | func (c *Codec) ReadBody(b interface{}) error {
method Write (line 45) | func (c *Codec) Write(m *codec.Message, b interface{}) error {
method Close (line 65) | func (c *Codec) Close() error {
method String (line 69) | func (c *Codec) String() string {
type Frame (line 16) | type Frame struct
function NewCodec (line 73) | func NewCodec(c io.ReadWriteCloser) codec.Codec {
FILE: config/config.go
type Config (line 14) | type Config interface
type Watcher (line 32) | type Watcher interface
type Options (line 37) | type Options struct
type Option (line 49) | type Option
function NewConfig (line 57) | func NewConfig(opts ...Option) (Config, error) {
function Bytes (line 62) | func Bytes() []byte {
function Map (line 67) | func Map() map[string]interface{} {
function Scan (line 72) | func Scan(v interface{}) error {
function Sync (line 77) | func Sync() error {
function Get (line 82) | func Get(path ...string) (reader.Value, error) {
function Load (line 87) | func Load(source ...source.Source) error {
function Watch (line 92) | func Watch(path ...string) (Watcher, error) {
function LoadFile (line 97) | func LoadFile(path string) error {
FILE: config/default.go
type config (line 15) | type config struct
method Init (line 46) | func (c *config) Init(opts ...Option) error {
method Options (line 83) | func (c *config) Options() Options {
method run (line 87) | func (c *config) run() {
method Map (line 150) | func (c *config) Map() map[string]interface{} {
method Scan (line 156) | func (c *config) Scan(v interface{}) error {
method Sync (line 163) | func (c *config) Sync() error {
method Close (line 186) | func (c *config) Close() error {
method Get (line 196) | func (c *config) Get(path ...string) (reader.Value, error) {
method Set (line 209) | func (c *config) Set(val interface{}, path ...string) {
method Del (line 220) | func (c *config) Del(path ...string) {
method Bytes (line 231) | func (c *config) Bytes() []byte {
method Load (line 242) | func (c *config) Load(sources ...source.Source) error {
method Watch (line 265) | func (c *config) Watch(path ...string) (Watcher, error) {
method String (line 284) | func (c *config) String() string {
type watcher (line 26) | type watcher struct
method Next (line 288) | func (w *watcher) Next() (reader.Value, error) {
method Stop (line 309) | func (w *watcher) Stop() error {
function newConfig (line 33) | func newConfig(opts ...Option) (Config, error) {
FILE: config/default_test.go
function createFileForIssue18 (line 18) | func createFileForIssue18(t *testing.T, content string) *os.File {
function createFileForTest (line 33) | func createFileForTest(t *testing.T) *os.File {
function TestConfigLoadWithGoodFile (line 48) | func TestConfigLoadWithGoodFile(t *testing.T) {
function TestConfigLoadWithInvalidFile (line 69) | func TestConfigLoadWithInvalidFile(t *testing.T) {
function TestConfigMerge (line 96) | func TestConfigMerge(t *testing.T) {
function equalS (line 138) | func equalS(t *testing.T, actual, expect string) {
function TestConfigWatcherDirtyOverrite (line 144) | func TestConfigWatcherDirtyOverrite(t *testing.T) {
FILE: config/encoder/encoder.go
type Encoder (line 4) | type Encoder interface
FILE: config/encoder/json/json.go
type jsonEncoder (line 9) | type jsonEncoder struct
method Encode (line 11) | func (j jsonEncoder) Encode(v interface{}) ([]byte, error) {
method Decode (line 15) | func (j jsonEncoder) Decode(d []byte, v interface{}) error {
method String (line 19) | func (j jsonEncoder) String() string {
function NewEncoder (line 23) | func NewEncoder() encoder.Encoder {
FILE: config/loader/loader.go
type Loader (line 12) | type Loader interface
type Watcher (line 28) | type Watcher interface
type Snapshot (line 38) | type Snapshot struct
type Options (line 46) | type Options struct
type Option (line 58) | type Option
function Copy (line 61) | func Copy(s *Snapshot) *Snapshot {
FILE: config/loader/memory/memory.go
type memory (line 19) | type memory struct
method watch (line 56) | func (m *memory) watch(idx int, s source.Source) {
method loaded (line 128) | func (m *memory) loaded() bool {
method reload (line 139) | func (m *memory) reload() error {
method update (line 166) | func (m *memory) update() {
method Snapshot (line 201) | func (m *memory) Snapshot() (*loader.Snapshot, error) {
method Sync (line 223) | func (m *memory) Sync() error {
method Close (line 272) | func (m *memory) Close() error {
method Get (line 282) | func (m *memory) Get(path ...string) (reader.Value, error) {
method Load (line 320) | func (m *memory) Load(sources ...source.Source) error {
method Watch (line 354) | func (m *memory) Watch(path ...string) (loader.Watcher, error) {
method String (line 389) | func (m *memory) String() string {
type updateValue (line 37) | type updateValue struct
type watcher (line 42) | type watcher struct
method getVersion (line 52) | func (w *watcher) getVersion() string {
method Next (line 393) | func (w *watcher) Next() (*loader.Snapshot, error) {
method Stop (line 434) | func (w *watcher) Stop() error {
function genVer (line 448) | func genVer() string {
function NewLoader (line 452) | func NewLoader(opts ...loader.Option) loader.Loader {
FILE: config/loader/memory/options.go
function WithSource (line 10) | func WithSource(s source.Source) loader.Option {
function WithReader (line 17) | func WithReader(r reader.Reader) loader.Option {
function WithWatcherDisabled (line 23) | func WithWatcherDisabled() loader.Option {
FILE: config/options.go
function WithLoader (line 10) | func WithLoader(l loader.Loader) Option {
function WithSource (line 17) | func WithSource(s source.Source) Option {
function WithReader (line 24) | func WithReader(r reader.Reader) Option {
function WithWatcherDisabled (line 30) | func WithWatcherDisabled() Option {
FILE: config/reader/json/json.go
type jsonReader (line 14) | type jsonReader struct
method Merge (line 19) | func (j *jsonReader) Merge(changes ...*source.ChangeSet) (*source.Chan...
method Values (line 62) | func (j *jsonReader) Values(ch *source.ChangeSet) (reader.Values, erro...
method String (line 72) | func (j *jsonReader) String() string {
function NewReader (line 77) | func NewReader(opts ...reader.Option) reader.Reader {
FILE: config/reader/json/json_test.go
function TestReader (line 9) | func TestReader(t *testing.T) {
FILE: config/reader/json/values.go
type jsonValues (line 15) | type jsonValues struct
method Get (line 42) | func (j *jsonValues) Get(path ...string) (reader.Value, error) {
method Del (line 46) | func (j *jsonValues) Del(path ...string) {
method Set (line 64) | func (j *jsonValues) Set(val interface{}, path ...string) {
method Bytes (line 68) | func (j *jsonValues) Bytes() []byte {
method Map (line 73) | func (j *jsonValues) Map() map[string]interface{} {
method Scan (line 78) | func (j *jsonValues) Scan(v interface{}) error {
method String (line 86) | func (j *jsonValues) String() string {
type jsonValue (line 20) | type jsonValue struct
method Bool (line 90) | func (j *jsonValue) Bool(def bool) bool {
method Int (line 109) | func (j *jsonValue) Int(def int) int {
method String (line 128) | func (j *jsonValue) String(def string) string {
method Float64 (line 132) | func (j *jsonValue) Float64(def float64) float64 {
method Duration (line 151) | func (j *jsonValue) Duration(def time.Duration) time.Duration {
method StringSlice (line 165) | func (j *jsonValue) StringSlice(def []string) []string {
method StringMap (line 176) | func (j *jsonValue) StringMap(def map[string]string) map[string]string {
method Scan (line 191) | func (j *jsonValue) Scan(v interface{}) error {
method Bytes (line 199) | func (j *jsonValue) Bytes() []byte {
function NewValues (line 24) | func NewValues(val []byte) (reader.Values, error) {
function newValues (line 33) | func newValues(ch *source.ChangeSet) (reader.Values, error) {
FILE: config/reader/json/values_test.go
function TestValues (line 10) | func TestValues(t *testing.T) {
function TestStructArray (line 54) | func TestStructArray(t *testing.T) {
FILE: config/reader/options.go
type Options (line 8) | type Options struct
type Option (line 12) | type Option
function NewOptions (line 14) | func NewOptions(opts ...Option) Options {
function WithEncoder (line 26) | func WithEncoder(e encoder.Encoder) Option {
FILE: config/reader/preprocessor.go
function ReplaceEnvVars (line 8) | func ReplaceEnvVars(raw []byte) ([]byte, error) {
function replaceEnvVars (line 19) | func replaceEnvVars(element string) string {
FILE: config/reader/preprocessor_test.go
function TestReplaceEnvVars (line 9) | func TestReplaceEnvVars(t *testing.T) {
FILE: config/reader/reader.go
type Reader (line 11) | type Reader interface
type Values (line 18) | type Values interface
type Value (line 28) | type Value interface
FILE: config/secrets/box/box.go
constant keyLength (line 12) | keyLength = 32
type box (line 14) | type box struct
method Init (line 30) | func (b *box) Init(opts ...secrets.Option) error {
method Options (line 43) | func (b *box) Options() secrets.Options {
method String (line 48) | func (*box) String() string {
method Encrypt (line 53) | func (b *box) Encrypt(in []byte, opts ...secrets.EncryptOption) ([]byt...
method Decrypt (line 71) | func (b *box) Decrypt(in []byte, opts ...secrets.DecryptOption) ([]byt...
function NewSecrets (line 22) | func NewSecrets(opts ...secrets.Option) secrets.Secrets {
FILE: config/secrets/box/box_test.go
function TestBox (line 12) | func TestBox(t *testing.T) {
FILE: config/secrets/secretbox/secretbox.go
constant keyLength (line 13) | keyLength = 32
type secretBox (line 15) | type secretBox struct
method Init (line 30) | func (s *secretBox) Init(opts ...secrets.Option) error {
method Options (line 44) | func (s *secretBox) Options() secrets.Options {
method String (line 48) | func (s *secretBox) String() string {
method Encrypt (line 52) | func (s *secretBox) Encrypt(in []byte, opts ...secrets.EncryptOption) ...
method Decrypt (line 63) | func (s *secretBox) Decrypt(in []byte, opts ...secrets.DecryptOption) ...
function NewSecrets (line 22) | func NewSecrets(opts ...secrets.Option) secrets.Secrets {
FILE: config/secrets/secretbox/secretbox_test.go
function TestSecretBox (line 11) | func TestSecretBox(t *testing.T) {
FILE: config/secrets/secrets.go
type Secrets (line 7) | type Secrets interface
type Options (line 20) | type Options struct
type Option (line 32) | type Option
function Key (line 35) | func Key(k []byte) Option {
function PublicKey (line 43) | func PublicKey(key []byte) Option {
function PrivateKey (line 51) | func PrivateKey(key []byte) Option {
type DecryptOptions (line 59) | type DecryptOptions struct
type DecryptOption (line 64) | type DecryptOption
function SenderPublicKey (line 67) | func SenderPublicKey(key []byte) DecryptOption {
type EncryptOptions (line 75) | type EncryptOptions struct
type EncryptOption (line 80) | type EncryptOption
function RecipientPublicKey (line 83) | func RecipientPublicKey(key []byte) EncryptOption {
FILE: config/source/changeset.go
method Sum (line 9) | func (c *ChangeSet) Sum() string {
FILE: config/source/cli/cli.go
type cliSource (line 16) | type cliSource struct
method Read (line 21) | func (c *cliSource) Read() (*source.ChangeSet, error) {
method Watch (line 76) | func (c *cliSource) Watch() (source.Watcher, error) {
method Write (line 81) | func (c *cliSource) Write(cs *source.ChangeSet) error {
method String (line 85) | func (c *cliSource) String() string {
function toEntry (line 49) | func toEntry(name string, v interface{}) map[string]interface{} {
function reverse (line 65) | func reverse(ss []string) {
function split (line 72) | func split(r rune) bool {
function NewSource (line 103) | func NewSource(opts ...source.Option) source.Source {
function WithContext (line 143) | func WithContext(ctx *cli.Context, opts ...source.Option) source.Source {
FILE: config/source/cli/cli_test.go
function TestCliSourceDefault (line 15) | func TestCliSourceDefault(t *testing.T) {
function test (line 66) | func test(t *testing.T, withContext bool) {
function TestCliSource (line 114) | func TestCliSource(t *testing.T) {
function TestCliSourceWithContext (line 119) | func TestCliSourceWithContext(t *testing.T) {
FILE: config/source/cli/options.go
type contextKey (line 10) | type contextKey struct
function Context (line 13) | func Context(c *cli.Context) source.Option {
FILE: config/source/cli/util.go
function copyFlag (line 11) | func copyFlag(name string, ff *flag.Flag, set *flag.FlagSet) {
function normalizeFlags (line 19) | func normalizeFlags(flags []cli.Flag, set *flag.FlagSet) error {
FILE: config/source/env/env.go
type env (line 17) | type env struct
method Read (line 23) | func (e *env) Read() (*source.ChangeSet, error) {
method Watch (line 103) | func (e *env) Watch() (source.Watcher, error) {
method Write (line 107) | func (e *env) Write(cs *source.ChangeSet) error {
method String (line 111) | func (e *env) String() string {
function matchPrefix (line 86) | func matchPrefix(pre []string, s string) (string, bool) {
function reverse (line 96) | func reverse(ss []string) {
function NewSource (line 129) | func NewSource(opts ...source.Option) source.Source {
FILE: config/source/env/env_test.go
function TestEnv_Read (line 12) | func TestEnv_Read(t *testing.T) {
function TestEnvvar_Prefixes (line 47) | func TestEnvvar_Prefixes(t *testing.T) {
function TestEnvvar_WatchNextNoOpsUntilStop (line 88) | func TestEnvvar_WatchNextNoOpsUntilStop(t *testing.T) {
function containsKey (line 105) | func containsKey(m map[string]interface{}, s string) bool {
FILE: config/source/env/options.go
type strippedPrefixKey (line 10) | type strippedPrefixKey struct
type prefixKey (line 11) | type prefixKey struct
function WithStrippedPrefix (line 15) | func WithStrippedPrefix(p ...string) source.Option {
function WithPrefix (line 27) | func WithPrefix(p ...string) source.Option {
function appendUnderscore (line 36) | func appendUnderscore(prefixes []string) []string {
FILE: config/source/env/watcher.go
type watcher (line 7) | type watcher struct
method Next (line 11) | func (w *watcher) Next() (*source.ChangeSet, error) {
method Stop (line 17) | func (w *watcher) Stop() error {
function newWatcher (line 22) | func newWatcher() (source.Watcher, error) {
FILE: config/source/file/file.go
type file (line 12) | type file struct
method Read (line 22) | func (f *file) Read() (*source.ChangeSet, error) {
method String (line 56) | func (f *file) String() string {
method Watch (line 60) | func (f *file) Watch() (source.Watcher, error) {
method Write (line 72) | func (f *file) Write(cs *source.ChangeSet) error {
function NewSource (line 76) | func NewSource(opts ...source.Option) source.Source {
FILE: config/source/file/file_test.go
function TestConfig (line 15) | func TestConfig(t *testing.T) {
function TestFile (line 41) | func TestFile(t *testing.T) {
function TestWithFS (line 69) | func TestWithFS(t *testing.T) {
FILE: config/source/file/format.go
function format (line 9) | func format(p string, e encoder.Encoder) string {
FILE: config/source/file/format_test.go
function TestFormat (line 9) | func TestFormat(t *testing.T) {
FILE: config/source/file/options.go
type filePathKey (line 10) | type filePathKey struct
type fsKey (line 11) | type fsKey struct
function WithPath (line 14) | func WithPath(p string) source.Option {
function WithFS (line 24) | func WithFS(fs fs.FS) source.Option {
FILE: config/source/file/watcher.go
type watcher (line 13) | type watcher struct
method Next (line 33) | func (w *watcher) Next() (*source.ChangeSet, error) {
method Stop (line 66) | func (w *watcher) Stop() error {
function newWatcher (line 19) | func newWatcher(f *file) (source.Watcher, error) {
FILE: config/source/file/watcher_linux.go
type watcher (line 13) | type watcher struct
method Next (line 33) | func (w *watcher) Next() (*source.ChangeSet, error) {
method Stop (line 69) | func (w *watcher) Stop() error {
function newWatcher (line 19) | func newWatcher(f *file) (source.Watcher, error) {
FILE: config/source/file/watcher_test.go
function createTestFile (line 17) | func createTestFile(data []byte) (*os.File, func(), string, error) {
function TestWatcher (line 35) | func TestWatcher(t *testing.T) {
function TestWatcherStop (line 78) | func TestWatcherStop(t *testing.T) {
FILE: config/source/flag/flag.go
type flagsrc (line 13) | type flagsrc struct
method Read (line 17) | func (fs *flagsrc) Read() (*source.ChangeSet, error) {
method Watch (line 77) | func (fs *flagsrc) Watch() (source.Watcher, error) {
method Write (line 81) | func (fs *flagsrc) Write(cs *source.ChangeSet) error {
method String (line 85) | func (fs *flagsrc) String() string {
function split (line 66) | func split(r rune) bool {
function reverse (line 70) | func reverse(ss []string) {
function NewSource (line 101) | func NewSource(opts ...source.Option) source.Source {
FILE: config/source/flag/flag_test.go
function initTestFlags (line 15) | func initTestFlags() {
function TestFlagsrc_Read (line 21) | func TestFlagsrc_Read(t *testing.T) {
function TestFlagsrc_ReadAll (line 49) | func TestFlagsrc_ReadAll(t *testing.T) {
FILE: config/source/flag/options.go
type includeUnsetKey (line 9) | type includeUnsetKey struct
function IncludeUnset (line 13) | func IncludeUnset(b bool) source.Option {
FILE: config/source/memory/memory.go
type memory (line 12) | type memory struct
method Read (line 18) | func (s *memory) Read() (*source.ChangeSet, error) {
method Watch (line 31) | func (s *memory) Watch() (source.Watcher, error) {
method Write (line 44) | func (m *memory) Write(cs *source.ChangeSet) error {
method Update (line 50) | func (s *memory) Update(c *source.ChangeSet) {
method String (line 77) | func (s *memory) String() string {
function NewSource (line 81) | func NewSource(opts ...source.Option) source.Source {
FILE: config/source/memory/options.go
type changeSetKey (line 9) | type changeSetKey struct
function withData (line 11) | func withData(d []byte, f string) source.Option {
function WithChangeSet (line 24) | func WithChangeSet(cs *source.ChangeSet) source.Option {
function WithJSON (line 34) | func WithJSON(d []byte) source.Option {
function WithYAML (line 39) | func WithYAML(d []byte) source.Option {
FILE: config/source/memory/watcher.go
type watcher (line 7) | type watcher struct
method Next (line 13) | func (w *watcher) Next() (*source.ChangeSet, error) {
method Stop (line 18) | func (w *watcher) Stop() error {
FILE: config/source/nats/nats.go
type nats (line 14) | type nats struct
method Read (line 30) | func (n *nats) Read() (*source.ChangeSet, error) {
method Write (line 54) | func (n *nats) Write(cs *source.ChangeSet) error {
method String (line 63) | func (n *nats) String() string {
method Watch (line 67) | func (n *nats) Watch() (source.Watcher, error) {
method Close (line 140) | func (n *nats) Close() error {
function NewSource (line 71) | func NewSource(opts ...source.Option) source.Source {
FILE: config/source/nats/options.go
type urlKey (line 12) | type urlKey struct
type bucketKey (line 13) | type bucketKey struct
type keyKey (line 14) | type keyKey struct
function WithUrl (line 18) | func WithUrl(a ...string) source.Option {
function WithBucket (line 28) | func WithBucket(a string) source.Option {
function WithKey (line 38) | func WithKey(a string) source.Option {
function Client (line 47) | func Client(url string) (natsgo.JetStreamContext, error) {
FILE: config/source/nats/watcher.go
type watcher (line 11) | type watcher struct
method handle (line 49) | func (w *watcher) handle(data []byte) {
method Next (line 61) | func (w *watcher) Next() (*source.ChangeSet, error) {
method Stop (line 70) | func (w *watcher) Stop() error {
function newWatcher (line 21) | func newWatcher(kv natsgo.KeyValue, bucket, key, name string, e encoder....
FILE: config/source/noop.go
type noopWatcher (line 7) | type noopWatcher struct
method Next (line 11) | func (w *noopWatcher) Next() (*ChangeSet, error) {
method Stop (line 17) | func (w *noopWatcher) Stop() error {
function NewNoopWatcher (line 23) | func NewNoopWatcher() (Watcher, error) {
FILE: config/source/options.go
type Options (line 11) | type Options struct
type Option (line 22) | type Option
function NewOptions (line 24) | func NewOptions(opts ...Option) Options {
function WithEncoder (line 39) | func WithEncoder(e encoder.Encoder) Option {
function WithClient (line 46) | func WithClient(c client.Client) Option {
FILE: config/source/source.go
type Source (line 15) | type Source interface
type ChangeSet (line 23) | type ChangeSet struct
type Watcher (line 32) | type Watcher interface
FILE: config/value.go
type value (line 9) | type value struct
method Bool (line 15) | func (v *value) Bool(def bool) bool {
method Int (line 19) | func (v *value) Int(def int) int {
method String (line 23) | func (v *value) String(def string) string {
method Float64 (line 27) | func (v *value) Float64(def float64) float64 {
method Duration (line 31) | func (v *value) Duration(def time.Duration) time.Duration {
method StringSlice (line 35) | func (v *value) StringSlice(def []string) []string {
method StringMap (line 39) | func (v *value) StringMap(def map[string]string) map[string]string {
method Scan (line 43) | func (v *value) Scan(val interface{}) error {
method Bytes (line 47) | func (v *value) Bytes() []byte {
function newValue (line 11) | func newValue() reader.Value {
FILE: contrib/go-micro-llamaindex/examples/basic_agent.py
function main (line 12) | def main():
FILE: contrib/go-micro-llamaindex/examples/rag_with_services.py
function main (line 15) | def main():
FILE: contrib/go-micro-llamaindex/go_micro_llamaindex/exceptions.py
class GoMicroError (line 4) | class GoMicroError(Exception):
class GoMicroConnectionError (line 9) | class GoMicroConnectionError(GoMicroError):
class GoMicroAuthError (line 14) | class GoMicroAuthError(GoMicroError):
class GoMicroToolError (line 19) | class GoMicroToolError(GoMicroError):
FILE: contrib/go-micro-llamaindex/go_micro_llamaindex/toolkit.py
class GoMicroConfig (line 20) | class GoMicroConfig:
class GoMicroTool (line 40) | class GoMicroTool(BaseModel):
class GoMicroToolkit (line 62) | class GoMicroToolkit:
method __init__ (line 75) | def __init__(self, config: GoMicroConfig):
method from_gateway (line 91) | def from_gateway(
method _make_request (line 117) | def _make_request(
method refresh (line 165) | def refresh(self) -> None:
method get_tools (line 188) | def get_tools(
method _create_llamaindex_tool (line 231) | def _create_llamaindex_tool(self, tool: GoMicroTool) -> FunctionTool:
method call_tool (line 263) | def call_tool(self, tool_name: str, arguments: str) -> str:
method list_tools (line 298) | def list_tools(self) -> List[GoMicroTool]:
FILE: contrib/go-micro-llamaindex/tests/test_toolkit.py
function mock_gateway_response (line 17) | def mock_gateway_response():
class TestGoMicroConfig (line 56) | class TestGoMicroConfig:
method test_config_defaults (line 59) | def test_config_defaults(self):
method test_config_custom_values (line 70) | def test_config_custom_values(self):
class TestGoMicroToolkit (line 89) | class TestGoMicroToolkit:
method test_from_gateway (line 92) | def test_from_gateway(self):
method test_from_gateway_with_auth (line 99) | def test_from_gateway_with_auth(self):
method test_refresh (line 111) | def test_refresh(self, mock_request, mock_gateway_response):
method test_get_tools (line 127) | def test_get_tools(self, mock_request, mock_gateway_response):
method test_get_tools_with_service_filter (line 144) | def test_get_tools_with_service_filter(self, mock_request, mock_gatewa...
method test_get_tools_with_include (line 159) | def test_get_tools_with_include(self, mock_request, mock_gateway_respo...
method test_get_tools_with_exclude (line 173) | def test_get_tools_with_exclude(self, mock_request, mock_gateway_respo...
method test_get_tools_with_name_pattern (line 188) | def test_get_tools_with_name_pattern(self, mock_request, mock_gateway_...
method test_call_tool (line 202) | def test_call_tool(self, mock_request):
method test_list_tools (line 216) | def test_list_tools(self, mock_request, mock_gateway_response):
method test_connection_error (line 232) | def test_connection_error(self, mock_request):
method test_auth_error (line 242) | def test_auth_error(self, mock_request):
method test_timeout (line 254) | def test_timeout(self, mock_request):
FILE: contrib/langchain-go-micro/examples/basic_agent.py
function main (line 12) | def main():
FILE: contrib/langchain-go-micro/examples/multi_agent.py
function main (line 12) | def main():
FILE: contrib/langchain-go-micro/langchain_go_micro/exceptions.py
class GoMicroError (line 4) | class GoMicroError(Exception):
class GoMicroConnectionError (line 9) | class GoMicroConnectionError(GoMicroError):
class GoMicroAuthError (line 14) | class GoMicroAuthError(GoMicroError):
class GoMicroToolError (line 19) | class GoMicroToolError(GoMicroError):
FILE: contrib/langchain-go-micro/langchain_go_micro/toolkit.py
class GoMicroConfig (line 20) | class GoMicroConfig:
class GoMicroTool (line 40) | class GoMicroTool(BaseModel):
class GoMicroToolkit (line 62) | class GoMicroToolkit:
method __init__ (line 75) | def __init__(self, config: GoMicroConfig):
method from_gateway (line 92) | def from_gateway(
method _make_request (line 118) | def _make_request(
method refresh (line 166) | def refresh(self) -> None:
method get_tools (line 189) | def get_tools(
method _create_langchain_tool (line 238) | def _create_langchain_tool(self, tool: GoMicroTool) -> Tool:
method call_tool (line 269) | def call_tool(self, tool_name: str, arguments: str) -> str:
method list_tools (line 306) | def list_tools(self) -> List[GoMicroTool]:
FILE: contrib/langchain-go-micro/tests/test_toolkit.py
function mock_gateway_response (line 17) | def mock_gateway_response():
class TestGoMicroConfig (line 48) | class TestGoMicroConfig:
method test_config_defaults (line 51) | def test_config_defaults(self):
method test_config_custom_values (line 62) | def test_config_custom_values(self):
class TestGoMicroToolkit (line 81) | class TestGoMicroToolkit:
method test_from_gateway (line 84) | def test_from_gateway(self):
method test_from_gateway_with_auth (line 91) | def test_from_gateway_with_auth(self):
method test_refresh (line 103) | def test_refresh(self, mock_request, mock_gateway_response):
method test_get_tools (line 118) | def test_get_tools(self, mock_request, mock_gateway_response):
method test_get_tools_with_service_filter (line 133) | def test_get_tools_with_service_filter(self, mock_request, mock_gatewa...
method test_get_tools_with_include (line 148) | def test_get_tools_with_include(self, mock_request, mock_gateway_respo...
method test_get_tools_with_exclude (line 162) | def test_get_tools_with_exclude(self, mock_request, mock_gateway_respo...
method test_call_tool (line 176) | def test_call_tool(self, mock_request):
method test_connection_error (line 190) | def test_connection_error(self, mock_request):
method test_auth_error (line 200) | def test_auth_error(self, mock_request):
method test_timeout (line 212) | def test_timeout(self, mock_request):
FILE: debug/handler/debug.go
function NewHandler (line 18) | func NewHandler(c client.Client) *Debug {
type Debug (line 28) | type Debug struct
method Health (line 39) | func (d *Debug) Health(ctx context.Context, req *proto.HealthRequest, ...
method MessageBus (line 44) | func (d *Debug) MessageBus(ctx context.Context, stream proto.Debug_Mes...
method Stats (line 63) | func (d *Debug) Stats(ctx context.Context, req *proto.StatsRequest, rs...
method Trace (line 86) | func (d *Debug) Trace(ctx context.Context, req *proto.TraceRequest, rs...
method Log (line 117) | func (d *Debug) Log(ctx context.Context, req *proto.LogRequest, stream...
FILE: debug/log/log.go
type Log (line 20) | type Log interface
type Record (line 30) | type Record struct
type Stream (line 40) | type Stream interface
type FormatFunc (line 46) | type FormatFunc
function TextFormat (line 49) | func TextFormat(r Record) string {
function JSONFormat (line 55) | func JSONFormat(r Record) string {
FILE: debug/log/memory/memory.go
type memoryLog (line 17) | type memoryLog struct
method Write (line 37) | func (l *memoryLog) Write(r log.Record) error {
method Read (line 43) | func (l *memoryLog) Read(opts ...log.ReadOption) ([]log.Record, error) {
method Stream (line 87) | func (l *memoryLog) Stream() (log.Stream, error) {
function NewLog (line 22) | func NewLog(opts ...log.Option) log.Log {
FILE: debug/log/memory/memory_test.go
function TestLogger (line 10) | func TestLogger(t *testing.T) {
FILE: debug/log/memory/stream.go
type logStream (line 7) | type logStream struct
method Chan (line 12) | func (l *logStream) Chan() <-chan log.Record {
method Stop (line 16) | func (l *logStream) Stop() error {
FILE: debug/log/noop/noop.go
type noop (line 7) | type noop struct
method Read (line 9) | func (n *noop) Read(...log.ReadOption) ([]log.Record, error) {
method Write (line 13) | func (n *noop) Write(log.Record) error {
method Stream (line 17) | func (n *noop) Stream() (log.Stream, error) {
function NewLog (line 21) | func NewLog(opts ...log.Option) log.Log {
FILE: debug/log/options.go
type Option (line 6) | type Option
type Options (line 9) | type Options struct
function Name (line 19) | func Name(n string) Option {
function Size (line 26) | func Size(s int) Option {
function Format (line 32) | func Format(f FormatFunc) Option {
function DefaultOptions (line 39) | func DefaultOptions() Options {
type ReadOptions (line 46) | type ReadOptions struct
type ReadOption (line 56) | type ReadOption
function Since (line 59) | func Since(s time.Time) ReadOption {
function Count (line 66) | func Count(c int) ReadOption {
FILE: debug/log/os.go
type osLog (line 11) | type osLog struct
method Read (line 25) | func (o *osLog) Read(...ReadOption) ([]Record, error) {
method Write (line 37) | func (o *osLog) Write(r Record) error {
method Stream (line 43) | func (o *osLog) Stream() (Stream, error) {
type osStream (line 20) | type osStream struct
method Chan (line 58) | func (o *osStream) Chan() <-chan Record {
method Stop (line 62) | func (o *osStream) Stop() error {
function NewLog (line 66) | func NewLog(opts ...Option) Log {
FILE: debug/profile/http/http.go
type httpProfile (line 13) | type httpProfile struct
method Start (line 24) | func (h *httpProfile) Start() error {
method Stop (line 46) | func (h *httpProfile) Stop() error {
method String (line 59) | func (h *httpProfile) String() string {
function NewProfile (line 63) | func NewProfile(opts ...profile.Option) profile.Profile {
FILE: debug/profile/pprof/pprof.go
type profiler (line 14) | type profiler struct
method Start (line 26) | func (p *profiler) Start() error {
method Stop (line 67) | func (p *profiler) Stop() error {
method String (line 86) | func (p *profiler) String() string {
function NewProfile (line 90) | func NewProfile(opts ...profile.Option) profile.Profile {
FILE: debug/profile/profile.go
type Profile (line 4) | type Profile interface
type noop (line 17) | type noop struct
method Start (line 19) | func (p *noop) Start() error {
method Stop (line 23) | func (p *noop) Stop() error {
method String (line 27) | func (p *noop) String() string {
type Options (line 31) | type Options struct
type Option (line 36) | type Option
function Name (line 39) | func Name(n string) Option {
FILE: debug/proto/debug.pb.go
constant _ (line 18) | _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
constant _ (line 20) | _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
type SpanType (line 23) | type SpanType
method Enum (line 42) | func (x SpanType) Enum() *SpanType {
method String (line 48) | func (x SpanType) String() string {
method Descriptor (line 52) | func (SpanType) Descriptor() protoreflect.EnumDescriptor {
method Type (line 56) | func (SpanType) Type() protoreflect.EnumType {
method Number (line 60) | func (x SpanType) Number() protoreflect.EnumNumber {
method EnumDescriptor (line 65) | func (SpanType) EnumDescriptor() ([]byte, []int) {
constant SpanType_INBOUND (line 26) | SpanType_INBOUND SpanType = 0
constant SpanType_OUTBOUND (line 27) | SpanType_OUTBOUND SpanType = 1
type BusMsg (line 69) | type BusMsg struct
method Reset (line 77) | func (x *BusMsg) Reset() {
method String (line 86) | func (x *BusMsg) String() string {
method ProtoMessage (line 90) | func (*BusMsg) ProtoMessage() {}
method ProtoReflect (line 92) | func (x *BusMsg) ProtoReflect() protoreflect.Message {
method Descriptor (line 105) | func (*BusMsg) Descriptor() ([]byte, []int) {
method GetMsg (line 109) | func (x *BusMsg) GetMsg() string {
type HealthRequest (line 116) | type HealthRequest struct
method Reset (line 125) | func (x *HealthRequest) Reset() {
method String (line 134) | func (x *HealthRequest) String() string {
method ProtoMessage (line 138) | func (*HealthRequest) ProtoMessage() {}
method ProtoReflect (line 140) | func (x *HealthRequest) ProtoReflect() protoreflect.Message {
method Descriptor (line 153) | func (*HealthRequest) Descriptor() ([]byte, []int) {
method GetService (line 157) | func (x *HealthRequest) GetService() string {
type HealthResponse (line 164) | type HealthResponse struct
method Reset (line 173) | func (x *HealthResponse) Reset() {
method String (line 182) | func (x *HealthResponse) String() string {
method ProtoMessage (line 186) | func (*HealthResponse) ProtoMessage() {}
method ProtoReflect (line 188) | func (x *HealthResponse) ProtoReflect() protoreflect.Message {
method Descriptor (line 201) | func (*HealthResponse) Descriptor() ([]byte, []int) {
method GetStatus (line 205) | func (x *HealthResponse) GetStatus() string {
type StatsRequest (line 212) | type StatsRequest struct
method Reset (line 221) | func (x *StatsRequest) Reset() {
method String (line 230) | func (x *StatsRequest) String() string {
method ProtoMessage (line 234) | func (*StatsRequest) ProtoMessage() {}
method ProtoReflect (line 236) | func (x *StatsRequest) ProtoReflect() protoreflect.Message {
method Descriptor (line 249) | func (*StatsRequest) Descriptor() ([]byte, []int) {
method GetService (line 253) | func (x *StatsRequest) GetService() string {
type StatsResponse (line 260) | type StatsResponse struct
method Reset (line 283) | func (x *StatsResponse) Reset() {
method String (line 292) | func (x *StatsResponse) String() string {
method ProtoMessage (line 296) | func (*StatsResponse) ProtoMessage() {}
method ProtoReflect (line 298) | func (x *StatsResponse) ProtoReflect() protoreflect.Message {
method Descriptor (line 311) | func (*StatsResponse) Descriptor() ([]byte, []int) {
method GetTimestamp (line 315) | func (x *StatsResponse) GetTimestamp() uint64 {
method GetStarted (line 322) | func (x *StatsResponse) GetStarted() uint64 {
method GetUptime (line 329) | func (x *StatsResponse) GetUptime() uint64 {
method GetMemory (line 336) | func (x *StatsResponse) GetMemory() uint64 {
method GetThreads (line 343) | func (x *StatsResponse) GetThreads() uint64 {
method GetGc (line 350) | func (x *StatsResponse) GetGc() uint64 {
method GetRequests (line 357) | func (x *StatsResponse) GetRequests() uint64 {
method GetErrors (line 364) | func (x *StatsResponse) GetErrors() uint64 {
type LogRequest (line 372) | type LogRequest struct
method Reset (line 389) | func (x *LogRequest) Reset() {
method String (line 398) | func (x *LogRequest) String() string {
method ProtoMessage (line 402) | func (*LogRequest) ProtoMessage() {}
method ProtoReflect (line 404) | func (x *LogRequest) ProtoReflect() protoreflect.Message {
method Descriptor (line 417) | func (*LogRequest) Descriptor() ([]byte, []int) {
method GetService (line 421) | func (x *LogRequest) GetService() string {
method GetStream (line 428) | func (x *LogRequest) GetStream() bool {
method GetCount (line 435) | func (x *LogRequest) GetCount() int64 {
method GetSince (line 442) | func (x *LogRequest) GetSince() int64 {
type Record (line 451) | type Record struct
method Reset (line 464) | func (x *Record) Reset() {
method String (line 473) | func (x *Record) String() string {
method ProtoMessage (line 477) | func (*Record) ProtoMessage() {}
method ProtoReflect (line 479) | func (x *Record) ProtoReflect() protoreflect.Message {
method Descriptor (line 492) | func (*Record) Descriptor() ([]byte, []int) {
method GetTimestamp (line 496) | func (x *Record) GetTimestamp() int64 {
method GetMetadata (line 503) | func (x *Record) GetMetadata() map[string]string {
method GetMessage (line 510) | func (x *Record) GetMessage() string {
type TraceRequest (line 517) | type TraceRequest struct
method Reset (line 526) | func (x *TraceRequest) Reset() {
method String (line 535) | func (x *TraceRequest) String() string {
method ProtoMessage (line 539) | func (*TraceRequest) ProtoMessage() {}
method ProtoReflect (line 541) | func (x *TraceRequest) ProtoReflect() protoreflect.Message {
method Descriptor (line 554) | func (*TraceRequest) Descriptor() ([]byte, []int) {
method GetId (line 558) | func (x *TraceRequest) GetId() string {
type TraceResponse (line 565) | type TraceResponse struct
method Reset (line 573) | func (x *TraceResponse) Reset() {
method String (line 582) | func (x *TraceResponse) String() string {
method ProtoMessage (line 586) | func (*TraceResponse) ProtoMessage() {}
method ProtoReflect (line 588) | func (x *TraceResponse) ProtoReflect() protoreflect.Message {
method Descriptor (line 601) | func (*TraceResponse) Descriptor() ([]byte, []int) {
method GetSpans (line 605) | func (x *TraceResponse) GetSpans() []*Span {
type Span (line 612) | type Span struct
method Reset (line 634) | func (x *Span) Reset() {
method String (line 643) | func (x *Span) String() string {
method ProtoMessage (line 647) | func (*Span) ProtoMessage() {}
method ProtoReflect (line 649) | func (x *Span) ProtoReflect() protoreflect.Message {
method Descriptor (line 662) | func (*Span) Descriptor() ([]byte, []int) {
method GetTrace (line 666) | func (x *Span) GetTrace() string {
method GetId (line 673) | func (x *Span) GetId() string {
method GetParent (line 680) | func (x *Span) GetParent() string {
method GetName (line 687) | func (x *Span) GetName() string {
method GetStarted (line 694) | func (x *Span) GetStarted() uint64 {
method GetDuration (line 701) | func (x *Span) GetDuration() uint64 {
method GetMetadata (line 708) | func (x *Span) GetMetadata() map[string]string {
method GetType (line 715) | func (x *Span) GetType() SpanType {
function file_proto_debug_proto_rawDescGZIP (line 820) | func file_proto_debug_proto_rawDescGZIP() []byte {
function init (line 866) | func init() { file_proto_debug_proto_init() }
function file_proto_debug_proto_init (line 867) | func file_proto_debug_proto_init() {
FILE: debug/proto/debug.pb.micro.go
type DebugService (line 30) | type DebugService interface
type debugService (line 38) | type debugService struct
method Log (line 50) | func (c *debugService) Log(ctx context.Context, in *LogRequest, opts ....
method Health (line 104) | func (c *debugService) Health(ctx context.Context, in *HealthRequest, ...
method Stats (line 114) | func (c *debugService) Stats(ctx context.Context, in *StatsRequest, op...
method Trace (line 124) | func (c *debugService) Trace(ctx context.Context, in *TraceRequest, op...
method MessageBus (line 134) | func (c *debugService) MessageBus(ctx context.Context, opts ...client....
function NewDebugService (line 43) | func NewDebugService(name string, c client.Client) DebugService {
type Debug_LogService (line 62) | type Debug_LogService interface
type debugServiceLog (line 71) | type debugServiceLog struct
method CloseSend (line 75) | func (x *debugServiceLog) CloseSend() error {
method Close (line 79) | func (x *debugServiceLog) Close() error {
method Context (line 83) | func (x *debugServiceLog) Context() context.Context {
method SendMsg (line 87) | func (x *debugServiceLog) SendMsg(m interface{}) error {
method RecvMsg (line 91) | func (x *debugServiceLog) RecvMsg(m interface{}) error {
method Recv (line 95) | func (x *debugServiceLog) Recv() (*Record, error) {
type Debug_MessageBusService (line 143) | type Debug_MessageBusService interface
type debugServiceMessageBus (line 153) | type debugServiceMessageBus struct
method CloseSend (line 157) | func (x *debugServiceMessageBus) CloseSend() error {
method Close (line 161) | func (x *debugServiceMessageBus) Close() error {
method Context (line 165) | func (x *debugServiceMessageBus) Context() context.Context {
method SendMsg (line 169) | func (x *debugServiceMessageBus) SendMsg(m interface{}) error {
method RecvMsg (line 173) | func (x *debugServiceMessageBus) RecvMsg(m interface{}) error {
method Send (line 177) | func (x *debugServiceMessageBus) Send(m *BusMsg) error {
method Recv (line 181) | func (x *debugServiceMessageBus) Recv() (*BusMsg, error) {
type DebugHandler (line 192) | type DebugHandler interface
function RegisterDebugHandler (line 200) | func RegisterDebugHandler(s server.Server, hdlr DebugHandler, opts ...se...
type debugHandler (line 215) | type debugHandler struct
method Log (line 219) | func (h *debugHandler) Log(ctx context.Context, stream server.Stream) ...
method Health (line 259) | func (h *debugHandler) Health(ctx context.Context, in *HealthRequest, ...
method Stats (line 263) | func (h *debugHandler) Stats(ctx context.Context, in *StatsRequest, ou...
method Trace (line 267) | func (h *debugHandler) Trace(ctx context.Context, in *TraceRequest, ou...
method MessageBus (line 271) | func (h *debugHandler) MessageBus(ctx context.Context, stream server.S...
type Debug_LogStream (line 227) | type Debug_LogStream interface
type debugLogStream (line 235) | type debugLogStream struct
method Close (line 239) | func (x *debugLogStream) Close() error {
method Context (line 243) | func (x *debugLogStream) Context() context.Context {
method SendMsg (line 247) | func (x *debugLogStream) SendMsg(m interface{}) error {
method RecvMsg (line 251) | func (x *debugLogStream) RecvMsg(m interface{}) error {
method Send (line 255) | func (x *debugLogStream) Send(m *Record) error {
type Debug_MessageBusStream (line 275) | type Debug_MessageBusStream interface
type debugMessageBusStream (line 284) | type debugMessageBusStream struct
method Close (line 288) | func (x *debugMessageBusStream) Close() error {
method Context (line 292) | func (x *debugMessageBusStream) Context() context.Context {
method SendMsg (line 296) | func (x *debugMessageBusStream) SendMsg(m interface{}) error {
method RecvMsg (line 300) | func (x *debugMessageBusStream) RecvMsg(m interface{}) error {
method Send (line 304) | func (x *debugMessageBusStream) Send(m *BusMsg) error {
method Recv (line 308) | func (x *debugMessageBusStream) Recv() (*BusMsg, error) {
FILE: debug/stats/default.go
type stats (line 11) | type stats struct
method snapshot (line 21) | func (s *stats) snapshot() *Stat {
method Read (line 42) | func (s *stats) Read() ([]*Stat, error) {
method Write (line 62) | func (s *stats) Write(stat *Stat) error {
method Record (line 67) | func (s *stats) Record(err error) error {
function NewStats (line 84) | func NewStats() Stats {
FILE: debug/stats/stats.go
type Stats (line 5) | type Stats interface
type Stat (line 15) | type Stat struct
FILE: debug/trace/default.go
type memTracer (line 11) | type memTracer struct
method Read (line 18) | func (t *memTracer) Read(opts ...ReadOption) ([]*Span, error) {
method Start (line 40) | func (t *memTracer) Start(ctx context.Context, name string) (context.C...
method Finish (line 69) | func (t *memTracer) Finish(s *Span) error {
function NewTracer (line 78) | func NewTracer(opts ...Option) Tracer {
FILE: debug/trace/noop.go
type noop (line 5) | type noop struct
method Init (line 7) | func (n *noop) Init(...Option) error {
method Start (line 11) | func (n *noop) Start(ctx context.Context, name string) (context.Contex...
method Finish (line 15) | func (n *noop) Finish(*Span) error {
method Read (line 19) | func (n *noop) Read(...ReadOption) ([]*Span, error) {
FILE: debug/trace/options.go
type Options (line 3) | type Options struct
type Option (line 8) | type Option
type ReadOptions (line 10) | type ReadOptions struct
type ReadOption (line 15) | type ReadOption
function ReadTrace (line 18) | func ReadTrace(t string) ReadOption {
constant DefaultSize (line 26) | DefaultSize = 64
function DefaultOptions (line 30) | func DefaultOptions() Options {
FILE: debug/trace/trace.go
type Tracer (line 18) | type Tracer interface
type SpanType (line 28) | type SpanType
constant SpanTypeRequestInbound (line 32) | SpanTypeRequestInbound SpanType = iota
constant SpanTypeRequestOutbound (line 34) | SpanTypeRequestOutbound
type Span (line 38) | type Span struct
function FromContext (line 58) | func FromContext(ctx context.Context) (traceID string, parentSpanID stri...
function ToContext (line 77) | func ToContext(ctx context.Context, traceID, parentSpanID string) contex...
FILE: errors/errors.go
method Error (line 14) | func (e *Error) Error() string {
function New (line 20) | func New(id, detail string, code int32) error {
function Parse (line 31) | func Parse(err string) *Error {
function newError (line 40) | func newError(id string, code int32, detail string, a ...interface{}) er...
function BadRequest (line 53) | func BadRequest(id, format string, a ...interface{}) error {
function Unauthorized (line 58) | func Unauthorized(id, format string, a ...interface{}) error {
function Forbidden (line 63) | func Forbidden(id, format string, a ...interface{}) error {
function NotFound (line 68) | func NotFound(id, format string, a ...interface{}) error {
function MethodNotAllowed (line 73) | func MethodNotAllowed(id, format string, a ...interface{}) error {
function Timeout (line 78) | func Timeout(id, format string, a ...interface{}) error {
function Conflict (line 83) | func Conflict(id, format string, a ...interface{}) error {
function InternalServerError (line 88) | func InternalServerError(id, format string, a ...interface{}) error {
function Equal (line 93) | func Equal(err1 error, err2 error) bool {
function FromError (line 113) | func FromError(err error) *Error {
function As (line 125) | func As(err error) (*Error, bool) {
function NewMultiError (line 136) | func NewMultiError() *MultiError {
method Append (line 142) | func (e *MultiError) Append(err ...*Error) {
method HasErrors (line 146) | func (e *MultiError) HasErrors() bool {
method Error (line 150) | func (e *MultiError) Error() string {
FILE: errors/errors.pb.go
constant _ (line 18) | _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
constant _ (line 20) | _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
type Error (line 23) | type Error struct
method Reset (line 34) | func (x *Error) Reset() {
method String (line 43) | func (x *Error) String() string {
method ProtoMessage (line 47) | func (*Error) ProtoMessage() {}
method ProtoReflect (line 49) | func (x *Error) ProtoReflect() protoreflect.Message {
method Descriptor (line 62) | func (*Error) Descriptor() ([]byte, []int) {
method GetId (line 66) | func (x *Error) GetId() string {
method GetCode (line 73) | func (x *Error) GetCode() int32 {
method GetDetail (line 80) | func (x *Error) GetDetail() string {
method GetStatus (line 87) | func (x *Error) GetStatus() string {
type MultiError (line 94) | type MultiError struct
method Reset (line 102) | func (x *MultiError) Reset() {
method String (line 111) | func (x *MultiError) String() string {
method ProtoMessage (line 115) | func (*MultiError) ProtoMessage() {}
method ProtoReflect (line 117) | func (x *MultiError) ProtoReflect() protoreflect.Message {
method Descriptor (line 130) | func (*MultiError) Descriptor() ([]byte, []int) {
method GetErrors (line 134) | func (x *MultiError) GetErrors() []*Error {
function file_errors_proto_rawDescGZIP (line 163) | func file_errors_proto_rawDescGZIP() []byte {
function init (line 184) | func init() { file_errors_proto_init() }
function file_errors_proto_init (line 185) | func file_errors_proto_init() {
FILE: errors/errors_test.go
function TestFromError (line 9) | func TestFromError(t *testing.T) {
function TestEqual (line 26) | func TestEqual(t *testing.T) {
function TestErrors (line 40) | func TestErrors(t *testing.T) {
function TestAs (line 81) | func TestAs(t *testing.T) {
function TestAppend (line 101) | func TestAppend(t *testing.T) {
function TestHasErrors (line 131) | func TestHasErrors(t *testing.T) {
FILE: event.go
type event (line 9) | type event struct
method Publish (line 14) | func (e *event) Publish(ctx context.Context, msg interface{}, opts ......
FILE: events/events.go
type Stream (line 25) | type Stream interface
type Store (line 31) | type Store interface
type AckFunc (line 36) | type AckFunc
type NackFunc (line 37) | type NackFunc
type Event (line 40) | type Event struct
method Unmarshal (line 57) | func (e *Event) Unmarshal(v interface{}) error {
method Ack (line 62) | func (e *Event) Ack() error {
method SetAckFunc (line 66) | func (e *Event) SetAckFunc(f AckFunc) {
method Nack (line 71) | func (e *Event) Nack() error {
method SetNackFunc (line 75) | func (e *Event) SetNackFunc(f NackFunc) {
function Publish (line 80) | func Publish(topic string, msg interface{}, opts ...PublishOption) error {
function Consume (line 85) | func Consume(topic string, opts ...ConsumeOption) (<-chan Event, error) {
function Read (line 90) | func Read(topic string, opts ...ReadOption) ([]*Event, error) {
FILE: events/memory.go
function NewStream (line 16) | func NewStream(opts ...Option) (Stream, error) {
type subscriber (line 25) | type subscriber struct
type mem (line 37) | type mem struct
method Publish (line 44) | func (m *mem) Publish(topic string, msg interface{}, opts ...PublishOp...
method Consume (line 97) | func (m *mem) Consume(topic string, opts ...ConsumeOption) (<-chan Eve...
method lookupPreviousEvents (line 149) | func (m *mem) lookupPreviousEvents(sub *subscriber, startTime time.Tim...
method handleEvent (line 173) | func (m *mem) handleEvent(ev *Event) {
function sendEvent (line 195) | func sendEvent(ev *Event, sub *subscriber) {
function ackFunc (line 235) | func ackFunc(s *subscriber, evCopy Event) func() error {
function nackFunc (line 244) | func nackFunc(_ *subscriber, _ Event) func() error {
FILE: events/natsjs/helpers_test.go
function getFreeLocalhostAddress (line 15) | func getFreeLocalhostAddress() string {
function natsServer (line 21) | func natsServer(ctx context.Context, t *testing.T, opts *nserver.Options) {
function NewLogWrapper (line 59) | func NewLogWrapper() *LogWrapper {
type LogWrapper (line 63) | type LogWrapper struct
method Noticef (line 67) | func (l *LogWrapper) Noticef(format string, v ...interface{}) {
method Warnf (line 72) | func (l *LogWrapper) Warnf(format string, v ...interface{}) {
method Fatalf (line 77) | func (l *LogWrapper) Fatalf(format string, v ...interface{}) {
method Errorf (line 82) | func (l *LogWrapper) Errorf(format string, v ...interface{}) {
method Debugf (line 87) | func (l *LogWrapper) Debugf(format string, v ...interface{}) {
method Tracef (line 92) | func (l *LogWrapper) Tracef(format string, v ...interface{}) {
FILE: events/natsjs/nats.go
constant defaultClusterID (line 21) | defaultClusterID = "micro"
function NewStream (line 26) | func NewStream(opts ...Option) (events.Stream, error) {
type stream (line 50) | type stream struct
method Publish (line 96) | func (s *stream) Publish(topic string, msg interface{}, opts ...events...
method Consume (line 157) | func (s *stream) Consume(topic string, opts ...events.ConsumeOption) (...
method Close (line 278) | func (s *stream) Close() error {
function connectToNatsJetStream (line 56) | func connectToNatsJetStream(options Options) (*nats.Conn, nats.JetStream...
FILE: events/natsjs/nats_test.go
type Payload (line 18) | type Payload struct
function TestSingleEvent (line 23) | func TestSingleEvent(t *testing.T) {
FILE: events/natsjs/options.go
type Options (line 11) | type Options struct
type Option (line 29) | type Option
function ClusterID (line 32) | func ClusterID(id string) Option {
function ClientID (line 39) | func ClientID(id string) Option {
function Address (line 46) | func Address(addr string) Option {
function TLSConfig (line 53) | func TLSConfig(t *tls.Config) Option {
function NkeyConfig (line 60) | func NkeyConfig(nkey string) Option {
function Logger (line 67) | func Logger(log logger.Logger) Option {
function SynchronousPublish (line 74) | func SynchronousPublish(sync bool) Option {
function Name (line 81) | func Name(name string) Option {
function DisableDurableStreams (line 88) | func DisableDurableStreams() Option {
function Authenticate (line 95) | func Authenticate(username, password string) Option {
function RetentionPolicy (line 101) | func RetentionPolicy(rp int) Option {
function MaxMsgSize (line 107) | func MaxMsgSize(size int) Option {
function MaxAge (line 112) | func MaxAge(age time.Duration) Option {
FILE: events/options.go
type Options (line 5) | type Options struct
type Option (line 7) | type Option
type StoreOptions (line 9) | type StoreOptions struct
type StoreOption (line 14) | type StoreOption
type PublishOptions (line 17) | type PublishOptions struct
type PublishOption (line 25) | type PublishOption
function WithMetadata (line 28) | func WithMetadata(md map[string]string) PublishOption {
function WithTimestamp (line 35) | func WithTimestamp(t time.Time) PublishOption {
type ConsumeOptions (line 42) | type ConsumeOptions struct
method GetRetryLimit (line 97) | func (s ConsumeOptions) GetRetryLimit() int {
type ConsumeOption (line 63) | type ConsumeOption
function WithGroup (line 66) | func WithGroup(q string) ConsumeOption {
function WithOffset (line 73) | func WithOffset(t time.Time) ConsumeOption {
function WithAutoAck (line 81) | func WithAutoAck(ack bool, ackWait time.Duration) ConsumeOption {
function WithRetryLimit (line 90) | func WithRetryLimit(retries int) ConsumeOption {
type WriteOptions (line 105) | type WriteOptions struct
type WriteOption (line 112) | type WriteOption
function WithTTL (line 115) | func WithTTL(d time.Duration) WriteOption {
type ReadOptions (line 122) | type ReadOptions struct
type ReadOption (line 130) | type ReadOption
function ReadLimit (line 133) | func ReadLimit(l uint) ReadOption {
function ReadOffset (line 140) | func ReadOffset(l uint) ReadOption {
FILE: events/store.go
constant joinKey (line 12) | joinKey = "/"
function NewStore (line 15) | func NewStore(opts ...StoreOption) Store {
type evStore (line 36) | type evStore struct
method Read (line 42) | func (s *evStore) Read(topic string, opts ...ReadOption) ([]*Event, er...
method Write (line 81) | func (s *evStore) Write(event *Event, opts ...WriteOption) error {
method backupLoop (line 113) | func (s *evStore) backupLoop() {
type Backup (line 125) | type Backup interface
FILE: events/store_test.go
function TestStore (line 10) | func TestStore(t *testing.T) {
FILE: events/stream_test.go
type testPayload (line 12) | type testPayload struct
type testCase (line 16) | type testCase struct
function TestStream (line 21) | func TestStream(t *testing.T) {
function runTestStream (line 37) | func runTestStream(t *testing.T, stream Stream) {
FILE: examples/agent-demo/main.go
type Project (line 31) | type Project struct
type CreateProjectRequest (line 39) | type CreateProjectRequest struct
type CreateProjectResponse (line 44) | type CreateProjectResponse struct
type GetProjectRequest (line 48) | type GetProjectRequest struct
type GetProjectResponse (line 52) | type GetProjectResponse struct
type ListProjectsRequest (line 56) | type ListProjectsRequest struct
type ListProjectsResponse (line 60) | type ListProjectsResponse struct
type ProjectService (line 64) | type ProjectService struct
method Create (line 74) | func (s *ProjectService) Create(ctx context.Context, req *CreateProjec...
method Get (line 94) | func (s *ProjectService) Get(ctx context.Context, req *GetProjectReque...
method List (line 109) | func (s *ProjectService) List(ctx context.Context, req *ListProjectsRe...
type Task (line 124) | type Task struct
type CreateTaskRequest (line 133) | type CreateTaskRequest struct
type CreateTaskResponse (line 140) | type CreateTaskResponse struct
type ListTasksRequest (line 144) | type ListTasksRequest struct
type ListTasksResponse (line 150) | type ListTasksResponse struct
type UpdateTaskRequest (line 154) | type UpdateTaskRequest struct
type UpdateTaskResponse (line 160) | type UpdateTaskResponse struct
type TaskService (line 164) | type TaskService struct
method Create (line 174) | func (s *TaskService) Create(ctx context.Context, req *CreateTaskReque...
method List (line 199) | func (s *TaskService) List(ctx context.Context, req *ListTasksRequest,...
method Update (line 222) | func (s *TaskService) Update(ctx context.Context, req *UpdateTaskReque...
type Member (line 243) | type Member struct
type AddMemberRequest (line 250) | type AddMemberRequest struct
type AddMemberResponse (line 257) | type AddMemberResponse struct
type ListMembersRequest (line 261) | type ListMembersRequest struct
type ListMembersResponse (line 266) | type ListMembersResponse struct
type GetMemberRequest (line 270) | type GetMemberRequest struct
type GetMemberResponse (line 274) | type GetMemberResponse struct
type TeamService (line 278) | type TeamService struct
method Add (line 287) | func (s *TeamService) Add(ctx context.Context, req *AddMemberRequest, ...
method List (line 304) | func (s *TeamService) List(ctx context.Context, req *ListMembersReques...
method Get (line 323) | func (s *TeamService) Get(ctx context.Context, req *GetMemberRequest, ...
function hasSkill (line 334) | func hasSkill(skills []string, target string) bool {
function main (line 347) | func main() {
function seedData (line 401) | func seedData(srv server.Server) {
FILE: examples/auth/client/main.go
function main (line 18) | func main() {
FILE: examples/auth/proto/greeter.pb.go
type Request (line 16) | type Request struct
method Reset (line 20) | func (m *Request) Reset() { *m = Request{} }
method String (line 21) | func (m *Request) String() string { return fmt.Sprintf("Request{Name:%...
method ProtoMessage (line 22) | func (*Request) ProtoMessage() {}
method GetName (line 24) | func (m *Request) GetName() string {
type Response (line 31) | type Response struct
method Reset (line 35) | func (m *Response) Reset() { *m = Response{} }
method String (line 36) | func (m *Response) String() string { return fmt.Sprintf("Response{Msg:...
method ProtoMessage (line 37) | func (*Response) ProtoMessage() {}
method GetMsg (line 39) | func (m *Response) GetMsg() string {
type HealthRequest (line 46) | type HealthRequest struct
method Reset (line 48) | func (m *HealthRequest) Reset() { *m = HealthRequest{} }
method String (line 49) | func (m *HealthRequest) String() string { return "HealthRequest{}" }
method ProtoMessage (line 50) | func (*HealthRequest) ProtoMessage() {}
type HealthResponse (line 52) | type HealthResponse struct
method Reset (line 56) | func (m *HealthResponse) Reset() { *m = HealthResponse{} }
method String (line 57) | func (m *HealthResponse) String() string { return fmt.Sprintf("HealthR...
method ProtoMessage (line 58) | func (*HealthResponse) ProtoMessage() {}
method GetStatus (line 60) | func (m *HealthResponse) GetStatus() string {
function init (line 67) | func init() {
type GreeterService (line 78) | type GreeterService interface
type greeterService (line 83) | type greeterService struct
method Hello (line 95) | func (c *greeterService) Hello(ctx context.Context, in *Request, opts ...
method Health (line 105) | func (c *greeterService) Health(ctx context.Context, in *HealthRequest...
function NewGreeterService (line 88) | func NewGreeterService(name string, c client.Client) GreeterService {
type GreeterHandler (line 117) | type GreeterHandler interface
function RegisterGreeterHandler (line 122) | func RegisterGreeterHandler(s server.Server, hdlr GreeterHandler, opts ....
type greeterHandler (line 134) | type greeterHandler struct
method Hello (line 138) | func (h *greeterHandler) Hello(ctx context.Context, in *Request, out *...
method Health (line 142) | func (h *greeterHandler) Health(ctx context.Context, in *HealthRequest...
FILE: examples/auth/server/main.go
type Greeter (line 16) | type Greeter struct
method Hello (line 19) | func (g *Greeter) Hello(ctx context.Context, req *pb.Request, rsp *pb....
method Health (line 32) | func (g *Greeter) Health(ctx context.Context, req *pb.HealthRequest, r...
function main (line 37) | func main() {
FILE: examples/hello-world/main.go
type Request (line 12) | type Request struct
type Response (line 16) | type Response struct
type Greeter (line 21) | type Greeter struct
method Hello (line 24) | func (g *Greeter) Hello(ctx context.Context, req *Request, rsp *Respon...
function main (line 30) | func main() {
FILE: examples/mcp/crud/main.go
type Contact (line 29) | type Contact struct
type CreateRequest (line 38) | type CreateRequest struct
type CreateResponse (line 46) | type CreateResponse struct
type GetRequest (line 50) | type GetRequest struct
type GetResponse (line 54) | type GetResponse struct
type UpdateRequest (line 58) | type UpdateRequest struct
type UpdateResponse (line 67) | type UpdateResponse struct
type DeleteRequest (line 71) | type DeleteRequest struct
type DeleteResponse (line 75) | type DeleteResponse struct
type ListRequest (line 79) | type ListRequest struct
type ListResponse (line 82) | type ListResponse struct
type SearchRequest (line 86) | type SearchRequest struct
type SearchResponse (line 90) | type SearchResponse struct
type Contacts (line 97) | type Contacts struct
method Create (line 116) | func (h *Contacts) Create(ctx context.Context, req *CreateRequest, rsp...
method Get (line 145) | func (h *Contacts) Get(ctx context.Context, req *GetRequest, rsp *GetR...
method Update (line 165) | func (h *Contacts) Update(ctx context.Context, req *UpdateRequest, rsp...
method Delete (line 201) | func (h *Contacts) Delete(ctx context.Context, req *DeleteRequest, rsp...
method List (line 221) | func (h *Contacts) List(ctx context.Context, req *ListRequest, rsp *Li...
method Search (line 235) | func (h *Contacts) Search(ctx context.Context, req *SearchRequest, rsp...
function NewContacts (line 103) | func NewContacts() *Contacts {
function main (line 255) | func main() {
FILE: examples/mcp/documented/main.go
type User (line 19) | type User struct
type GetUserRequest (line 27) | type GetUserRequest struct
type GetUserResponse (line 32) | type GetUserResponse struct
type CreateUserRequest (line 37) | type CreateUserRequest struct
type CreateUserResponse (line 44) | type CreateUserResponse struct
type Users (line 49) | type Users struct
method GetUser (line 56) | func (u *Users) GetUser(ctx context.Context, req *GetUserRequest, rsp ...
method CreateUser (line 69) | func (u *Users) CreateUser(ctx context.Context, req *CreateUserRequest...
function main (line 91) | func main() {
FILE: examples/mcp/hello/main.go
type Greeter (line 18) | type Greeter struct
method SayHello (line 23) | func (g *Greeter) SayHello(ctx context.Context, req *HelloRequest, rsp...
type HelloRequest (line 29) | type HelloRequest struct
type HelloResponse (line 34) | type HelloResponse struct
function main (line 38) | func main() {
FILE: examples/mcp/platform/main.go
type User (line 47) | type User struct
type SignupRequest (line 54) | type SignupRequest struct
type SignupResponse (line 58) | type SignupResponse struct
type LoginRequest (line 63) | type LoginRequest struct
type LoginResponse (line 67) | type LoginResponse struct
type GetProfileRequest (line 72) | type GetProfileRequest struct
type GetProfileResponse (line 75) | type GetProfileResponse struct
type UpdateStatusRequest (line 79) | type UpdateStatusRequest struct
type UpdateStatusResponse (line 83) | type UpdateStatusResponse struct
type ListUsersRequest (line 87) | type ListUsersRequest struct
type ListUsersResponse (line 88) | type ListUsersResponse struct
type Users (line 92) | type Users struct
method Signup (line 112) | func (s *Users) Signup(ctx context.Context, req *SignupRequest, rsp *S...
method Login (line 151) | func (s *Users) Login(ctx context.Context, req *LoginRequest, rsp *Log...
method GetProfile (line 176) | func (s *Users) GetProfile(ctx context.Context, req *GetProfileRequest...
method UpdateStatus (line 191) | func (s *Users) UpdateStatus(ctx context.Context, req *UpdateStatusReq...
method List (line 207) | func (s *Users) List(ctx context.Context, req *ListUsersRequest, rsp *...
function NewUsers (line 100) | func NewUsers() *Users {
type Post (line 221) | type Post struct
type CreatePostRequest (line 232) | type CreatePostRequest struct
type CreatePostResponse (line 238) | type CreatePostResponse struct
type ReadPostRequest (line 242) | type ReadPostRequest struct
type ReadPostResponse (line 245) | type ReadPostResponse struct
type UpdatePostRequest (line 249) | type UpdatePostRequest struct
type UpdatePostResponse (line 254) | type UpdatePostResponse struct
type DeletePostRequest (line 258) | type DeletePostRequest struct
type DeletePostResponse (line 261) | type DeletePostResponse struct
type ListPostsRequest (line 265) | type ListPostsRequest struct
type ListPostsResponse (line 268) | type ListPostsResponse struct
type TagPostRequest (line 273) | type TagPostRequest struct
type TagPostResponse (line 277) | type TagPostResponse struct
type UntagPostRequest (line 281) | type UntagPostRequest struct
type UntagPostResponse (line 285) | type UntagPostResponse struct
type ListTagsRequest (line 289) | type ListTagsRequest struct
type ListTagsResponse (line 290) | type ListTagsResponse struct
type Posts (line 294) | type Posts struct
method Create (line 308) | func (s *Posts) Create(ctx context.Context, req *CreatePostRequest, rs...
method Read (line 341) | func (s *Posts) Read(ctx context.Context, req *ReadPostRequest, rsp *R...
method Update (line 357) | func (s *Posts) Update(ctx context.Context, req *UpdatePostRequest, rs...
method Delete (line 379) | func (s *Posts) Delete(ctx context.Context, req *DeletePostRequest, rs...
method List (line 395) | func (s *Posts) List(ctx context.Context, req *ListPostsRequest, rsp *...
method TagPost (line 416) | func (s *Posts) TagPost(ctx context.Context, req *TagPostRequest, rsp ...
method UntagPost (line 445) | func (s *Posts) UntagPost(ctx context.Context, req *UntagPostRequest, ...
method ListTags (line 469) | func (s *Posts) ListTags(ctx context.Context, req *ListTagsRequest, rs...
function NewPosts (line 300) | func NewPosts() *Posts {
type Comment (line 490) | type Comment struct
type CreateCommentRequest (line 499) | type CreateCommentRequest struct
type CreateCommentResponse (line 505) | type CreateCommentResponse struct
type ListCommentsRequest (line 509) | type ListCommentsRequest struct
type ListCommentsResponse (line 513) | type ListCommentsResponse struct
type DeleteCommentRequest (line 517) | type DeleteCommentRequest struct
type DeleteCommentResponse (line 520) | type DeleteCommentResponse struct
type Comments (line 524) | type Comments struct
method Create (line 534) | func (s *Comments) Create(ctx context.Context, req *CreateCommentReque...
method List (line 566) | func (s *Comments) List(ctx context.Context, req *ListCommentsRequest,...
method Delete (line 585) | func (s *Comments) Delete(ctx context.Context, req *DeleteCommentReque...
type MailMessage (line 603) | type MailMessage struct
type SendMailRequest (line 613) | type SendMailRequest struct
type SendMailResponse (line 619) | type SendMailResponse struct
type ReadMailRequest (line 623) | type ReadMailRequest struct
type ReadMailResponse (line 626) | type ReadMailResponse struct
type Mail (line 630) | type Mail struct
method Send (line 640) | func (s *Mail) Send(ctx context.Context, req *SendMailRequest, rsp *Se...
method Read (line 668) | func (s *Mail) Read(ctx context.Context, req *ReadMailRequest, rsp *Re...
function main (line 689) | func main() {
function seedData (line 717) | func seedData(users *Users, posts *Posts) {
function printBanner (line 747) | func printBanner() {
function generateToken (line 770) | func generateToken() string {
FILE: examples/mcp/workflow/main.go
type Product (line 36) | type Product struct
type CheckStockRequest (line 44) | type CheckStockRequest struct
type CheckStockResponse (line 48) | type CheckStockResponse struct
type SearchProductsRequest (line 52) | type SearchProductsRequest struct
type SearchProductsResponse (line 57) | type SearchProductsResponse struct
type ReserveStockRequest (line 61) | type ReserveStockRequest struct
type ReserveStockResponse (line 66) | type ReserveStockResponse struct
type InventoryService (line 72) | type InventoryService struct
method CheckStock (line 81) | func (s *InventoryService) CheckStock(ctx context.Context, req *CheckS...
method Search (line 96) | func (s *InventoryService) Search(ctx context.Context, req *SearchProd...
method ReserveStock (line 115) | func (s *InventoryService) ReserveStock(ctx context.Context, req *Rese...
type Order (line 139) | type Order struct
type PlaceOrderRequest (line 149) | type PlaceOrderRequest struct
type PlaceOrderResponse (line 155) | type PlaceOrderResponse struct
type GetOrderRequest (line 159) | type GetOrderRequest struct
type GetOrderResponse (line 163) | type GetOrderResponse struct
type ListOrdersRequest (line 167) | type ListOrdersRequest struct
type ListOrdersResponse (line 172) | type ListOrdersResponse struct
type OrderService (line 176) | type OrderService struct
method PlaceOrder (line 188) | func (s *OrderService) PlaceOrder(ctx context.Context, req *PlaceOrder...
method GetOrder (line 227) | func (s *OrderService) GetOrder(ctx context.Context, req *GetOrderRequ...
method ListOrders (line 241) | func (s *OrderService) ListOrders(ctx context.Context, req *ListOrders...
type Notification (line 260) | type Notification struct
type SendNotificationRequest (line 269) | type SendNotificationRequest struct
type SendNotificationResponse (line 276) | type SendNotificationResponse struct
type ListNotificationsRequest (line 280) | type ListNotificationsRequest struct
type ListNotificationsResponse (line 284) | type ListNotificationsResponse struct
type NotificationService (line 288) | type NotificationService struct
method Send (line 299) | func (s *NotificationService) Send(ctx context.Context, req *SendNotif...
method List (line 333) | func (s *NotificationService) List(ctx context.Context, req *ListNotif...
function main (line 349) | func main() {
FILE: examples/multi-service/main.go
type UserRequest (line 18) | type UserRequest struct
type UserResponse (line 22) | type UserResponse struct
type Users (line 27) | type Users struct
method Lookup (line 29) | func (u *Users) Lookup(ctx context.Context, req *UserRequest, rsp *Use...
type OrderRequest (line 38) | type OrderRequest struct
type OrderResponse (line 42) | type OrderResponse struct
type Orders (line 47) | type Orders struct
method Create (line 49) | func (o *Orders) Create(ctx context.Context, req *OrderRequest, rsp *O...
function main (line 56) | func main() {
FILE: examples/web-service/main.go
type User (line 13) | type User struct
function main (line 25) | func main() {
function homeHandler (line 55) | func homeHandler(w http.ResponseWriter, r *http.Request) {
function usersHandler (line 64) | func usersHandler(w http.ResponseWriter, r *http.Request) {
function userHandler (line 76) | func userHandler(w http.ResponseWriter, r *http.Request) {
function healthHandler (line 94) | func healthHandler(w http.ResponseWriter, r *http.Request) {
FILE: gateway/api/gateway.go
type Options (line 20) | type Options struct
type Gateway (line 49) | type Gateway struct
method Wait (line 131) | func (g *Gateway) Wait() error {
method Stop (line 137) | func (g *Gateway) Stop() error {
method Addr (line 147) | func (g *Gateway) Addr() string {
method Mux (line 153) | func (g *Gateway) Mux() *http.ServeMux {
function New (line 58) | func New(opts Options) (*Gateway, error) {
function Run (line 122) | func Run(opts Options) error {
FILE: gateway/mcp/benchmark_test.go
function benchServer (line 18) | func benchServer(n int, opts Options) *Server {
function toolName (line 61) | func toolName(i int) string {
function BenchmarkListTools (line 69) | func BenchmarkListTools(b *testing.B) {
function BenchmarkListToolsParallel (line 89) | func BenchmarkListToolsParallel(b *testing.B) {
function BenchmarkToolLookup (line 104) | func BenchmarkToolLookup(b *testing.B) {
function BenchmarkAuthInspect (line 125) | func BenchmarkAuthInspect(b *testing.B) {
function BenchmarkScopeCheck (line 146) | func BenchmarkScopeCheck(b *testing.B) {
function BenchmarkAuditRecord (line 158) | func BenchmarkAuditRecord(b *testing.B) {
function BenchmarkRateLimiter (line 179) | func BenchmarkRateLimiter(b *testing.B) {
function BenchmarkJSONEncodeTool (line 203) | func BenchmarkJSONEncodeTool(b *testing.B) {
function BenchmarkJSONDecodeCallRequest (line 231) | func BenchmarkJSONDecodeCallRequest(b *testing.B) {
function toolCountLabel (line 247) | func toolCountLabel(n int) string {
FILE: gateway/mcp/circuitbreaker.go
type CircuitBreakerConfig (line 12) | type CircuitBreakerConfig struct
type circuitState (line 28) | type circuitState
method String (line 36) | func (s circuitState) String() string {
constant circuitClosed (line 31) | circuitClosed circuitState = iota
constant circuitOpen (line 32) | circuitOpen
constant circuitHalfOpen (line 33) | circuitHalfOpen
type circuitBreaker (line 50) | type circuitBreaker struct
method Allow (line 84) | func (cb *circuitBreaker) Allow() error {
method RecordSuccess (line 109) | func (cb *circuitBreaker) RecordSuccess() {
method RecordFailure (line 118) | func (cb *circuitBreaker) RecordFailure() {
method State (line 137) | func (cb *circuitBreaker) State() circuitState {
function newCircuitBreaker (line 61) | func newCircuitBreaker(cfg CircuitBreakerConfig) *circuitBreaker {
FILE: gateway/mcp/circuitbreaker_test.go
function TestCircuitBreaker_ClosedAllowsRequests (line 8) | func TestCircuitBreaker_ClosedAllowsRequests(t *testing.T) {
function TestCircuitBreaker_OpensAfterMaxFailures (line 18) | func TestCircuitBreaker_OpensAfterMaxFailures(t *testing.T) {
function TestCircuitBreaker_SuccessResetsFailures (line 40) | func TestCircuitBreaker_SuccessResetsFailures(t *testing.T) {
function TestCircuitBreaker_HalfOpenAfterTimeout (line 55) | func TestCircuitBreaker_HalfOpenAfterTimeout(t *testing.T) {
function TestCircuitBreaker_HalfOpenSuccessCloses (line 85) | func TestCircuitBreaker_HalfOpenSuccessCloses(t *testing.T) {
function TestCircuitBreaker_HalfOpenFailureReopens (line 106) | func TestCircuitBreaker_HalfOpenFailureReopens(t *testing.T) {
function TestCircuitBreaker_Defaults (line 125) | func TestCircuitBreaker_Defaults(t *testing.T) {
function TestCircuitBreaker_StateString (line 139) | func TestCircuitBreaker_StateString(t *testing.T) {
FILE: gateway/mcp/example_test.go
function Example_withMCP (line 15) | func Example_withMCP() {
function Example_inlineGateway (line 27) | func Example_inlineGateway() {
function Example_standaloneGateway (line 46) | func Example_standaloneGateway() {
function Example_withAuthentication (line 57) | func Example_withAuthentication() {
function Example_customContext (line 82) | func Example_customContext() {
function Example_withScopesAndTracing (line 106) | func Example_withScopesAndTracing() {
FILE: gateway/mcp/mcp.go
constant TraceIDKey (line 42) | TraceIDKey = "Mcp-Trace-Id"
constant ToolNameKey (line 44) | ToolNameKey = "Mcp-Tool-Name"
constant AccountIDKey (line 46) | AccountIDKey = "Mcp-Account-Id"
type AuditRecord (line 50) | type AuditRecord struct
type AuditFunc (line 74) | type AuditFunc
type RateLimitConfig (line 77) | type RateLimitConfig struct
type Options (line 85) | type Options struct
type Server (line 155) | type Server struct
method discoverServices (line 230) | func (s *Server) discoverServices() error {
method buildInputSchema (line 320) | func (s *Server) buildInputSchema(value *registry.Value) map[string]in...
method mapGoTypeToJSON (line 342) | func (s *Server) mapGoTypeToJSON(goType string) string {
method watchServices (line 358) | func (s *Server) watchServices() {
method serveHTTP (line 391) | func (s *Server) serveHTTP() error {
method serveStdio (line 413) | func (s *Server) serveStdio() error {
method handleListTools (line 419) | func (s *Server) handleListTools(w http.ResponseWriter, r *http.Reques...
method handleCallTool (line 441) | func (s *Server) handleCallTool(w http.ResponseWriter, r *http.Request) {
method handleHealth (line 618) | func (s *Server) handleHealth(w http.ResponseWriter, r *http.Request) {
method Stop (line 631) | func (s *Server) Stop() error {
method GetTools (line 641) | func (s *Server) GetTools() []*Tool {
method audit (line 653) | func (s *Server) audit(record AuditRecord) {
method allowRate (line 661) | func (s *Server) allowRate(toolName string) error {
method allowCircuit (line 679) | func (s *Server) allowCircuit(toolName string) error {
method recordCircuit (line 693) | func (s *Server) recordCircuit(toolName string, success bool) {
type Tool (line 172) | type Tool struct
function Serve (line 186) | func Serve(opts Options) error {
function ListenAndServe (line 224) | func ListenAndServe(address string, opts Options) error {
function hasScope (line 711) | func hasScope(accountScopes, requiredScopes []string) bool {
function Example (line 723) | func Example() {
FILE: gateway/mcp/mcp_test.go
type mockAuth (line 20) | type mockAuth struct
method Init (line 24) | func (m *mockAuth) Init(...auth.Option) {}
method Options (line 25) | func (m *mockAuth) Options() auth.Options { return auth.Options{} }
method Generate (line 26) | func (m *mockAuth) Generate(string, ...auth.GenerateOption) (*auth.Acc...
method Token (line 29) | func (m *mockAuth) Token(...auth.TokenOption) (*auth.Token, error) { r...
method String (line 30) | func (m *mockAuth) String() string { r...
method Inspect (line 32) | func (m *mockAuth) Inspect(token string) (*auth.Account, error) {
function newTestServer (line 41) | func newTestServer(opts Options) *Server {
function testLogger (line 60) | func testLogger() *log.Logger {
type nopWriter (line 64) | type nopWriter struct
method Write (line 66) | func (nopWriter) Write(p []byte) (int, error) { return len(p), nil }
function TestHasScope (line 70) | func TestHasScope(t *testing.T) {
function TestToolScopesFromMetadata (line 95) | func TestToolScopesFromMetadata(t *testing.T) {
function TestHandleCallTool_AuthRequired (line 147) | func TestHandleCallTool_AuthRequired(t *testing.T) {
function TestHandleCallTool_TraceID (line 194) | func TestHandleCallTool_TraceID(t *testing.T) {
function TestHandleCallTool_AuditFunc (line 220) | func TestHandleCallTool_AuditFunc(t *testing.T) {
function TestHandleCallTool_AuditDenied (line 274) | func TestHandleCallTool_AuditDenied(t *testing.T) {
function TestRateLimiter (line 326) | func TestRateLimiter(t *testing.T) {
function TestHandleCallTool_RateLimit (line 351) | func TestHandleCallTool_RateLimit(t *testing.T) {
function TestHandleCallTool_NoAuth_NoScope (line 408) | func TestHandleCallTool_NoAuth_NoScope(t *testing.T) {
function TestToolScopesInJSON (line 431) | func TestToolScopesInJSON(t *testing.T) {
function TestToolNoScopesOmittedInJSON (line 458) | func TestToolNoScopesOmittedInJSON(t *testing.T) {
function TestDiscoverServices_RateLimiters (line 480) | func TestDiscoverServices_RateLimiters(t *testing.T) {
function TestScopesFromGatewayOptions (line 515) | func TestScopesFromGatewayOptions(t *testing.T) {
FILE: gateway/mcp/option.go
function WithMCP (line 18) | func WithMCP(address string) service.Option {
FILE: gateway/mcp/otel.go
constant instrumentationName (line 14) | instrumentationName = "go-micro.dev/v5/gateway/mcp"
constant spanNameToolCall (line 18) | spanNameToolCall = "mcp.tool.call"
constant AttrToolName (line 21) | AttrToolName = "mcp.tool.name"
constant AttrTransport (line 23) | AttrTransport = "mcp.transport"
constant AttrAccountID (line 25) | AttrAccountID = "mcp.account.id"
constant AttrTraceID (line 27) | AttrTraceID = "mcp.trace_id"
constant AttrAuthAllowed (line 29) | AttrAuthAllowed = "mcp.auth.allowed"
constant AttrAuthDeniedReason (line 31) | AttrAuthDeniedReason = "mcp.auth.denied_reason"
constant AttrScopesRequired (line 33) | AttrScopesRequired = "mcp.auth.scopes_required"
constant AttrRateLimited (line 35) | AttrRateLimited = "mcp.rate_limited"
method tracer (line 40) | func (s *Server) tracer() trace.Tracer {
method startToolSpan (line 50) | func (s *Server) startToolSpan(ctx context.Context, toolName, transport,...
function setSpanOK (line 87) | func setSpanOK(span trace.Span) {
function setSpanError (line 92) | func setSpanError(span trace.Span, err error) {
type metadataCarrier (line 98) | type metadataCarrier
method Get (line 100) | func (c metadataCarrier) Get(key string) string {
method Set (line 105) | func (c metadataCarrier) Set(key, value string) {
method Keys (line 109) | func (c metadataCarrier) Keys() []string {
FILE: gateway/mcp/otel_test.go
function newTestTP (line 20) | func newTestTP() (*tracetest.InMemoryExporter, trace.TracerProvider) {
function TestOTel_SpanCreated (line 26) | func TestOTel_SpanCreated(t *testing.T) {
function TestOTel_SpanAttributes_AuthDenied (line 63) | func TestOTel_SpanAttributes_AuthDenied(t *testing.T) {
function TestOTel_SpanAttributes_AuthAllowed (line 108) | func TestOTel_SpanAttributes_AuthAllowed(t *testing.T) {
function TestOTel_SpanAttributes_RateLimit (line 150) | func TestOTel_SpanAttributes_RateLimit(t *testing.T) {
function TestOTel_NoProvider_NoSpan (line 200) | func TestOTel_NoProvider_NoSpan(t *testing.T) {
function TestOTel_TraceContextPropagation (line 224) | func TestOTel_TraceContextPropagation(t *testing.T) {
function TestOTel_MissingToken (line 257) | func TestOTel_MissingToken(t *testing.T) {
function TestOTel_StartToolSpan_NilProvider (line 294) | func TestOTel_StartToolSpan_NilProvider(t *testing.T) {
function assertAttr (line 310) | func assertAttr(t *testing.T, attrs []attribute.KeyValue, key, want stri...
function assertAttrBool (line 323) | func assertAttrBool(t *testing.T, attrs []attribute.KeyValue, key string...
FILE: gateway/mcp/parser.go
type ToolDescription (line 18) | type ToolDescription struct
type ParamDoc (line 27) | type ParamDoc struct
type ReturnDoc (line 35) | type ReturnDoc struct
function parseServiceDocs (line 49) | func parseServiceDocs(serviceName string, endpoint *registry.Endpoint) *...
function parseEndpointParams (line 69) | func parseEndpointParams(value *registry.Value) []ParamDoc {
function parseEndpointReturns (line 88) | func parseEndpointReturns(value *registry.Value) []ReturnDoc {
function formatFieldDescription (line 100) | func formatFieldDescription(name, typeName string) string {
function toReadable (line 107) | func toReadable(s string) string {
function ParseGoDocComment (line 120) | func ParseGoDocComment(comment string) *ToolDescription {
function enhanceToolDescription (line 178) | func enhanceToolDescription(tool *Tool, serviceName string, endpoint *re...
function ParseStructTags (line 223) | func ParseStructTags(t reflect.Type) map[string]interface{} {
function reflectTypeToJSONType (line 275) | func reflectTypeToJSONType(t reflect.Type) string {
function findServiceSource (line 297) | func findServiceSource(serviceName string) ([]string, error) {
function parseGoFile (line 307) | func parseGoFile(filename string, serviceName string) (map[string]*ToolD...
FILE: gateway/mcp/ratelimit.go
type rateLimiter (line 9) | type rateLimiter struct
method Allow (line 32) | func (r *rateLimiter) Allow() bool {
function newRateLimiter (line 19) | func newRateLimiter(rate float64, burst int) *rateLimiter {
FILE: gateway/mcp/stdio.go
type StdioTransport (line 24) | type StdioTransport struct
method Serve (line 78) | func (t *StdioTransport) Serve() error {
method handleRequest (line 117) | func (t *StdioTransport) handleRequest(req *JSONRPCRequest) {
method handleInitialize (line 131) | func (t *StdioTransport) handleInitialize(req *JSONRPCRequest) {
method handleToolsList (line 147) | func (t *StdioTransport) handleToolsList(req *JSONRPCRequest) {
method handleToolsCall (line 167) | func (t *StdioTransport) handleToolsCall(req *JSONRPCRequest) {
method sendResponse (line 337) | func (t *StdioTransport) sendResponse(id interface{}, result interface...
method sendError (line 348) | func (t *StdioTransport) sendError(id interface{}, code int, message s...
method writeJSON (line 363) | func (t *StdioTransport) writeJSON(v interface{}) {
method Stop (line 389) | func (t *StdioTransport) Stop() error {
type JSONRPCRequest (line 34) | type JSONRPCRequest struct
type JSONRPCResponse (line 42) | type JSONRPCResponse struct
type RPCError (line 50) | type RPCError struct
constant ParseError (line 58) | ParseError = -32700
constant InvalidRequest (line 59) | InvalidRequest = -32600
constant MethodNotFound (line 60) | MethodNotFound = -32601
constant InvalidParams (line 61) | InvalidParams = -32602
constant InternalError (line 62) | InternalError = -32603
function NewStdioTransport (line 66) | func NewStdioTransport(server *Server) *StdioTransport {
FILE: gateway/mcp/websocket.go
type WebSocketTransport (line 25) | type WebSocketTransport struct
method ServeHTTP (line 43) | func (t *WebSocketTransport) ServeHTTP(w http.ResponseWriter, r *http....
type wsConn (line 30) | type wsConn struct
method readLoop (line 78) | func (wc *wsConn) readLoop() {
method handleRequest (line 106) | func (wc *wsConn) handleRequest(req *JSONRPCRequest) {
method handleInitialize (line 120) | func (wc *wsConn) handleInitialize(req *JSONRPCRequest) {
method handleToolsList (line 135) | func (wc *wsConn) handleToolsList(req *JSONRPCRequest) {
method handleToolsCall (line 153) | func (wc *wsConn) handleToolsCall(req *JSONRPCRequest) {
method sendResponse (line 318) | func (wc *wsConn) sendResponse(id interface{}, result interface{}) {
method sendError (line 327) | func (wc *wsConn) sendError(id interface{}, code int, message string, ...
method writeJSON (line 340) | func (wc *wsConn) writeJSON(v interface{}) {
function NewWebSocketTransport (line 38) | func NewWebSocketTransport(server *Server) *WebSocketTransport {
FILE: gateway/mcp/websocket_test.go
function wsDialer (line 18) | func wsDialer(t *testing.T, url string, headers http.Header) *websocket....
function sendJSONRPC (line 30) | func sendJSONRPC(t *testing.T, conn *websocket.Conn, method string, id i...
function newWSTestServer (line 50) | func newWSTestServer(t *testing.T, opts Options) (*Server, *httptest.Ser...
function TestWebSocket_Initialize (line 62) | func TestWebSocket_Initialize(t *testing.T) {
function TestWebSocket_ToolsList (line 80) | func TestWebSocket_ToolsList(t *testing.T) {
function TestWebSocket_ToolsCall_NoAuth (line 103) | func TestWebSocket_ToolsCall_NoAuth(t *testing.T) {
function TestWebSocket_ToolsCall_AuthRequired (line 126) | func TestWebSocket_ToolsCall_AuthRequired(t *testing.T) {
function TestWebSocket_ToolsCall_InsufficientScopes (line 198) | func TestWebSocket_ToolsCall_InsufficientScopes(t *testing.T) {
function TestWebSocket_ToolsCall_Audit (line 224) | func TestWebSocket_ToolsCall_Audit(t *testing.T) {
function TestWebSocket_RateLimit (line 262) | func TestWebSocket_RateLimit(t *testing.T) {
function TestWebSocket_MethodNotFound (line 293) | func TestWebSocket_MethodNotFound(t *testing.T) {
function TestWebSocket_ToolNotFound (line 303) | func TestWebSocket_ToolNotFound(t *testing.T) {
function TestWebSocket_MultipleConcurrentRequests (line 316) | func TestWebSocket_MultipleConcurrentRequests(t *testing.T) {
function TestWebSocket_MultipleConnections (line 360) | func TestWebSocket_MultipleConnections(t *testing.T) {
function TestWebSocket_InvalidJSON (line 386) | func TestWebSocket_InvalidJSON(t *testing.T) {
function TestWebSocket_InvalidJSONRPCVersion (line 408) | func TestWebSocket_InvalidJSONRPCVersion(t *testing.T) {
function TestWebSocket_ConnectionPersistence (line 426) | func TestWebSocket_ConnectionPersistence(t *testing.T) {
FILE: health/health.go
type Status (line 35) | type Status
constant StatusUp (line 38) | StatusUp Status = "up"
constant StatusDown (line 39) | StatusDown Status = "down"
type CheckFunc (line 44) | type CheckFunc
type Check (line 47) | type Check struct
type Result (line 55) | type Result struct
type Response (line 63) | type Response struct
function Register (line 77) | func Register(name string, check CheckFunc) {
function RegisterCheck (line 87) | func RegisterCheck(check Check) {
function SetInfo (line 97) | func SetInfo(key, value string) {
function Reset (line 104) | func Reset() {
function Run (line 112) | func Run(ctx context.Context) Response {
function runCheck (line 164) | func runCheck(ctx context.Context, check Check) Result {
function IsReady (line 187) | func IsReady(ctx context.Context) bool {
function IsLive (line 194) | func IsLive() bool {
function Handler (line 200) | func Handler() http.Handler {
function LiveHandler (line 209) | func LiveHandler() http.Handler {
function ReadyHandler (line 223) | func ReadyHandler() http.Handler {
function writeResponse (line 230) | func writeResponse(w http.ResponseWriter, resp Response) {
function RegisterHandlers (line 241) | func RegisterHandlers(mux *http.ServeMux) {
function PingCheck (line 250) | func PingCheck(ping func() error) CheckFunc {
function PingContextCheck (line 257) | func PingContextCheck(ping func(context.Context) error) CheckFunc {
function TCPCheck (line 262) | func TCPCheck(addr string, timeout time.Duration) CheckFunc {
function HTTPCheck (line 274) | func HTTPCheck(url string, timeout time.Duration) CheckFunc {
function DNSCheck (line 294) | func DNSCheck(host string) CheckFunc {
function CustomCheck (line 305) | func CustomCheck(fn func() error) CheckFunc {
FILE: health/health_test.go
function TestRegisterAndRun (line 14) | func TestRegisterAndRun(t *testing.T) {
function TestFailingCheck (line 35) | func TestFailingCheck(t *testing.T) {
function TestNonCriticalCheck (line 52) | func TestNonCriticalCheck(t *testing.T) {
function TestCheckTimeout (line 76) | func TestCheckTimeout(t *testing.T) {
function TestHealthHandler (line 103) | func TestHealthHandler(t *testing.T) {
function TestHealthHandlerUnhealthy (line 128) | func TestHealthHandlerUnhealthy(t *testing.T) {
function TestLiveHandler (line 145) | func TestLiveHandler(t *testing.T) {
function TestReadyHandler (line 158) | func TestReadyHandler(t *testing.T) {
function TestSetInfo (line 175) | func TestSetInfo(t *testing.T) {
function TestPingCheck (line 195) | func TestPingCheck(t *testing.T) {
function TestTCPCheck (line 211) | func TestTCPCheck(t *testing.T) {
function TestTCPCheckFailing (line 230) | func TestTCPCheckFailing(t *testing.T) {
function TestHTTPCheck (line 243) | func TestHTTPCheck(t *testing.T) {
function TestHTTPCheckFailing (line 260) | func TestHTTPCheckFailing(t *testing.T) {
function TestDNSCheck (line 277) | func TestDNSCheck(t *testing.T) {
function TestMultipleChecks (line 289) | func TestMultipleChecks(t *testing.T) {
function TestRegisterHandlers (line 306)
Condensed preview — 676 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (3,034K chars).
[
{
"path": ".editorconfig",
"chars": 427,
"preview": "# EditorConfig for go-micro\n# https://editorconfig.org\n\nroot = true\n\n[*]\ncharset = utf-8\nend_of_line = lf\ninsert_final_n"
},
{
"path": ".github/FUNDING.yml",
"chars": 13,
"preview": "github: asim\n"
},
{
"path": ".github/ISSUE_TEMPLATE/bug_report.md",
"chars": 1353,
"preview": "---\nname: Bug report\nabout: Create a report to help us improve\ntitle: '[BUG] '\nlabels: bug\nassignees: ''\n---\n\n## Describ"
},
{
"path": ".github/ISSUE_TEMPLATE/feature_request.md",
"chars": 1451,
"preview": "---\nname: Feature request\nabout: Suggest an idea for this project\ntitle: '[FEATURE] '\nlabels: enhancement\nassignees: ''\n"
},
{
"path": ".github/ISSUE_TEMPLATE/performance.md",
"chars": 1265,
"preview": "---\nname: Performance issue\nabout: Report a performance problem or regression\ntitle: '[PERFORMANCE] '\nlabels: performanc"
},
{
"path": ".github/ISSUE_TEMPLATE/question.md",
"chars": 945,
"preview": "---\nname: Question\nabout: Ask a question about using Go Micro\ntitle: '[QUESTION] '\nlabels: question\nassignees: ''\n---\n\n#"
},
{
"path": ".github/workflows/release.yml",
"chars": 1191,
"preview": "name: goreleaser\n\non:\n push:\n tags:\n - 'v*.*.*'\n\npermissions:\n contents: write\n id-token: write\n packages: w"
},
{
"path": ".github/workflows/tests.yaml",
"chars": 1877,
"preview": "name: Run Tests\non:\n push:\n branches:\n - \"**\"\n pull_request:\n types:\n - opened\n - reopened\n br"
},
{
"path": ".github/workflows/website.yml",
"chars": 1427,
"preview": "# Sample workflow for building and deploying a Jekyll site to GitHub Pages\nname: Deploy Jekyll with GitHub Pages depende"
},
{
"path": ".gitignore",
"chars": 787,
"preview": "# Develop tools\n/.idea/\n/.trunk\n\n# VS Code workspace files (keep settings for consistency)\n/.vscode/*\n!/.vscode/settings"
},
{
"path": ".golangci.yaml",
"chars": 8270,
"preview": "# This file contains all available configuration options\n# with their default values.\n\n# options for analysis running\nru"
},
{
"path": ".goreleaser.yaml",
"chars": 3181,
"preview": "# yaml-language-server: $schema=https://goreleaser.com/static/schema.json\n# vim: set ts=2 sw=2 tw=0 fo=cnqoj\n\nversion: 2"
},
{
"path": ".vscode/settings.json",
"chars": 3115,
"preview": "{\n \"folders\": [\n {\n \"path\": \".\"\n }\n ],\n \"settings\": {\n \"go.toolsManagement.autoUpdate\": true,\n \"go.u"
},
{
"path": "CHANGELOG.md",
"chars": 6805,
"preview": "# Changelog\n\nAll notable changes to Go Micro are documented here.\n\nFormat follows [Keep a Changelog](https://keepachange"
},
{
"path": "CLAUDE.md",
"chars": 5898,
"preview": "# CLAUDE.md - Go Micro Project Guide\n\n## Project Overview\n\nGo Micro is a framework for distributed systems development i"
},
{
"path": "CONTRIBUTING.md",
"chars": 4812,
"preview": "# Contributing to Go Micro\n\nThank you for your interest in contributing to Go Micro! This document provides guidelines a"
},
{
"path": "Dockerfile",
"chars": 617,
"preview": "FROM alpine:latest\nARG TARGETPLATFORM\nENV USER=micro\nENV GROUPNAME=$USER\nARG UID=1001\nARG GID=1001\nRUN addgroup --gid \"$"
},
{
"path": "LICENSE",
"chars": 11357,
"preview": " Apache License\n Version 2.0, January 2004\n "
},
{
"path": "Makefile",
"chars": 2477,
"preview": "NAME = micro\nGIT_COMMIT = $(shell git rev-parse --short HEAD)\nGIT_TAG = $(shell git describe --abbrev=0 --tags --always "
},
{
"path": "README.md",
"chars": 13857,
"preview": "# Go Micro [\n\nfunc TestProvider_String(t *testing.T) {\n\tp "
},
{
"path": "ai/model.go",
"chars": 3747,
"preview": "// Package ai provides abstraction for AI model providers\npackage ai\n\nimport (\n\t\"context\"\n\t\"strings\"\n)\n\n// Model provide"
},
{
"path": "ai/openai/openai.go",
"chars": 5559,
"preview": "// Package openai implements the OpenAI model provider\npackage openai\n\nimport (\n\t\"bytes\"\n\t\"context\"\n\t\"encoding/json\"\n\t\"f"
},
{
"path": "ai/openai/openai_test.go",
"chars": 2034,
"preview": "package openai\n\nimport (\n\t\"context\"\n\t\"testing\"\n\n\t\"go-micro.dev/v5/ai\"\n)\n\nfunc TestProvider_String(t *testing.T) {\n\tp := "
},
{
"path": "ai/options.go",
"chars": 1577,
"preview": "package ai\n\nimport (\n\t\"context\"\n)\n\n// Options for model configuration\ntype Options struct {\n\t// Context for the model\n\tC"
},
{
"path": "auth/ANALYSIS.md",
"chars": 9010,
"preview": "# Auth Package Analysis\n\n## Current Status: ✅ Fully Functional\n\nThe auth package is now **production-ready** with comple"
},
{
"path": "auth/auth.go",
"chars": 4175,
"preview": "// Package auth provides authentication and authorization capability\npackage auth\n\nimport (\n\t\"context\"\n\t\"errors\"\n\t\"time\""
},
{
"path": "auth/jwt/jwt.go",
"chars": 2996,
"preview": "package jwt\n\nimport (\n\t\"sync\"\n\t\"time\"\n\n\tjwtToken \"github.com/micro/plugins/v5/auth/jwt/token\"\n\t\"go-micro.dev/v5/auth\"\n\t\""
},
{
"path": "auth/jwt/token/jwt.go",
"chars": 2253,
"preview": "package token\n\nimport (\n\t\"encoding/base64\"\n\t\"time\"\n\n\t\"github.com/dgrijalva/jwt-go\"\n\t\"go-micro.dev/v5/auth\"\n)\n\n// authCla"
},
{
"path": "auth/jwt/token/jwt_test.go",
"chars": 2123,
"preview": "package token\n\nimport (\n\t\"os\"\n\t\"testing\"\n\t\"time\"\n\n\t\"go-micro.dev/v5/auth\"\n)\n\nfunc TestGenerate(t *testing.T) {\n\tprivKey,"
},
{
"path": "auth/jwt/token/options.go",
"chars": 1497,
"preview": "package token\n\nimport (\n\t\"time\"\n\n\t\"go-micro.dev/v5/store\"\n)\n\ntype Options struct {\n\t// Store to persist the tokens\n\tStor"
},
{
"path": "auth/jwt/token/test/sample_key",
"chars": 4332,
"preview": "LS0tLS1CRUdJTiBSU0EgUFJJVkFURSBLRVktLS0tLQpNSUlKS3dJQkFBS0NBZ0VBOFNiSlA1WGJFaWRSbTViMnNOcExHbzJlV2ZVNU9KZTBpemdySHdEOEg3"
},
{
"path": "auth/jwt/token/test/sample_key 2",
"chars": 4332,
"preview": "LS0tLS1CRUdJTiBSU0EgUFJJVkFURSBLRVktLS0tLQpNSUlKS3dJQkFBS0NBZ0VBOFNiSlA1WGJFaWRSbTViMnNOcExHbzJlV2ZVNU9KZTBpemdySHdEOEg3"
},
{
"path": "auth/jwt/token/test/sample_key.pub",
"chars": 1068,
"preview": "LS0tLS1CRUdJTiBQVUJMSUMgS0VZLS0tLS0KTUlJQ0lqQU5CZ2txaGtpRzl3MEJBUUVGQUFPQ0FnOEFNSUlDQ2dLQ0FnRUE4U2JKUDVYYkVpZFJtNWIyc05w"
},
{
"path": "auth/jwt/token/token.go",
"chars": 856,
"preview": "package token\n\nimport (\n\t\"errors\"\n\t\"time\"\n\n\t\"go-micro.dev/v5/auth\"\n)\n\nvar (\n\t// ErrNotFound is returned when a token can"
},
{
"path": "auth/noop/noop.go",
"chars": 1290,
"preview": "// Package noop provides a no-op auth implementation for testing and development.\n//\n// The noop auth provider:\n// - Acc"
},
{
"path": "auth/noop.go",
"chars": 1682,
"preview": "package auth\n\nimport (\n\t\"github.com/google/uuid\"\n)\n\nvar (\n\tDefaultAuth = NewAuth()\n)\n\nfunc NewAuth(opts ...Option) Auth "
},
{
"path": "auth/options.go",
"chars": 4295,
"preview": "package auth\n\nimport (\n\t\"context\"\n\t\"time\"\n\n\t\"go-micro.dev/v5/logger\"\n)\n\nfunc NewOptions(opts ...Option) Options {\n\toptio"
},
{
"path": "auth/rules.go",
"chars": 2871,
"preview": "package auth\n\nimport (\n\t\"fmt\"\n\t\"sort\"\n\t\"strings\"\n)\n\n// Verify an account has access to a resource using the rules provid"
},
{
"path": "auth/rules_test.go",
"chars": 5228,
"preview": "package auth\n\nimport (\n\t\"testing\"\n)\n\nfunc TestVerify(t *testing.T) {\n\tsrvResource := &Resource{\n\t\tType: \"service\",\n\t"
},
{
"path": "broker/broker.go",
"chars": 1762,
"preview": "// Package broker is an interface used for asynchronous messaging\npackage broker\n\n// Broker is an interface used for asy"
},
{
"path": "broker/http.go",
"chars": 13167,
"preview": "package broker\n\nimport (\n\t\"bytes\"\n\t\"crypto/tls\"\n\t\"errors\"\n\t\"fmt\"\n\t\"io\"\n\t\"math/rand\"\n\t\"net\"\n\t\"net/http\"\n\t\"net/url\"\n\t\"runt"
},
{
"path": "broker/http_test.go",
"chars": 7406,
"preview": "package broker_test\n\nimport (\n\t\"sync\"\n\t\"testing\"\n\t\"time\"\n\n\t\"github.com/google/uuid\"\n\t\"go-micro.dev/v5/broker\"\n\t\"go-micro"
},
{
"path": "broker/memory.go",
"chars": 3793,
"preview": "// Package memory provides a memory broker\npackage broker\n\nimport (\n\t\"errors\"\n\t\"math/rand\"\n\t\"sync\"\n\n\t\"github.com/google/"
},
{
"path": "broker/memory_test.go",
"chars": 929,
"preview": "package broker_test\n\nimport (\n\t\"fmt\"\n\t\"testing\"\n\n\t\"go-micro.dev/v5/broker\"\n)\n\nfunc TestMemoryBroker(t *testing.T) {\n\tb :"
},
{
"path": "broker/nats/context.go",
"chars": 346,
"preview": "package nats\n\nimport (\n\t\"context\"\n\n\t\"go-micro.dev/v5/broker\"\n)\n\n// setBrokerOption returns a function to setup a context"
},
{
"path": "broker/nats/nats.go",
"chars": 8528,
"preview": "// Package nats provides a NATS broker\npackage nats\n\nimport (\n\t\"context\"\n\t\"errors\"\n\t\"strings\"\n\t\"sync\"\n\t\"time\"\n\n\tnatsp \"g"
},
{
"path": "broker/nats/nats_test.go",
"chars": 2561,
"preview": "package nats\n\nimport (\n\t\"fmt\"\n\t\"testing\"\n\n\tnatsp \"github.com/nats-io/nats.go\"\n\t\"go-micro.dev/v5/broker\"\n)\n\nvar addrTestC"
},
{
"path": "broker/nats/options.go",
"chars": 1042,
"preview": "package nats\n\nimport (\n\t\"time\"\n\n\tnatsp \"github.com/nats-io/nats.go\"\n\t\"go-micro.dev/v5/broker\"\n)\n\ntype optionsKey struct{"
},
{
"path": "broker/nats/pool.go",
"chars": 3979,
"preview": "package nats\n\nimport (\n\t\"errors\"\n\t\"sync\"\n\t\"time\"\n\n\tnatsp \"github.com/nats-io/nats.go\"\n)\n\nvar (\n\t// ErrPoolExhausted is r"
},
{
"path": "broker/nats/pool_test.go",
"chars": 4655,
"preview": "package nats\n\nimport (\n\t\"sync\"\n\t\"testing\"\n\t\"time\"\n\n\tnatsp \"github.com/nats-io/nats.go\"\n)\n\nfunc TestConnectionPool_GetPut"
},
{
"path": "broker/options.go",
"chars": 3223,
"preview": "package broker\n\nimport (\n\t\"context\"\n\t\"crypto/tls\"\n\n\t\"go-micro.dev/v5/codec\"\n\t\"go-micro.dev/v5/logger\"\n\t\"go-micro.dev/v5/"
},
{
"path": "broker/rabbitmq/auth.go",
"chars": 206,
"preview": "package rabbitmq\n\ntype ExternalAuthentication struct {\n}\n\nfunc (auth *ExternalAuthentication) Mechanism() string {\n\tretu"
},
{
"path": "broker/rabbitmq/channel.go",
"chars": 3864,
"preview": "package rabbitmq\n\n//\n// All credit to Mondo\n//\n\nimport (\n\t\"errors\"\n\t\"sync\"\n\n\t\"github.com/google/uuid\"\n\tamqp \"github.com/"
},
{
"path": "broker/rabbitmq/connection.go",
"chars": 7053,
"preview": "package rabbitmq\n\n//\n// All credit to Mondo\n//\n\nimport (\n\t\"regexp\"\n\t\"strings\"\n\t\"sync\"\n\t\"time\"\n\n\tamqp \"github.com/rabbitm"
},
{
"path": "broker/rabbitmq/connection_test.go",
"chars": 3439,
"preview": "package rabbitmq\n\nimport (\n\t\"crypto/tls\"\n\t\"errors\"\n\t\"testing\"\n\n\tamqp \"github.com/rabbitmq/amqp091-go\"\n\t\"go-micro.dev/v5/"
},
{
"path": "broker/rabbitmq/context.go",
"chars": 1295,
"preview": "package rabbitmq\n\nimport (\n\t\"context\"\n\n\t\"go-micro.dev/v5/broker\"\n\t\"go-micro.dev/v5/server\"\n)\n\n// setSubscribeOption retu"
},
{
"path": "broker/rabbitmq/options.go",
"chars": 5764,
"preview": "package rabbitmq\n\nimport (\n\t\"context\"\n\t\"time\"\n\n\t\"go-micro.dev/v5/broker\"\n\t\"go-micro.dev/v5/client\"\n\t\"go-micro.dev/v5/ser"
},
{
"path": "broker/rabbitmq/rabbitmq.go",
"chars": 9133,
"preview": "// Package rabbitmq provides a RabbitMQ broker\npackage rabbitmq\n\nimport (\n\t\"context\"\n\t\"errors\"\n\t\"fmt\"\n\t\"net/url\"\n\t\"sync\""
},
{
"path": "broker/rabbitmq/rabbitmq_test.go",
"chars": 6435,
"preview": "package rabbitmq_test\n\nimport (\n\t\"context\"\n\t\"encoding/json\"\n\t\"os\"\n\t\"testing\"\n\t\"time\"\n\n\t\"go-micro.dev/v5/logger\"\n\n\tmicro "
},
{
"path": "cache/cache.go",
"chars": 1581,
"preview": "package cache\n\nimport (\n\t\"context\"\n\t\"errors\"\n\t\"time\"\n)\n\nvar (\n\t// DefaultCache is the default cache.\n\tDefaultCache Cache"
},
{
"path": "cache/memory.go",
"chars": 1093,
"preview": "package cache\n\nimport (\n\t\"context\"\n\t\"sync\"\n\t\"time\"\n)\n\ntype memCache struct {\n\topts Options\n\n\titems map[string]Item\n\tsync"
},
{
"path": "cache/memory_test.go",
"chars": 2480,
"preview": "package cache\n\nimport (\n\t\"context\"\n\t\"testing\"\n\t\"time\"\n)\n\nvar (\n\tctx = context.TODO()\n\tkey string = \"tes"
},
{
"path": "cache/options.go",
"chars": 1588,
"preview": "package cache\n\nimport (\n\t\"context\"\n\t\"time\"\n\n\t\"go-micro.dev/v5/logger\"\n)\n\n// Options represents the options for the cache"
},
{
"path": "cache/options_test.go",
"chars": 883,
"preview": "package cache\n\nimport (\n\t\"testing\"\n\t\"time\"\n)\n\nfunc TestOptions(t *testing.T) {\n\ttestData := map[string]struct {\n\t\tset "
},
{
"path": "cache/redis/options.go",
"chars": 1096,
"preview": "package redis\n\nimport (\n\t\"context\"\n\n\trclient \"github.com/go-redis/redis/v8\"\n\t\"go-micro.dev/v5/cache\"\n)\n\ntype redisOption"
},
{
"path": "cache/redis/options_test.go",
"chars": 3984,
"preview": "package redis\n\nimport (\n\t\"context\"\n\t\"reflect\"\n\t\"testing\"\n\n\trclient \"github.com/go-redis/redis/v8\"\n\t\"go-micro.dev/v5/cach"
},
{
"path": "cache/redis/redis.go",
"chars": 1281,
"preview": "package redis\n\nimport (\n\t\"context\"\n\t\"time\"\n\n\trclient \"github.com/go-redis/redis/v8\"\n\t\"go-micro.dev/v5/cache\"\n)\n\n// NewRe"
},
{
"path": "cache/redis/redis_test.go",
"chars": 1894,
"preview": "package redis\n\nimport (\n\t\"context\"\n\t\"os\"\n\t\"testing\"\n\t\"time\"\n\n\t\"go-micro.dev/v5/cache\"\n)\n\nvar (\n\tctx = conte"
},
{
"path": "client/backoff.go",
"chars": 316,
"preview": "package client\n\nimport (\n\t\"context\"\n\t\"time\"\n\n\t\"go-micro.dev/v5/internal/util/backoff\"\n)\n\ntype BackoffFunc func(ctx conte"
},
{
"path": "client/backoff_test.go",
"chars": 538,
"preview": "package client\n\nimport (\n\t\"context\"\n\t\"testing\"\n\t\"time\"\n)\n\nfunc TestBackoff(t *testing.T) {\n\tresults := []time.Duration{\n"
},
{
"path": "client/cache.go",
"chars": 1459,
"preview": "package client\n\nimport (\n\t\"context\"\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"hash/fnv\"\n\t\"time\"\n\n\tcache \"github.com/patrickmn/go-cache\"\n"
},
{
"path": "client/cache_test.go",
"chars": 1823,
"preview": "package client\n\nimport (\n\t\"context\"\n\t\"testing\"\n\t\"time\"\n\n\t\"go-micro.dev/v5/metadata\"\n\t\"go-micro.dev/v5/transport/headers\""
},
{
"path": "client/client.go",
"chars": 4284,
"preview": "// Package client is an interface for an RPC client\npackage client\n\nimport (\n\t\"context\"\n\n\t\"go-micro.dev/v5/codec\"\n)\n\nvar"
},
{
"path": "client/common_test.go",
"chars": 1013,
"preview": "package client\n\nimport (\n\t\"go-micro.dev/v5/registry\"\n)\n\nvar (\n\t// mock data.\n\ttestData = map[string][]*registry.Service{"
},
{
"path": "client/context.go",
"chars": 292,
"preview": "package client\n\nimport (\n\t\"context\"\n)\n\ntype clientKey struct{}\n\nfunc FromContext(ctx context.Context) (Client, bool) {\n\t"
},
{
"path": "client/grpc/codec.go",
"chars": 4474,
"preview": "package grpc\n\nimport (\n\tb \"bytes\"\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"strings\"\n\n\t\"go-micro.dev/v5/codec\"\n\t\"go-micro.dev/v5/codec/b"
},
{
"path": "client/grpc/error.go",
"chars": 1477,
"preview": "package grpc\n\nimport (\n\t\"net/http\"\n\n\t\"go-micro.dev/v5/errors\"\n\t\"google.golang.org/grpc/codes\"\n\t\"google.golang.org/grpc/s"
},
{
"path": "client/grpc/grpc.go",
"chars": 16863,
"preview": "// Package grpc provides a gRPC client\npackage grpc\n\nimport (\n\t\"context\"\n\t\"crypto/tls\"\n\t\"fmt\"\n\t\"net\"\n\t\"reflect\"\n\t\"string"
},
{
"path": "client/grpc/grpc_pool.go",
"chars": 4029,
"preview": "package grpc\n\nimport (\n\t\"context\"\n\t\"sync\"\n\t\"time\"\n\n\t\"google.golang.org/grpc\"\n\t\"google.golang.org/grpc/connectivity\"\n)\n\nt"
},
{
"path": "client/grpc/grpc_pool_test.go",
"chars": 1274,
"preview": "package grpc\n\nimport (\n\t\"context\"\n\t\"net\"\n\t\"testing\"\n\t\"time\"\n\n\t\"google.golang.org/grpc\"\n\tpb \"google.golang.org/grpc/examp"
},
{
"path": "client/grpc/grpc_test.go",
"chars": 2275,
"preview": "package grpc\n\nimport (\n\t\"context\"\n\t\"net\"\n\t\"testing\"\n\n\t\"go-micro.dev/v5/client\"\n\t\"go-micro.dev/v5/errors\"\n\t\"go-micro.dev/"
},
{
"path": "client/grpc/message.go",
"chars": 706,
"preview": "package grpc\n\nimport (\n\t\"go-micro.dev/v5/client\"\n)\n\ntype grpcEvent struct {\n\ttopic string\n\tcontentType string\n\tpay"
},
{
"path": "client/grpc/options.go",
"chars": 3504,
"preview": "// Package grpc provides a gRPC options\npackage grpc\n\nimport (\n\t\"context\"\n\t\"crypto/tls\"\n\n\t\"go-micro.dev/v5/client\"\n\t\"goo"
},
{
"path": "client/grpc/request.go",
"chars": 1659,
"preview": "package grpc\n\nimport (\n\t\"fmt\"\n\t\"strings\"\n\n\t\"go-micro.dev/v5/client\"\n\t\"go-micro.dev/v5/codec\"\n)\n\ntype grpcRequest struct "
},
{
"path": "client/grpc/request_test.go",
"chars": 650,
"preview": "package grpc\n\nimport (\n\t\"testing\"\n)\n\nfunc TestMethodToGRPC(t *testing.T) {\n\ttestData := []struct {\n\t\tservice string\n\t\tme"
},
{
"path": "client/grpc/response.go",
"chars": 807,
"preview": "package grpc\n\nimport (\n\t\"strings\"\n\n\t\"go-micro.dev/v5/codec\"\n\t\"go-micro.dev/v5/codec/bytes\"\n\t\"google.golang.org/grpc\"\n\t\"g"
},
{
"path": "client/grpc/stream.go",
"chars": 1331,
"preview": "package grpc\n\nimport (\n\t\"context\"\n\t\"io\"\n\t\"sync\"\n\n\t\"go-micro.dev/v5/client\"\n\t\"google.golang.org/grpc\"\n)\n\n// Implements th"
},
{
"path": "client/options.go",
"chars": 10422,
"preview": "package client\n\nimport (\n\t\"context\"\n\t\"time\"\n\n\t\"go-micro.dev/v5/broker\"\n\t\"go-micro.dev/v5/codec\"\n\t\"go-micro.dev/v5/logger"
},
{
"path": "client/options_test.go",
"chars": 2121,
"preview": "package client\n\nimport (\n\t\"testing\"\n\t\"time\"\n\n\t\"go-micro.dev/v5/transport\"\n)\n\nfunc TestCallOptions(t *testing.T) {\n\ttestD"
},
{
"path": "client/retry.go",
"chars": 893,
"preview": "package client\n\nimport (\n\t\"context\"\n\n\t\"go-micro.dev/v5/errors\"\n)\n\n// note that returning either false or a non-nil error"
},
{
"path": "client/rpc_client.go",
"chars": 15984,
"preview": "package client\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"sync\"\n\t\"sync/atomic\"\n\t\"time\"\n\n\t\"github.com/google/uuid\"\n\t\"github.com/pkg/er"
},
{
"path": "client/rpc_client_test.go",
"chars": 3876,
"preview": "package client\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"testing\"\n\n\t\"go-micro.dev/v5/errors\"\n\t\"go-micro.dev/v5/registry\"\n\t\"go-micro."
},
{
"path": "client/rpc_codec.go",
"chars": 5990,
"preview": "package client\n\nimport (\n\t\"bytes\"\n\terrs \"errors\"\n\n\t\"go-micro.dev/v5/codec\"\n\traw \"go-micro.dev/v5/codec/bytes\"\n\t\"go-micro"
},
{
"path": "client/rpc_message.go",
"chars": 637,
"preview": "package client\n\ntype message struct {\n\tpayload interface{}\n\ttopic string\n\tcontentType string\n}\n\nfunc newMessag"
},
{
"path": "client/rpc_request.go",
"chars": 1142,
"preview": "package client\n\nimport (\n\t\"go-micro.dev/v5/codec\"\n)\n\ntype rpcRequest struct {\n\topts RequestOptions\n\tcodec c"
},
{
"path": "client/rpc_request_test.go",
"chars": 648,
"preview": "package client\n\nimport (\n\t\"testing\"\n)\n\nfunc TestRequestOptions(t *testing.T) {\n\tr := newRequest(\"service\", \"endpoint\", n"
},
{
"path": "client/rpc_response.go",
"chars": 559,
"preview": "package client\n\nimport (\n\t\"go-micro.dev/v5/codec\"\n\t\"go-micro.dev/v5/transport\"\n)\n\ntype rpcResponse struct {\n\tsocket tran"
},
{
"path": "client/rpc_stream.go",
"chars": 3054,
"preview": "package client\n\nimport (\n\t\"context\"\n\t\"errors\"\n\t\"io\"\n\t\"sync\"\n\n\t\"go-micro.dev/v5/codec\"\n)\n\n// Implements the streamer inte"
},
{
"path": "client/wrapper.go",
"chars": 512,
"preview": "package client\n\nimport (\n\t\"context\"\n\n\t\"go-micro.dev/v5/registry\"\n)\n\n// CallFunc represents the individual call func.\ntyp"
},
{
"path": "cmd/cmd.go",
"chars": 22932,
"preview": "// Package cmd is an interface for parsing the command line\npackage cmd\n\nimport (\n\t\"fmt\"\n\t\"os\"\n\t\"sort\"\n\t\"strings\"\n\t\"time"
},
{
"path": "cmd/micro/README.md",
"chars": 16587,
"preview": "# Micro\n\nGo Micro Command Line\n\n## Install the CLI\n\nInstall `micro` via `go install`\n\n```\ngo install go-micro.dev/v5/cmd"
},
{
"path": "cmd/micro/cli/README.md",
"chars": 6379,
"preview": "# Micro [](https://opensource.org/licenses/Apache-2."
},
{
"path": "cmd/micro/cli/build/build.go",
"chars": 8290,
"preview": "// Package build provides the micro build command for building service binaries\npackage build\n\nimport (\n\t\"fmt\"\n\t\"os\"\n\t\"o"
},
{
"path": "cmd/micro/cli/cli.go",
"chars": 4422,
"preview": "package microcli\n\nimport (\n\t\"context\"\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"os\"\n\t\"os/exec\"\n\n\t\"github.com/urfave/cli/v2\"\n\t\"go-micro.d"
},
{
"path": "cmd/micro/cli/deploy/deploy.go",
"chars": 13312,
"preview": "// Package deploy provides the micro deploy command for deploying services\npackage deploy\n\nimport (\n\t\"fmt\"\n\t\"os\"\n\t\"os/ex"
},
{
"path": "cmd/micro/cli/gen/generate.go",
"chars": 6051,
"preview": "// Package generate provides code generation commands for micro\npackage gen\n\nimport (\n\t\"fmt\"\n\t\"os\"\n\t\"path/filepath\"\n\t\"st"
},
{
"path": "cmd/micro/cli/init/init.go",
"chars": 6497,
"preview": "// Package initcmd provides the micro init command for server setup\npackage initcmd\n\nimport (\n\t\"fmt\"\n\t\"os\"\n\t\"os/exec\"\n\t\""
},
{
"path": "cmd/micro/cli/new/new.go",
"chars": 5945,
"preview": "// Package new generates micro service templates\npackage new\n\nimport (\n\t\"fmt\"\n\t\"go/build\"\n\t\"os\"\n\t\"os/exec\"\n\t\"path\"\n\t\"pat"
},
{
"path": "cmd/micro/cli/new/template/handler.go",
"chars": 1529,
"preview": "package template\n\nvar (\n\tHandlerSRV = `package handler\n\nimport (\n\t\"context\"\n\n\tlog \"go-micro.dev/v5/logger\"\n\n\tpb \"{{.Dir}"
},
{
"path": "cmd/micro/cli/new/template/ignore.go",
"chars": 54,
"preview": "package template\n\nvar (\n\tGitIgnore = `\n{{.Alias}}\n`\n)\n"
},
{
"path": "cmd/micro/cli/new/template/main.go",
"chars": 772,
"preview": "package template\n\nvar (\n\tMainSRV = `package main\n\nimport (\n\t\"{{.Dir}}/handler\"\n\tpb \"{{.Dir}}/proto\"\n\n\t\"go-micro.dev/v5\"\n"
},
{
"path": "cmd/micro/cli/new/template/makefile.go",
"chars": 1018,
"preview": "package template\n\nvar Makefile = `.PHONY: proto build run test clean docker\n\n# Generate protobuf files\nproto:\n\tprotoc --"
},
{
"path": "cmd/micro/cli/new/template/module.go",
"chars": 171,
"preview": "package template\n\nvar (\n\tModule = `module {{.Dir}}\n\ngo 1.22\n\nrequire (\n\tgo-micro.dev/v5 latest\n\tgithub.com/golang/protob"
},
{
"path": "cmd/micro/cli/new/template/proto.go",
"chars": 628,
"preview": "package template\n\nvar (\n\tProtoSRV = `syntax = \"proto3\";\n\npackage {{dehyphen .Alias}};\n\noption go_package = \"./proto;{{de"
},
{
"path": "cmd/micro/cli/new/template/readme.go",
"chars": 1839,
"preview": "package template\n\nvar (\n\tReadme = `# {{title .Alias}} Service\n\nGenerated with\n\n` + \"```\" + `\nmicro new {{.Alias}}\n` + \"`"
},
{
"path": "cmd/micro/cli/remote/remote.go",
"chars": 8432,
"preview": "// Package remote provides remote server operations for micro\npackage remote\n\nimport (\n\t\"bufio\"\n\t\"fmt\"\n\t\"os\"\n\t\"os/exec\"\n"
},
{
"path": "cmd/micro/cli/util/dynamic.go",
"chars": 11936,
"preview": "package util\n\nimport (\n\t\"bytes\"\n\t\"context\"\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"math\"\n\t\"os\"\n\t\"sort\"\n\t\"strconv\"\n\t\"strings\"\n\t\"unicode"
},
{
"path": "cmd/micro/cli/util/dynamic_test.go",
"chars": 9257,
"preview": "package util\n\nimport (\n\t\"context\"\n\t\"reflect\"\n\t\"strings\"\n\t\"testing\"\n\n\t\"github.com/davecgh/go-spew/spew\"\n\t\"go-micro.dev/v5"
},
{
"path": "cmd/micro/cli/util/util.go",
"chars": 2196,
"preview": "// Package cliutil contains methods used across all cli commands\n// @todo: get rid of os.Exits and use errors instread\np"
},
{
"path": "cmd/micro/main.go",
"chars": 497,
"preview": "package main\n\nimport (\n\t\"embed\"\n\t\"go-micro.dev/v5/cmd\"\n\n\t_ \"go-micro.dev/v5/cmd/micro/cli\"\n\t_ \"go-micro.dev/v5/cmd/micro"
},
{
"path": "cmd/micro/mcp/EXAMPLES.md",
"chars": 9286,
"preview": "# MCP CLI Command Examples\n\nThis document provides examples of using the `micro mcp` commands for AI agent integration.\n"
},
{
"path": "cmd/micro/mcp/mcp.go",
"chars": 21528,
"preview": "// Package mcp provides the 'micro mcp' command for MCP server management\npackage mcp\n\nimport (\n\t\"context\"\n\t\"encoding/js"
},
{
"path": "cmd/micro/mcp/mcp_test.go",
"chars": 1842,
"preview": "package mcp\n\nimport (\n\t\"reflect\"\n\t\"testing\"\n)\n\nfunc TestParseTool(t *testing.T) {\n\ttests := []struct {\n\t\tname string"
},
{
"path": "cmd/micro/run/config/config.go",
"chars": 6828,
"preview": "// Package config handles micro.mu and micro.json configuration parsing\npackage config\n\nimport (\n\t\"bufio\"\n\t\"encoding/jso"
},
{
"path": "cmd/micro/run/config/config_test.go",
"chars": 4540,
"preview": "package config\n\nimport (\n\t\"os\"\n\t\"path/filepath\"\n\t\"testing\"\n)\n\nfunc TestParseMu(t *testing.T) {\n\tcontent := `# Micro conf"
},
{
"path": "cmd/micro/run/run.go",
"chars": 12549,
"preview": "package run\n\nimport (\n\t\"bufio\"\n\t\"context\"\n\t\"crypto/md5\"\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n\t\"os\"\n\t\"os/exec\"\n\t\"os/signal\"\n\t\"path/fi"
},
{
"path": "cmd/micro/run/watcher/watcher.go",
"chars": 3255,
"preview": "// Package watcher provides file watching for hot reload\npackage watcher\n\nimport (\n\t\"os\"\n\t\"path/filepath\"\n\t\"strings\"\n\t\"s"
},
{
"path": "cmd/micro/server/gateway.go",
"chars": 1962,
"preview": "package server\n\nimport (\n\t\"fmt\"\n\t\"net/http\"\n\t\"os\"\n\t\"path/filepath\"\n\n\t\"go-micro.dev/v5/gateway/api\"\n\t\"go-micro.dev/v5/reg"
},
{
"path": "cmd/micro/server/server.go",
"chars": 51678,
"preview": "package server\n\nimport (\n\t\"bytes\"\n\t\"crypto/rand\"\n\t\"crypto/rsa\"\n\t\"crypto/x509\"\n\t\"encoding/base64\"\n\t\"encoding/json\"\n\t\"enco"
},
{
"path": "cmd/micro/server/util_jwt.go",
"chars": 2298,
"preview": "package server\n\nimport (\n\t\"crypto/rand\"\n\t\"crypto/rsa\"\n\t\"crypto/x509\"\n\t\"encoding/pem\"\n\t\"errors\"\n\t\"os\"\n\t\"time\"\n\n\t\"github.c"
},
{
"path": "cmd/micro/web/main.js",
"chars": 1400,
"preview": "// Minimal JS for reactive form submissions\n\ndocument.addEventListener('DOMContentLoaded', function() {\n document.que"
},
{
"path": "cmd/micro/web/styles.css",
"chars": 4051,
"preview": "body {\n background: #fff;\n color: #111;\n font-family: 'Inter', 'Segoe UI', 'Arial', 'Helvetica Neue', Arial, sans-ser"
},
{
"path": "cmd/micro/web/templates/api.html",
"chars": 1736,
"preview": "{{define \"content\"}}\n<h2 class=\"text-2xl font-bold mb-4\">API</h2>\n<p style=\"background:#f8f8e8; border:1px solid #e0e0b0"
},
{
"path": "cmd/micro/web/templates/auth_login.html",
"chars": 613,
"preview": "{{define \"content\"}}\n<h2 class=\"text-2xl font-bold mb-4\">Login</h2>\n<form method=\"POST\" action=\"/auth/login\" style=\"max-"
},
{
"path": "cmd/micro/web/templates/auth_tokens.html",
"chars": 3605,
"preview": "{{define \"content\"}}\n<h2 class=\"text-2xl font-bold mb-4\">Tokens</h2>\n<table style=\"margin-bottom:2em;\">\n <thead>\n <t"
},
{
"path": "cmd/micro/web/templates/auth_users.html",
"chars": 1338,
"preview": "{{define \"content\"}}\n<h2 class=\"text-2xl font-bold mb-4\">User Accounts</h2>\n<table style=\"margin-bottom:2em;\">\n <thead>"
},
{
"path": "cmd/micro/web/templates/base.html",
"chars": 2872,
"preview": "<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n <meta charset=\"UTF-8\">\n <meta name=\"viewport\" content=\"width=device-width"
},
{
"path": "cmd/micro/web/templates/form.html",
"chars": 841,
"preview": "{{define \"content\"}}\n<h2>{{.ServiceName}}</h2>\n<form action=\"/{{.Action}}\" method=\"POST\" data-reactive>\n <h3 class=\"t"
},
{
"path": "cmd/micro/web/templates/home.html",
"chars": 1653,
"preview": "{{define \"content\"}}\n<h2 class=\"text-2xl font-bold mb-4\">Home</h2>\n<div style=\"display:flex; align-items:center; gap:2em"
},
{
"path": "cmd/micro/web/templates/log.html",
"chars": 245,
"preview": "{{define \"content\"}}\n<h2 class=\"text-2xl font-bold mb-4\">Logs for {{.Service}}</h2>\n<pre class=\"bg-gray-100 rounded p-2 "
},
{
"path": "cmd/micro/web/templates/logs.html",
"chars": 209,
"preview": "{{define \"content\"}}\n<h2 class=\"text-2xl font-bold mb-4\">Logs</h2>\n<ul class=\"no-bullets\">\n {{range .Services}}\n "
},
{
"path": "cmd/micro/web/templates/playground.html",
"chars": 12447,
"preview": "{{define \"content\"}}\n<style>\n #agent-chat {\n display: flex;\n flex-direction: column;\n height: calc(100vh - 160"
},
{
"path": "cmd/micro/web/templates/scopes.html",
"chars": 4325,
"preview": "{{define \"content\"}}\n<h2 class=\"text-2xl font-bold mb-4\">Scopes</h2>\n<p style=\"color:#666; margin-bottom:1.5em;\">\n Set "
},
{
"path": "cmd/micro/web/templates/service.html",
"chars": 754,
"preview": "{{define \"content\"}}\n{{if .ServiceName}}\n <h2 class=\"text-xl font-bold mb-2\">{{.ServiceName}}</h2>\n <h4 class=\"font-se"
},
{
"path": "cmd/micro/web/templates/status.html",
"chars": 640,
"preview": "{{define \"content\"}}\n<h2 class=\"text-2xl font-bold mb-4\">Service Status</h2>\n<table>\n <thead>\n <tr>\n <th>Servic"
},
{
"path": "cmd/micro-mcp-gateway/Dockerfile",
"chars": 405,
"preview": "FROM golang:1.23-alpine AS builder\n\nRUN apk add --no-cache git\n\nWORKDIR /src\nCOPY go.mod go.sum ./\nRUN go mod download\n\n"
},
{
"path": "cmd/micro-mcp-gateway/main.go",
"chars": 6270,
"preview": "// Command micro-mcp-gateway runs a standalone MCP gateway that discovers\n// go-micro services via a registry and expose"
},
{
"path": "cmd/options.go",
"chars": 5219,
"preview": "package cmd\n\nimport (\n\t\"context\"\n\n\t\"go-micro.dev/v5/auth\"\n\t\"go-micro.dev/v5/broker\"\n\t\"go-micro.dev/v5/cache\"\n\t\"go-micro."
},
{
"path": "cmd/protoc-gen-micro/README.md",
"chars": 3276,
"preview": "# protoc-gen-micro\n\nThis is protobuf code generation for go-micro. We use protoc-gen-micro to reduce boilerplate code.\n\n"
},
{
"path": "cmd/protoc-gen-micro/examples/greeter/greeter.pb.go",
"chars": 6593,
"preview": "// Code generated by protoc-gen-go. DO NOT EDIT.\n// versions:\n// \tprotoc-gen-go v1.32.0\n// \tprotoc v4.25.3\n// sou"
},
{
"path": "cmd/protoc-gen-micro/examples/greeter/greeter.pb.micro.go",
"chars": 4212,
"preview": "// Code generated by protoc-gen-micro. DO NOT EDIT.\n// source: greeter.proto\n\npackage greeter\n\nimport (\n\tfmt \"fmt\"\n\tprot"
},
{
"path": "cmd/protoc-gen-micro/examples/greeter/greeter.proto",
"chars": 278,
"preview": "syntax = \"proto3\";\n\noption go_package = \"../greeter\";\n\nservice Greeter {\n\trpc Hello(Request) returns (Response) {}\n\trpc "
},
{
"path": "cmd/protoc-gen-micro/examples/user/user.pb.micro.go.example",
"chars": 4513,
"preview": "// Code generated by protoc-gen-micro. DO NOT EDIT.\n// source: user.proto\n\npackage user\n\nimport (\n\tfmt \"fmt\"\n\tproto \"goo"
},
{
"path": "cmd/protoc-gen-micro/examples/user/user.proto",
"chars": 673,
"preview": "syntax = \"proto3\";\n\noption go_package = \"../user\";\n\n// UserService manages user accounts.\nservice UserService {\n\trpc Cre"
},
{
"path": "cmd/protoc-gen-micro/generator/Makefile",
"chars": 1826,
"preview": "# Go support for Protocol Buffers - Google's data interchange format\n#\n# Copyright 2010 The Go Authors. All rights rese"
},
{
"path": "cmd/protoc-gen-micro/generator/generator.go",
"chars": 90375,
"preview": "// Go support for Protocol Buffers - Google's data interchange format\n//\n// Copyright 2010 The Go Authors. All rights r"
},
{
"path": "cmd/protoc-gen-micro/generator/name_test.go",
"chars": 4656,
"preview": "// Go support for Protocol Buffers - Google's data interchange format\n//\n// Copyright 2013 The Go Authors. All rights r"
},
{
"path": "cmd/protoc-gen-micro/main.go",
"chars": 3665,
"preview": "// Go support for Protocol Buffers - Google's data interchange format\n//\n// Copyright 2010 The Go Authors. All rights r"
},
{
"path": "cmd/protoc-gen-micro/plugin/micro/micro.go",
"chars": 22000,
"preview": "package micro\n\nimport (\n\t\"fmt\"\n\t\"path\"\n\t\"strconv\"\n\t\"strings\"\n\n\t\"go-micro.dev/v5/cmd/protoc-gen-micro/generator\"\n\toptions"
},
{
"path": "cmd/protoc-gen-micro/plugin/micro/micro_test.go",
"chars": 1026,
"preview": "package micro\n\nimport \"testing\"\n\nfunc TestParseModelOptions(t *testing.T) {\n\ttests := []struct {\n\t\tcomment string\n\t\twa"
},
{
"path": "codec/bytes/bytes.go",
"chars": 1208,
"preview": "// Package bytes provides a bytes codec which does not encode or decode anything\npackage bytes\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\n\t"
},
{
"path": "codec/bytes/marshaler.go",
"chars": 634,
"preview": "package bytes\n\nimport (\n\t\"go-micro.dev/v5/codec\"\n)\n\ntype Marshaler struct{}\n\ntype Message struct {\n\tHeader map[string]st"
},
{
"path": "codec/codec.go",
"chars": 1512,
"preview": "// Package codec is an interface for encoding messages\npackage codec\n\nimport (\n\t\"errors\"\n\t\"io\"\n)\n\nconst (\n\tError Message"
},
{
"path": "codec/grpc/grpc.go",
"chars": 3238,
"preview": "// Package grpc provides a grpc codec\npackage grpc\n\nimport (\n\t\"encoding/json\"\n\t\"errors\"\n\t\"fmt\"\n\t\"io\"\n\t\"strings\"\n\n\t\"githu"
},
{
"path": "codec/grpc/util.go",
"chars": 1373,
"preview": "package grpc\n\nimport (\n\t\"encoding/binary\"\n\t\"fmt\"\n\t\"io\"\n)\n\nvar (\n\tMaxMessageSize = 1024 * 1024 * 4 // 4Mb\n\tmaxInt "
},
{
"path": "codec/json/any_test.go",
"chars": 2708,
"preview": "package json\n\nimport (\n\t\"encoding/json\"\n\t\"testing\"\n\n\t\"google.golang.org/protobuf/types/known/anypb\"\n\t\"google.golang.org/"
},
{
"path": "codec/json/codec_test.go",
"chars": 2848,
"preview": "package json\n\nimport (\n\t\"bytes\"\n\t\"encoding/json\"\n\t\"testing\"\n\n\t\"go-micro.dev/v5/codec\"\n\t\"google.golang.org/protobuf/types"
},
{
"path": "codec/json/json.go",
"chars": 1308,
"preview": "// Package json provides a json codec\npackage json\n\nimport (\n\t\"encoding/json\"\n\t\"io\"\n\n\t\"go-micro.dev/v5/codec\"\n\t\"google.g"
},
{
"path": "codec/json/marshaler.go",
"chars": 626,
"preview": "package json\n\nimport (\n\t\"encoding/json\"\n\n\t\"google.golang.org/protobuf/encoding/protojson\"\n\t\"google.golang.org/protobuf/p"
},
{
"path": "codec/jsonrpc/client.go",
"chars": 1847,
"preview": "package jsonrpc\n\nimport (\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"io\"\n\t\"sync\"\n\n\t\"go-micro.dev/v5/codec\"\n)\n\ntype clientCodec struct {\n\n"
},
{
"path": "codec/jsonrpc/jsonrpc.go",
"chars": 1661,
"preview": "// Package jsonrpc provides a json-rpc 1.0 codec\npackage jsonrpc\n\nimport (\n\t\"bytes\"\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"io\"\n\n\t\"go-"
},
{
"path": "codec/jsonrpc/server.go",
"chars": 1617,
"preview": "package jsonrpc\n\nimport (\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"io\"\n\n\t\"go-micro.dev/v5/codec\"\n)\n\ntype serverCodec struct {\n\tdec *jso"
},
{
"path": "codec/proto/marshaler.go",
"chars": 931,
"preview": "package proto\n\nimport (\n\t\"bytes\"\n\n\t\"github.com/golang/protobuf/proto\"\n\t\"github.com/oxtoacart/bpool\"\n\t\"go-micro.dev/v5/co"
},
{
"path": "codec/proto/message.go",
"chars": 568,
"preview": "package proto\n\ntype Message struct {\n\tData []byte\n}\n\nfunc (m *Message) MarshalJSON() ([]byte, error) {\n\treturn m.Data, n"
},
{
"path": "codec/proto/proto.go",
"chars": 1014,
"preview": "// Package proto provides a proto codec\npackage proto\n\nimport (\n\t\"io\"\n\n\t\"github.com/golang/protobuf/proto\"\n\t\"go-micro.de"
},
{
"path": "codec/protorpc/envelope.pb.go",
"chars": 4825,
"preview": "// Code generated by protoc-gen-go. DO NOT EDIT.\n// source: codec/protorpc/envelope.proto\n\npackage protorpc\n\nimport (\n\tf"
},
{
"path": "codec/protorpc/envelope.pb.micro.go",
"chars": 641,
"preview": "// Code generated by protoc-gen-micro. DO NOT EDIT.\n// source: codec/protorpc/envelope.proto\n\npackage protorpc\n\nimport ("
},
{
"path": "codec/protorpc/envelope.proto",
"chars": 192,
"preview": "syntax = \"proto3\";\n\npackage protorpc;\n\nmessage Request {\n\tstring service_method = 1;\n\tfixed64 seq = 2;\n}\n\nmessage Respon"
},
{
"path": "codec/protorpc/netstring.go",
"chars": 785,
"preview": "package protorpc\n\nimport (\n\t\"encoding/binary\"\n\t\"io\"\n)\n\n// WriteNetString writes data to a big-endian netstring on a Writ"
},
{
"path": "codec/protorpc/protorpc.go",
"chars": 3621,
"preview": "// Protorpc provides a net/rpc proto-rpc codec. See envelope.proto for the format.\npackage protorpc\n\nimport (\n\t\"bytes\"\n\t"
},
{
"path": "codec/text/text.go",
"chars": 1269,
"preview": "// Package text reads any text/* content-type\npackage text\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\n\t\"go-micro.dev/v5/codec\"\n)\n\ntype Code"
},
{
"path": "config/README.md",
"chars": 1651,
"preview": "# Config [](https://godoc.org/github.com/micro/go"
},
{
"path": "config/config.go",
"chars": 2061,
"preview": "// Package config is an interface for dynamic configuration.\npackage config\n\nimport (\n\t\"context\"\n\n\t\"go-micro.dev/v5/conf"
},
{
"path": "config/default.go",
"chars": 4770,
"preview": "package config\n\nimport (\n\t\"bytes\"\n\t\"fmt\"\n\t\"go-micro.dev/v5/config/loader\"\n\t\"go-micro.dev/v5/config/loader/memory\"\n\t\"go-m"
},
{
"path": "config/default_test.go",
"chars": 3385,
"preview": "package config\n\nimport (\n\t\"fmt\"\n\t\"os\"\n\t\"path/filepath\"\n\t\"runtime\"\n\t\"strings\"\n\t\"testing\"\n\t\"time\"\n\n\t\"go-micro.dev/v5/confi"
},
{
"path": "config/encoder/encoder.go",
"chars": 184,
"preview": "// Package encoder handles source encoding formats\npackage encoder\n\ntype Encoder interface {\n\tEncode(interface{}) ([]byt"
},
{
"path": "config/encoder/json/json.go",
"chars": 403,
"preview": "package json\n\nimport (\n\t\"encoding/json\"\n\n\t\"go-micro.dev/v5/config/encoder\"\n)\n\ntype jsonEncoder struct{}\n\nfunc (j jsonEnc"
},
{
"path": "config/loader/loader.go",
"chars": 1414,
"preview": "// Package loader manages loading from multiple sources\npackage loader\n\nimport (\n\t\"context\"\n\n\t\"go-micro.dev/v5/config/re"
},
{
"path": "config/loader/memory/memory.go",
"chars": 7632,
"preview": "package memory\n\nimport (\n\t\"bytes\"\n\t\"container/list\"\n\t\"errors\"\n\t\"fmt\"\n\t\"strings\"\n\t\"sync\"\n\t\"sync/atomic\"\n\t\"time\"\n\n\t\"go-mic"
},
{
"path": "config/loader/memory/options.go",
"chars": 555,
"preview": "package memory\n\nimport (\n\t\"go-micro.dev/v5/config/loader\"\n\t\"go-micro.dev/v5/config/reader\"\n\t\"go-micro.dev/v5/config/sour"
},
{
"path": "config/options.go",
"chars": 653,
"preview": "package config\n\nimport (\n\t\"go-micro.dev/v5/config/loader\"\n\t\"go-micro.dev/v5/config/reader\"\n\t\"go-micro.dev/v5/config/sour"
},
{
"path": "config/reader/json/json.go",
"chars": 1531,
"preview": "package json\n\nimport (\n\t\"errors\"\n\t\"time\"\n\n\t\"dario.cat/mergo\"\n\t\"go-micro.dev/v5/config/encoder\"\n\t\"go-micro.dev/v5/config/"
},
{
"path": "config/reader/json/json_test.go",
"chars": 725,
"preview": "package json\n\nimport (\n\t\"testing\"\n\n\t\"go-micro.dev/v5/config/source\"\n)\n\nfunc TestReader(t *testing.T) {\n\tdata := []byte(`"
},
{
"path": "config/reader/json/values.go",
"chars": 3471,
"preview": "package json\n\nimport (\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"strconv\"\n\t\"strings\"\n\t\"time\"\n\n\tsimple \"github.com/bitly/go-simplejson\"\n\t"
},
{
"path": "config/reader/json/values_test.go",
"chars": 1557,
"preview": "package json\n\nimport (\n\t\"reflect\"\n\t\"testing\"\n\n\t\"go-micro.dev/v5/config/source\"\n)\n\nfunc TestValues(t *testing.T) {\n\tempty"
}
]
// ... and 476 more files (download for full content)
About this extraction
This page contains the full source code of the micro/go-micro GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 676 files (2.6 MB), approximately 720.9k tokens, and a symbol index with 4401 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.
Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.