{"id":36753131,"url":"https://github.com/checkr/openmock","last_synced_at":"2026-01-12T12:46:57.290Z","repository":{"id":34386750,"uuid":"145638289","full_name":"checkr/openmock","owner":"checkr","description":"Mock all the services. Intuitive YAML DSL for HTTP, gRPC, Kafka, and AMQP mocks.","archived":false,"fork":false,"pushed_at":"2023-02-28T21:57:11.000Z","size":10071,"stargazers_count":159,"open_issues_count":9,"forks_count":21,"subscribers_count":34,"default_branch":"master","last_synced_at":"2024-06-18T23:12:35.898Z","etag":null,"topics":["golang","integration-testing","staging"],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/checkr.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2018-08-22T01:19:04.000Z","updated_at":"2024-05-14T11:27:37.000Z","dependencies_parsed_at":"2024-06-18T22:52:30.115Z","dependency_job_id":"d2c3ac36-0922-4a11-acec-6531ec26d5b8","html_url":"https://github.com/checkr/openmock","commit_stats":null,"previous_names":[],"tags_count":15,"template":false,"template_full_name":null,"purl":"pkg:github/checkr/openmock","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/checkr%2Fopenmock","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/checkr%2Fopenmock/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/checkr%2Fopenmock/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/checkr%2Fopenmock/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/checkr","download_url":"https://codeload.github.com/checkr/openmock/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/checkr%2Fopenmock/sbom","scorecard":{"id":275365,"data":{"date":"2025-08-11","repo":{"name":"github.com/checkr/openmock","commit":"377ef79c2f820730824abda160a5a11161470e8a"},"scorecard":{"version":"v5.2.1-40-gf6ed084d","commit":"f6ed084d17c9236477efd66e5b258b9d4cc7b389"},"score":3.5,"checks":[{"name":"Maintained","score":0,"reason":"0 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 0","details":null,"documentation":{"short":"Determines if the project is \"actively maintained\".","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#maintained"}},{"name":"Code-Review","score":7,"reason":"Found 6/8 approved changesets -- score normalized to 7","details":null,"documentation":{"short":"Determines if the project requires human code review before pull requests (aka merge requests) are merged.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#code-review"}},{"name":"CII-Best-Practices","score":0,"reason":"no effort to earn an OpenSSF best practices badge detected","details":null,"documentation":{"short":"Determines if the project has an OpenSSF (formerly CII) Best Practices Badge.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#cii-best-practices"}},{"name":"Token-Permissions","score":0,"reason":"detected GitHub workflow tokens with excessive permissions","details":["Warn: no topLevel permission defined: .github/workflows/main.yml:1","Info: no jobLevel write permissions found"],"documentation":{"short":"Determines if the project's workflows follow the principle of least privilege.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#token-permissions"}},{"name":"Packaging","score":-1,"reason":"packaging workflow not detected","details":["Warn: no GitHub/GitLab publishing workflow detected."],"documentation":{"short":"Determines if the project is published as a package that others can easily download, install, easily update, and uninstall.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#packaging"}},{"name":"Dangerous-Workflow","score":10,"reason":"no dangerous workflow patterns detected","details":null,"documentation":{"short":"Determines if the project's GitHub Action workflows avoid dangerous patterns.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#dangerous-workflow"}},{"name":"Security-Policy","score":0,"reason":"security policy file not detected","details":["Warn: no security policy file detected","Warn: no security file to analyze","Warn: no security file to analyze","Warn: no security file to analyze"],"documentation":{"short":"Determines if the project has published a security policy.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#security-policy"}},{"name":"Fuzzing","score":0,"reason":"project is not fuzzed","details":["Warn: no fuzzer integrations found"],"documentation":{"short":"Determines if the project uses fuzzing.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#fuzzing"}},{"name":"License","score":10,"reason":"license file detected","details":["Info: project has a license file: LICENSE:0","Info: FSF or OSI recognized license: Apache License 2.0: LICENSE:0"],"documentation":{"short":"Determines if the project has defined a license.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#license"}},{"name":"Branch-Protection","score":-1,"reason":"internal error: error during branchesHandler.setup: internal error: githubv4.Query: Resource not accessible by integration","details":null,"documentation":{"short":"Determines if the default and release branches are protected with GitHub's branch protection settings.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#branch-protection"}},{"name":"Signed-Releases","score":-1,"reason":"no releases found","details":null,"documentation":{"short":"Determines if the project cryptographically signs release artifacts.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#signed-releases"}},{"name":"Binary-Artifacts","score":10,"reason":"no binaries found in the repo","details":null,"documentation":{"short":"Determines if the project has generated executable (binary) artifacts in the source repository.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#binary-artifacts"}},{"name":"SAST","score":0,"reason":"SAST tool is not run on all commits -- score normalized to 0","details":["Warn: 0 commits out of 28 are checked with a SAST tool"],"documentation":{"short":"Determines if the project uses static code analysis.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#sast"}},{"name":"Pinned-Dependencies","score":0,"reason":"dependency not pinned by hash detected -- score normalized to 0","details":["Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/main.yml:9: update your workflow using https://app.stepsecurity.io/secureworkflow/checkr/openmock/main.yml/master?enable=pin","Warn: third-party GitHubAction not pinned by hash: .github/workflows/main.yml:11: update your workflow using https://app.stepsecurity.io/secureworkflow/checkr/openmock/main.yml/master?enable=pin","Warn: third-party GitHubAction not pinned by hash: .github/workflows/main.yml:18: update your workflow using https://app.stepsecurity.io/secureworkflow/checkr/openmock/main.yml/master?enable=pin","Warn: containerImage not pinned by hash: Dockerfile:1","Warn: containerImage not pinned by hash: Dockerfile:6","Warn: containerImage not pinned by hash: Dockerfile:8: pin your Docker image by updating alpine:3.6 to alpine:3.6@sha256:66790a2b79e1ea3e1dabac43990c54aca5d1ddf268d9a5a0285e4167c8b24475","Warn: goCommand not pinned by hash: vendor/github.com/goombaio/orderedmap/lint.bash:11","Warn: goCommand not pinned by hash: vendor/github.com/goombaio/orderedmap/lint.bash:36","Warn: goCommand not pinned by hash: vendor/google.golang.org/grpc/vet.sh:36","Warn: goCommand not pinned by hash: vendor/google.golang.org/grpc/vet.sh:47","Info:   0 out of   1 GitHub-owned GitHubAction dependencies pinned","Info:   0 out of   2 third-party GitHubAction dependencies pinned","Info:   0 out of   3 containerImage dependencies pinned","Info:   0 out of   4 goCommand dependencies pinned"],"documentation":{"short":"Determines if the project has declared and pinned the dependencies of its build process.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#pinned-dependencies"}},{"name":"Vulnerabilities","score":0,"reason":"42 existing vulnerabilities detected","details":["Warn: Project is vulnerable to: GO-2020-0048 / GHSA-93m7-c69f-5cfj","Warn: Project is vulnerable to: GO-2023-1941 / GHSA-4r8x-2p26-976p","Warn: Project is vulnerable to: GO-2021-0051 / GHSA-j453-hm5x-c46w","Warn: Project is vulnerable to: GO-2022-1031 / GHSA-crxj-hrmp-4rwf","Warn: Project is vulnerable to: GO-2021-0059 / GHSA-w942-gw6m-p62c","Warn: Project is vulnerable to: GO-2022-0957 / GHSA-wjm3-fq3r-5x46","Warn: Project is vulnerable to: GO-2021-0054 / GHSA-p64j-r5f4-pwwx","Warn: Project is vulnerable to: GO-2021-0265 / GHSA-ppj4-34rq-v8j9","Warn: Project is vulnerable to: GO-2021-0356 / GHSA-8c26-wmh5-6g9v","Warn: Project is vulnerable to: GO-2024-2961","Warn: Project is vulnerable to: GO-2023-2402 / GHSA-45x7-px36-x8w8","Warn: Project is vulnerable to: GO-2024-3321 / GHSA-v778-237x-gjrc","Warn: Project is vulnerable to: GO-2025-3487 / GHSA-hcg3-q754-cr77","Warn: Project is vulnerable to: GO-2022-0969 / GHSA-69cg-p879-7622","Warn: Project is vulnerable to: GO-2022-1144 / GHSA-xrjj-mj9h-534m","Warn: Project is vulnerable to: GO-2023-1571 / GHSA-vvpx-j8f3-3w6h","Warn: Project is vulnerable to: GO-2023-1988 / GHSA-2wrh-6pvc-2jm9","Warn: Project is vulnerable to: GO-2023-2102 / GHSA-4374-p667-p6c8","Warn: Project is vulnerable to: GO-2023-2153 / GHSA-m425-mq94-257g / GHSA-qppj-fm5r-hxr3","Warn: Project is vulnerable to: GO-2024-2687 / GHSA-4v7x-pqxf-cx7m","Warn: Project is vulnerable to: GO-2024-3333","Warn: Project is vulnerable to: GO-2025-3503 / GHSA-qxp5-gwg8-xv66","Warn: Project is vulnerable to: GO-2025-3595 / GHSA-vvgc-356p-c3xw","Warn: Project is vulnerable to: GO-2024-2611 / GHSA-8r3f-844c-mc37","Warn: Project is vulnerable to: GO-2021-0112 / GHSA-f6mq-5m25-4r72","Warn: Project is vulnerable to: GO-2022-0236 / GHSA-h86h-8ppg-mxmh","Warn: Project is vulnerable to: GO-2021-0238 / GHSA-83g2-8m93-v3w7","Warn: Project is vulnerable to: GO-2022-0288","Warn: Project is vulnerable to: GO-2020-0015 / GHSA-5rcv-m4m3-hfh7","Warn: Project is vulnerable to: GO-2021-0113 / GHSA-ppp9-7jff-5vj2","Warn: Project is vulnerable to: GO-2022-1059 / GHSA-69ch-w2m2-3vjp","Warn: Project is vulnerable to: GO-2020-0036 / GHSA-wxc4-f4m6-wwqv","Warn: Project is vulnerable to: GO-2024-2920 / GHSA-2hmf-46v7-v6fx","Warn: Project is vulnerable to: GO-2020-0017 / GHSA-w73w-5m7g-f7qc","Warn: Project is vulnerable to: GO-2021-0227 / GHSA-3vm4-22fp-5rfm","Warn: Project is vulnerable to: GO-2022-0968 / GHSA-gwc9-m7rh-j2ww","Warn: Project is vulnerable to: GO-2022-0493 / GHSA-p782-xgp4-8hr8","Warn: Project is vulnerable to: GO-2021-0061 / GHSA-r88r-gmrh-7j83","Warn: Project is vulnerable to: GO-2022-0956 / GHSA-6q6q-88xp-6f2r","Warn: Project is vulnerable to: GO-2025-3372 / GHSA-6wxm-mpqj-6jpf","Warn: Project is vulnerable to: GO-2022-0536 / GHSA-39qc-96h7-956f / GHSA-hgr8-6h9x-f7q9","Warn: Project is vulnerable to: GO-2025-3488 / GHSA-6v2p-p543-phr9"],"documentation":{"short":"Determines if the project has open, known unfixed vulnerabilities.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#vulnerabilities"}}]},"last_synced_at":"2025-08-17T14:15:45.120Z","repository_id":34386750,"created_at":"2025-08-17T14:15:45.120Z","updated_at":"2025-08-17T14:15:45.120Z"},"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28338983,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-12T12:22:26.515Z","status":"ssl_error","status_checked_at":"2026-01-12T12:22:10.856Z","response_time":98,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.6:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["golang","integration-testing","staging"],"created_at":"2026-01-12T12:46:57.218Z","updated_at":"2026-01-12T12:46:57.278Z","avatar_url":"https://github.com/checkr.png","language":"Go","readme":"[\u003cimg src=\"docs/logo.svg\"\u003e](https://github.com/checkr/openmock)\n\n\u003cp align=\"center\"\u003e\n    \u003ca href=\"https://goreportcard.com/report/github.com/checkr/openmock\" target=\"_blank\"\u003e\n        \u003cimg src=\"https://goreportcard.com/badge/github.com/checkr/openmock\"\u003e\n    \u003c/a\u003e\n    \u003ca href=\"https://circleci.com/gh/checkr/openmock\" target=\"_blank\"\u003e\n        \u003cimg src=\"https://circleci.com/gh/checkr/openmock.svg?style=shield\"\u003e\n    \u003c/a\u003e\n    \u003ca href=\"https://godoc.org/github.com/checkr/openmock\" target=\"_blank\"\u003e\n        \u003cimg src=\"https://img.shields.io/badge/godoc-reference-green.svg\"\u003e\n    \u003c/a\u003e\n\u003c/p\u003e\n\n# OpenMock\n\nOpenMock is a Go service that can mock services in integration tests, staging environment, or anywhere.\nThe goal is to simplify the process of writing mocks in various channels.\nCurrently it supports the following channels:\n\n- HTTP\n- gRPC\n- Kafka\n- AMQP (e.g. RabbitMQ)\n\n# Usage\n\nUse it with docker.\n\n```bash\n$ docker run -it -p 9999:9999 -v $(pwd)/demo_templates:/data/templates checkr/openmock \n```\n\nMore complete openmock instance (e.g. redis) with docker-compose.\n\n```bash\n$ docker-compose up\n```\n\nTest it.\n\n```bash\n$ curl localhost:9999/ping\n```\n\nDependencies.\n\n- HTTP (native supported, thanks to https://echo.labstack.com/)\n  - One can configure HTTP port, set env `OPENMOCK_HTTP_PORT=80`\n- GRPC (supported through through HTTP/2 interface)\n  - One can configure GRPC port, set env `OPENMOCK_GRPC_PORT=50051`\n- Kafka (optional)\n  - To enable mocking kafka, set env `OPENMOCK_KAFKA_ENABLED=true`.\n  - One can also config the following kafka parameters, optionally with separate config for consumers and producers.  For example `OPENMOCK_KAFKA_SEED_BROKERS`, `OPENMOCK_KAFKA_PRODUCER_SEED_BROKERS`, and `OPENMOCK_KAFKA_CONSUMER_SEED_BROKERS`\n    - `OPENMOCK_KAFKA_SEED_BROKERS`\n    - `OPENMOCK_KAFKA_SASL_USERNAME`\n    - `OPENMOCK_KAFKA_SASL_PASSWORD`\n    - `OPENMOCK_KAFKA_TLS_ENABLED`\n- AMQP (optional)\n  - To enable mocking amqp, set env `OPENMOCK_AMQP_ENABLED=true`\n  - One can also config `OPENMOCK_AMQP_URL`.\n- NPM (development only)\n  - Used in Makefile during swagger admin API server generation\n\n# OpenMock Templates\n\nTemplates are YAML files that describe the behavior of OpenMock.\n\n## Templates Directory\n\nYou can put any number of `.yaml` or `.yml` files in a directory, and then point\nenvironment variable `OPENMOCK_TEMPLATES_DIR` to it. OpenMock\nwill recursively (including subdirectories) load all the YAML files. For example:\n\n```sh\n# OPENMOCK_TEMPLATES_DIR=./demo_templates\n\n./demo_templates\n├── amqp.yaml\n├── files\n│   └── colors.json\n├── http.yaml\n├── jsonrpc.yaml\n├── kafka.yaml\n└── payload_from_file.yaml\n```\n\n## Schema\n\nOpenMock is configured a list of behaviors for it to follow. Each behavior is\nidentified by a key, and a kind:\n\n```yaml\n- key: respond-to-resource\n  kind: Behavior\n```\n\n### Expect\n\nIt represents the channel to listen on and condition for the \nactions of the behavior to be performed. Available channels are:\n\n- http\n- kafka\n- amqp\n- grpc\n\nFor example, under what condition and from what channel should\nwe proceed with the actions.\n\n```yaml\n- key: no-op\n  kind: Behavior\n  expect:\n    # Condition checks if we need to do the actions or not\n    # It only proceeds if it evaluates to \"true\"\n    condition: '{{.HTTPHeader.Get \"X-Token\" | eq \"t1234\"}}'\n    # Use one (and only one) of the following channels - [http, kafka, amqp]\n    http:\n      method: GET\n      path: /ping\n    kafka:\n      topic: hello_kafka_in\n    amqp:\n      exchange: exchange_1\n      routing_key: key_in\n      queue: key_in\n```\n\n### Actions\n\nActions are a series of functions to run. Availabe actions are:\n\n- publish_amqp\n- publish_kafka\n- redis\n- reply_http\n- send_http\n- reply_grpc\n- sleep\n\n```yaml\n- key: every-op\n  kind: Behavior\n  expect:\n    http:\n      method: GET\n      path: /ping\n  actions:\n    - publish_kafka:\n        topic: hello_kafka_out\n        payload: \u003e\n          {\n            \"kafka\": \"OK\",\n            \"data\": {}\n          }\n    - sleep:\n        duration: 1s\n    - reply_http:\n        status_code: 200\n        body: OK\n        headers:\n          Content-Type: text/html\n```\n\nThe actions by default run in the order defined in the mock file; you can adjust this by adding an int 'order' value from lowest to highest number. The default value for 'order' is 0.\n\n```yaml\n- key: every-op\n  kind: Behavior\n  expect:\n    http:\n      method: GET\n      path: /ping\n  actions:\n    - publish_kafka:\n        topic: hello_kafka_out\n        payload: \u003e\n          {\n            \"kafka\": \"OK\",\n            \"data\": {}\n          }\n    - sleep:\n        duration: 1s\n      # sleep first\n      order: -1000\n```\n\n### Templates\n\nTemplates can be useful to assemble your payloads from parts\n\n```yaml\n- key: dog\n  kind: Template\n  template: \u003e\n    \u003canimal\u003edog\u003c/animal\u003e\n\n- key: cat\n  kind: Template\n  template: \u003e\n    \u003canimal\u003ecat\u003c/animal\u003e\n\n# $ curl 0:9999/fred\n# \u003chuman\u003e   \u003cname\u003efred\u003c/name\u003e   \u003cpets\u003e     \u003canimal\u003edog\u003c/animal\u003e      \u003canimal\u003ecat\u003c/animal\u003e    \u003c/pets\u003e \u003c/human\u003e\n- key: get-freds-pets\n  kind: Behavior\n  expect:\n    http:\n      method: GET\n      path: /fred\n  actions:\n    - reply_http:\n        status_code: 200\n        body: \u003e\n          \u003chuman\u003e\n            \u003cname\u003efred\u003c/name\u003e\n            \u003cpets\u003e\n              {{template \"dog\"}}\n              {{template \"cat\"}}\n            \u003c/pets\u003e\n          \u003c/human\u003e\n```\n\n### Abstract Behaviors\n\nAbstract Behaviors can be used to parameterize some data.\n\nWhen an abstract behavior and a behavior extending it both have actions defined, all of them are run when the behavior matches.  Actions will run from lowest to highest value of the 'order' field; if this is the same for two actions the action defined earlier in the abstract behavior runs first, followed by actions in the concrete behavior.\nBe aware that values with all digits will be interpreted into `int` type (YAML syntax), and it will fail the condition check given that some helper functions are returning `string` types. Pipe to `toString` before the comparison or alternatively put quotes around the values. See example in `abstract_behaviors.yml`.\n\n```yaml\n- key: fruit-of-the-day\n  kind: AbstractBehavior\n  values:\n    fruit: potato\n  expect:\n    condition: '{{.HTTPQueryString | contains .Values.day}}'\n    http:\n      method: GET\n      path: /fruit-of-the-day\n  actions:\n    - reply_http:\n        status_code: 200\n        body: '{\"fruit\": \"{{.Values.fruit}}\"}'\n\n# $ curl 0:9999/fruit-of-the-day?day=monday\n# {\"fruit\": \"apple\"}\n- key: monday-fruit\n  kind: Behavior\n  extend: fruit-of-the-day\n  values:\n    day: monday\n    fruit: apple\n\n# $ curl 0:9999/fruit-of-the-day?day=tuesday\n# {\"fruit\": \"potato\"}\n- key: tuesday-fruit\n  kind: Behavior\n  extend: fruit-of-the-day\n  values:\n    day: tuesday\n  actions: \n    # sleep then reply_http\n    - sleep:\n         duration: 1s\n      order: -1000\n```\n\n### Dynamic templating\n\nOpenMock leverages [https://golang.org/pkg/text/template/](https://golang.org/pkg/text/template/) to write dynamic templates. Specifically, it supports a lot of _Context_ and _Helper Functions_.\n\n- Usage of `{{ expr }}`. One can put `{{ expr }}` inside three types of places:\n  \n  - `expect.condition`\n  - `action.http.body`, `action.grpc.payload`, `action.kafka.payload`, `action.amqp.payload`\n  - `action.http.body_from_file`, `action.http.body_from_binary_file`, `action.http.binary_file_name` ,`action.grpc.payload_from_file`, `action.kafka.payload_from_file`, `action.amqp.payload_from_file` (`{{ expr }}` will be in the file)\n\n- Use Context inside `{{ expr }}`.\n  \n  ```bash\n  .HTTPHeader      # type: http.Header; example: {{.HTTPHeader.Get \"X-Token\"}}\n  .HTTPBody        # type: string;      example: {{.HTTPBody}}\n  .HTTPPath        # type: string;      example: {{.HTTPPath}}\n  .HTTPQueryString # type: string;      example: {{.HTTPQueryString}}\n  \n  .GRPCHeader      # type: string;      example: {{.GRPCHeader}}\n  .GRPCPayload     # type: string;      example: {{.GRPCPayload}}\n  .GRPCService     # type: string;      example: {{.GRPCService}}\n  .GRPCMethod      # type: string;      example: {{.GRPCMethod}}\n  \n  .KafkaTopic      # type: string;      example: {{.KafkaTopic}}\n  .KafkaPayload    # type: string;      example: {{.KafkaPayload}}\n  \n  .AMQPExchange    # type: string;      example: {{.AMQPExchange}}\n  .AMQPRoutingKey  # type: string;      example: {{.AMQPRoutingKey}}\n  .AMQPQueue       # type: string;      example: {{.AMQPQueue}}\n  .AMQPPayload     # type: string;      example: {{.AMQPPayload}}\n  ```\n\n- Use helper functions inside `{{ expr }}`. We recommend pipeline format (`|`) of the functions.\n  \n  ```bash\n  # Supported functions defined in ./template_helper.go\n  \n    - \n    - jsonPath    # doc: https://github.com/antchfx/xpath\n    - gJsonPath   # doc: https://github.com/tidwall/gjson\n    - xmlPath     # doc: https://github.com/antchfx/xpath\n    - uuidv5      # uuid v5 sha1 hash\n    - redisDo     # run redis commands. For example {{redisDo \"RPUSH\" \"arr\" \"hi\"}}\n    - ...\n  \n  # Supported functions inherited from\n  # https://github.com/Masterminds/sprig/blob/master/functions.go\n  \n    - replace\n    - uuidv4\n    - regexMatch\n    - ...\n  \n  # Examples\n  {{.HTTPHeader.Get \"X-Token\" | eq \"t1234\"}}\n  {{.HTTPBody | jsonPath \"user/first_name\" | replace \"A\" \"a\" | uuidv5 }}\n  {{.HTTPBody | gJsonPath \"users.0.first_name\" }}\n  {{.HTTPBody | xmlPath \"node1/node2/node3\"}}\n  ```\n\n## Admin Interface\n\nOpenmock also by default provides an API on port 9998 to control the running instance.  See [api documentation](docs/api_docs/bundle.yaml).  You can serve the api documentation by getting [go-swagger](https://github.com/go-swagger/go-swagger) and running:\n\n```\n./swagger serve --host 0.0.0.0 --port 9997 docs/api_docs/bundle.yaml\"\n```\n\n## Command Line Interface\n\nOpenmock has a command-line interface to help with certain tasks interacting with openmock instances. This is \ninvoked with the `omctl` command.  This uses the [cobra](https://github.com/spf13/cobra) library to provide a discoverable CLI; run `omctl` for a list of commands / flags. \n\n### CLI: Directory\n\n#### Push\n\nPushes a local openmock model from the file system to a remote instance.\n\n```\n# Adds templates from the ./demo_templates directory to the instance running on localhost.\nomctl push --directory ./demo_templates --url http://localhost:9998\n```\n\n## Examples\n\n### Example: Mock HTTP\n\n```yaml\n# demo_templates/http.yaml\n\n# $ curl 0:9999/ping\n# OK\n- key: ping\n  kind: Behavior\n  expect:\n    http:\n      method: GET\n      path: /ping\n  actions:\n    - reply_http:\n        status_code: 200\n        body: OK\n        headers:\n          Content-Type: text/html\n\n# $ curl 0:9999/token -H X-Token:t1234 -H Y-Token:t1234\n# OK\n- key: header-token-200\n  kind: Behavior\n  expect:\n    condition: '{{.HTTPHeader.Get \"X-Token\" | eq \"t1234\" | and (.HTTPHeader.Get \"Y-Token\" | eq \"t1234\")}}'\n    http:\n      method: GET\n      path: /token\n  actions:\n    - reply_http:\n        status_code: 200\n        body: OK\n\n# $ curl 0:9999/token\n# Invalid X-Token\n- key: header-token-401\n  kind: Behavior\n  expect:\n    condition: '{{.HTTPHeader.Get \"X-Token\" | ne \"t1234\"}}'\n    http:\n      method: GET\n      path: /token\n  actions:\n    - reply_http:\n        status_code: 401\n        body: Invalid X-Token\n```\n\n### Example: Mock HTTP and reply with binary file\n\n```yaml\n- key: get-pdf\n  expect:\n    http:\n      method: GET\n      path: /api/v1/:ClientID/pdf\n    condition: '{{\n      (.HTTPHeader.Get \"Authorization\" | contains \"exp\") | and\n      (.HTTPHeader.Get \"x-timestamp\" | eq \"\" | not) \n    }}'\n  actions:\n    - reply_http:\n        status_code: 200\n        headers:\n          Content-Type: application/pdf\n        body_from_binary_file: ./data/example.pdf\n        binary_file_name: example_pdf.pdf # optional file name\n```\n\n### \n\n### Example: Mock HTTP and reply with body from file\n\n```yaml\n- key: get-json\n  expect:\n    http:\n      method: GET\n      path: /api/v1/:ClientID/json\n    condition: '{{\n      (.HTTPHeader.Get \"Authorization\" | contains \"exp\") | and\n      (.HTTPHeader.Get \"x-timestamp\" | eq \"\" | not) \n    }}'\n  actions:\n    - reply_http:\n        status_code: 200\n        headers:\n          Content-Type: application/json\n        body_from_file: ./data/example.json # only text files supported\n```\n\n### Example: Mock GRPC\n\n```yaml\n# demo_templates/grpc.yaml\n\n- key: example_grpc\n  expect:\n    grpc:\n      service: demo_protobuf.ExampleService\n      method: ExampleMethod\n  actions:\n    - reply_grpc:\n        payload_from_file: './files/example_grpc_response.json'\n```\n\n### Example: Mock Kafka\n\n```yaml\n# demo_templates/kafka.yaml\n\n- key: test_kafka_1\n  kind: Behavior\n  expect:\n    kafka:\n      topic: hello_kafka_in\n  actions:\n    - publish_kafka:\n        topic: hello_kafka_out\n        payload: \u003e\n          {\n            \"kafka\": \"OK\",\n            \"data\": {}\n          }\n\n- key: test_kafka_2\n  kind: Behavior\n  expect:\n    kafka:\n      topic: hello_kafka_in_2\n  actions:\n    - publish_kafka:\n        topic: hello_kafka_out\n        payload_from_file: './files/colors.json' # the path is relative to OPENMOCK_TEMPLATES_DIR\n```\n\nIf you started the example from docker-compose, you can test the above kafka mocks by using a kt docker container.\n\n```bash\n# Exec into the container\ndocker-compose exec kt bash\n\n# Run some kt commands inside the container\n# Notice that the container is within the docker-compose network, and it connects to \"kafka:9092\"\n\n$ kt topic\n$ echo '{\"123\":\"hi\"}' | kt produce -topic hello_kafka_in -literal\n$ kt consume -topic hello_kafka_out -offsets all=newest:newest\n```\n\n### Example: Mock AMQP (e.g. RabbitMQ)\n\n```yaml\n# demo_templates/amqp.yaml\n\n- key: test_amqp_1\n  kind: Behavior\n  expect:\n    amqp:\n      exchange: exchange_1\n      routing_key: key_in\n      queue: key_in\n  actions:\n    - publish_amqp:\n        exchange: exchange_1\n        routing_key: key_out\n        payload: \u003e\n          {\n            \"amqp\": \"OK\",\n            \"data\": {}\n          }\n\n- key: test_amqp_2\n  kind: Behavior\n  expect:\n    amqp:\n      exchange: exchange_1\n      routing_key: key_in\n      queue: key_in\n  actions:\n    - publish_amqp:\n        exchange: exchange_1\n        routing_key: key_out\n        payload_from_file: './files/colors.json'\n```\n\n### Example: Use Redis for stateful things (by default, OpenMock uses an in-memory miniredis)\n\n```yaml\n# demo_templates/redis.yaml\n\n- key: hello_redis\n  kind: Behavior\n  expect:\n    http:\n      method: GET\n      path: /test_redis\n  actions:\n    - redis:\n      - '{{.HTTPHeader.Get \"X-TOKEN\" | redisDo \"SET\" \"k1\"}}'\n      - '{{redisDo \"RPUSH\" \"random\" uuidv4}}'\n      - '{{redisDo \"RPUSH\" \"random\" uuidv4}}'\n      - '{{redisDo \"RPUSH\" \"random\" uuidv4}}'\n    - reply_http:\n        status_code: 200\n        body: \u003e\n          {\n            \"k1\": \"{{redisDo \"GET\" \"k1\"}}\",\n            \"randomStr\": \"{{redisDo \"LRANGE\" \"random\" 0 -1}}\",\n            \"random\": [\n              {{ $arr := redisDo \"LRANGE\" \"random\" 0 -1 | splitList \";;\" }}\n              {{ range $i, $v := $arr }}\n                {{if isLastIndex $i $arr}}\n                  \"{{$v}}\"\n                {{else}}\n                  \"{{$v}}\",\n                {{end}}\n              {{end}}\n            ]\n          }\n\n# To test\n# curl localhost:9999/test_redis -H \"X-TOKEN:t123\"  | jq .\n```\n\n### Example: Send Webhooks\n\n```yaml\n# demo_templates/webhook.yaml\n\n- key: webhooks\n  kind: Behavior\n  expect:\n    http:\n      method: GET\n      path: /send_webhook_to_httpbin\n  actions:\n    - send_http:\n        url: \"https://httpbin.org/post\"\n        method: POST\n        body: '{\"hello\": \"world\"}'\n        headers:\n          X-Token: t123\n    - reply_http:\n        status_code: 200\n        body: 'webhooks sent'\n\n# To test\n# curl localhost:9999/send_webhook_to_httpbin\n```\n\n### Example: Use data in templates\n\n```yaml\n# demo_templates/http.yaml\n\n- key: http-request-template\n  kind: Template\n  template: \u003e\n    { \"http_path\": \"{{.HTTPPath}}\", \"http_headers\": \"{{.HTTPHeader}}\" }\n\n- key: color-template\n  kind: Template\n  template: \u003e\n    { \"color\": \"{{.color}}\" }\n\n- key: teapot\n  kind: AbstractBehavior\n  expect:\n    http:\n      method: GET\n      path: /teapot\n  actions:\n    - reply_http:\n        status_code: 418\n        body: \u003e\n          {\n            \"request-info\": {{ template \"http-request-template\" . }},\n            \"teapot-info\": {{ template \"color-template\" .Values }}\n          }\n\n# $ curl 0:9999/teapot\n# {   \"request-info\": { \"http_path\": \"/teapot\", \"http_headers\": \"map[Accept:[*/*] User-Agent:[curl/7.54.0]]\" } ,   \"teapot-info\": { \"color\": \"purple\" }  }\n- key: purple-teapot\n  kind: Behavior\n  extend: teapot\n  values:\n    color: purple\n```\n\n# Advanced pipeline functions\n\nTo enable advanced mocks, for example, your own encoding/decoding of the kafka messages,\none can develop by directly importing the `github.com/checkr/openmock` package, making a copy of the swagger-generated server main, and passing in a custom OpenMock.\n\nFor example:\n(see [example](https://github.com/sesquipedalian-dev/openmock-custom-example/blob/master/main.go))\n\n```go\npackage main\n\nimport (\n  \"github.com/checkr/openmock\"\n  \"github.com/checkr/openmock/swagger_gen/restapi\"\n  \"github.com/checkr/openmock/swagger_gen/restapi/operations\"\n  /// etc\n)\n\nfunc consumePipelineFunc(c openmock.Context, in []byte) (out []byte, error) {\n  return decode(in), nil\n}\n\nfunc main() {\n  // server set up copy \u0026 paste...\n\n  // add our custom openmock functionality\n  om := \u0026openmock.OpenMock{}\n  om.ParseEnv()\n  om.KafkaConsumePipelineFunc = consumePipelineFunc\n\n  server.ConfigureAPI(om)\n\n  // rest of server set up copy \u0026 paste...\n}\n```\n\n## GRPC Configuration Notes\n\nOpenMock uses the APIv2 protobuf module (google.golang.org/protobuf). If your project uses the APIv1 protobuf module,\nyou can use https://github.com/golang/protobuf/releases/tag/v1.4.0 and convert your messages to be APIv2 compatible\nwith the `proto.MessageV2` method.\n\nPlease note that OpenMock expects the `payload` or `payload_from_file` for a reply_grpc action to be in the json\nform of your `Response` protobuf message.  The request should be in the `Request` protobuf message format\nas it is parsed into json to support `jsonPath` and `gJsonPath` operations.\n\nExample configuration by directly importing the `github.com/checkr/openmock` package into a wrapper project.\n\n```\nfunc main() {\n  // server set up copy \u0026 paste...\n\n  // add our custom openmock functionality\n  om := \u0026openmock.OpenMock{}\n  om.GRPCServiceMap = map[string]openmock.GRPCService{\n      \"demo_protobuf.ExampleService\": {\n          \"ExampleMethod\": openmock.RequestResponsePair{\n              Request:  proto.MessageV2(\u0026demo_protobuf.ExampleRequest{}),\n              Response: proto.MessageV2(\u0026demo_protobuf.ExampleResponse{}),\n          },\n      },\n  }\n  om.ParseEnv()\n  server.ConfigureAPI(om)\n\n  // rest of server set up copy \u0026 paste...\n```\n\n## Swagger\n\n### Swagger files / directories:\n\n```\nMakefile                    # contains build process for swagger generation\nswagger/                    # directory containing swagger definition, split \n                            # up into a few files\n   index.yaml               # all the model definitions are in here\n   health.yaml              # method definitions relating to e.g. /health\nswagger_gen/                # directory where generated swagger files go\n  restapi/\n    configure_open_mock.go  # this file contains code further customized from the \n                            # generated code to hook an implementation into the API\n                            # the makefiles makes sure it is preserved when \n                            # generating the other files\ndocs/\n  api_docs/\n    bundle.yaml             # combined swagger spec file, generated by Makefile\npkg/\n  admin/                    # code implementing the handlers for the swagger API\n```\n\n### Install Swagger\n\n```\nbrew tap go-swagger/go-swagger\nbrew install go-swagger\n```\n\n### Generate\n\n* `make gen` - bundles the separate swagger files and generates swagger_gen\n* `make build` - builds the executables `om` and `omctl`\n\n### Run\n\n`OPENMOCK_REDIS_TYPE=redis OPENMOCK_REDIS_URL=\u003credis Url, e.g. redis://localhost:6379\u003e OPENMOCK_TEMPLATES_DIR=./demo_templates ./om --port 9998`\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcheckr%2Fopenmock","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fcheckr%2Fopenmock","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcheckr%2Fopenmock/lists"}