{"id":21926666,"url":"https://github.com/aatarasoff/spring-cloud-marathon","last_synced_at":"2025-04-19T17:07:46.518Z","repository":{"id":46027419,"uuid":"62820115","full_name":"aatarasoff/spring-cloud-marathon","owner":"aatarasoff","description":"Spring Cloud integration with Mesos and Marathon","archived":false,"fork":false,"pushed_at":"2021-11-19T06:29:11.000Z","size":237,"stargazers_count":29,"open_issues_count":3,"forks_count":12,"subscribers_count":5,"default_branch":"master","last_synced_at":"2025-03-29T10:41:42.520Z","etag":null,"topics":["marathon","mesos","ribbon","service-discovery","spring-boot","spring-boot-starter","spring-cloud"],"latest_commit_sha":null,"homepage":"","language":"Java","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/aatarasoff.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}},"created_at":"2016-07-07T16:02:39.000Z","updated_at":"2022-08-24T06:56:52.000Z","dependencies_parsed_at":"2022-09-14T11:22:27.315Z","dependency_job_id":null,"html_url":"https://github.com/aatarasoff/spring-cloud-marathon","commit_stats":null,"previous_names":[],"tags_count":13,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aatarasoff%2Fspring-cloud-marathon","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aatarasoff%2Fspring-cloud-marathon/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aatarasoff%2Fspring-cloud-marathon/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aatarasoff%2Fspring-cloud-marathon/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/aatarasoff","download_url":"https://codeload.github.com/aatarasoff/spring-cloud-marathon/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":249745836,"owners_count":21319581,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","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":["marathon","mesos","ribbon","service-discovery","spring-boot","spring-boot-starter","spring-cloud"],"created_at":"2024-11-28T22:10:07.221Z","updated_at":"2025-04-19T17:07:46.490Z","avatar_url":"https://github.com/aatarasoff.png","language":"Java","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Spring Cloud Marathon\n\n[![Join the chat at https://gitter.im/aatarasoff/spring-cloud-marathon](https://badges.gitter.im/aatarasoff/spring-cloud-marathon.svg)](https://gitter.im/aatarasoff/spring-cloud-marathon?utm_source=badge\u0026utm_medium=badge\u0026utm_campaign=pr-badge\u0026utm_content=badge) [![Build Status](https://travis-ci.org/aatarasoff/spring-cloud-marathon.svg?branch=master)](https://travis-ci.org/aatarasoff/spring-cloud-marathon) [![Coverage Status](https://coveralls.io/repos/github/aatarasoff/spring-cloud-marathon/badge.svg?branch=master)](https://coveralls.io/github/aatarasoff/spring-cloud-marathon?branch=master)\n\nThis project helps with integration between [Spring Cloud](http://projects.spring.io/spring-cloud/) and [Marathon framework](https://mesosphere.github.io/marathon/) for [Apache Mesos](http://mesos.apache.org/)\n\n## How to connect the project\n\nAdd `jcenter` repository:\n```groovy\nrepositories {\n    jcenter()\n}\n```\n\nor for maven:\n```xml\n\u003crepositories\u003e\n    \u003crepository\u003e\n        \u003cid\u003ejcenter\u003c/id\u003e\n        \u003curl\u003ehttp://jcenter.bintray.com/\u003c/url\u003e\n    \u003c/repository\u003e\n\u003c/repositories\u003e\n```\n\nAnd add dependency with latest version (or feel free to choose specific)\n```groovy\ncompile 'info.developerblog.spring.cloud:spring-cloud-marathon-starter:+'\n```\n\nor for maven:\n```xml\n\u003cdependency\u003e\n    \u003cgroupId\u003einfo.developerblog.spring.cloud\u003c/groupId\u003e\n    \u003cartifactId\u003espring-cloud-marathon-starter\u003c/artifactId\u003e\n    \u003cversion\u003ex.y.z\u003c/version\u003e\n\u003c/dependency\u003e\n```\n\n## Motivation\n\nMesos and Marathon helps you to orchestrate microservices or other artifacts in distributed systems. In fact Marathon keeps information about current configuration including location of service, its healhchecks etc. So, do we need third-party system that keeps configuration and provides service discovery features? If you don't have any serious reason the answer will be \"No\".\n\n## Supported Spring Cloud patterns\n\n`DiscoveryClient` implementation (supports Ribbon, Feign and Zuul).\n\n`Client Load Balancing` with Ribbon and Hystrix.\n\nOther distributed systems patterns from Spring Cloud.\n\n## Marathon configuration\n\nAll configuration should be provided in `bootstrap.yml`\n\n### Development mode (without Marathon)\n\n```yaml\nspring.cloud.marathon.enabled: false\n```\n\n### Standalone mode (single-host Marathon)\n\n```yaml\nspring:\n    cloud:\n        marathon:\n            scheme: http       #url scheme\n            host: marathon     #marathon host\n            port: 8080         #marathon port\n```\n\n### Production mode\n\nAuthentication via Marathon, providing a list of marathon masters:\n```yaml\nspring:\n    cloud:\n        marathon:\n            listOfServers: m1:8080,m2:8080,m3:8080       #list of marathon masters\n            token: \u003cdcos_acs_token\u003e                      #DC/OS HTTP API Token (optional)\n            username: marathon                           #username for basic auth (optional)\n            password: mesos                              #password for basic auth (optional)\n```\n\nor, provide a load balanced marathon endpoint:\n```yaml\nspring:\n    cloud:\n        marathon:\n            endpoint: http://marathon.local:8080         #override scheme+host+port\n            token: \u003cdcos_acs_token\u003e                      #DC/OS HTTP API Token (optional)\n            username: marathon                           #username for basic auth (optional)\n            password: mesos                              #password for basic auth (optional)\n```\n\nOther configuration for services and discovery you can see in [official documentation](http://cloud.spring.io/spring-cloud-static/Camden.SR3/)\n\n### Authentication\n\nSpring Cloud Marathon supports four methods of authentication:\n\n- No Authentication (using Marathon Endpoint)\n- Basic Authentication (using Marathon Endpoint)\n- Token Authentication (using Marathon Endpoint)\n\n#### No Authentication\n\nDo not specify username, password, token or dcosPrivateKey\nSpecify a load balanced endpoint or listOfServers that describe the Marathon Endpoint. e.g.\n\n```yaml\nspring:\n    cloud:\n        marathon:\n            listOfServers: m1:8080,m2:8080,m3:8080      #list of marathon masters\n```\n\n#### Basic Authentication\n\nProvide a username \u0026 password.  Specify an endpoint or listOfServers that describe the Marathon Endpoint. e.g.\n\n```yaml\nspring:\n    cloud:\n        marathon:\n            listOfServers: m1:8080,m2:8080,m3:8080       #list of marathon masters\n            username: marathon                           #username for basic auth (optional)\n            password: mesos                              #password for basic auth (optional)\n```\n\n#### Token Authentication\n\nProvide a HTTP API token (note: tokens expire after 5 days).  Specify a load balanced endpoint or listOfServers that describe the Marathon Endpoint. e.g.\n\n```yaml\nspring:\n    cloud:\n        marathon:\n            listOfServers: m1:8080,m2:8080,m3:8080       #list of marathon masters\n            token: \u003cdcos_acs_token\u003e                      #DC/OS HTTP API Token (optional)\n```\n\n### Services configuration\n\nThere is one specific moment for services notation and their configuration. In Marathon service id has following pattern:\n```text\n/group/path/app\n```\n\nand symbol `/` is not allowed as a virtual host in Feign or RestTemplate. So we cannot use original service id as Spring Cloud service id. Instead of `/` in this implementation other separator: `.` is used. That means that service with id: `/group/path/app` has internal presentation: `group.path.app`.\n\nAnd you should configure them like:\n```yaml\ngroup.path.app:\n    ribbon:\n        \u003cyour settings are here\u003e\n```\n\nIf a specific service cannot be located by the id, then a second lookup is performed for services that contain the given id. e.g.\nA service has been deployed using three different Marathon service ids:\n```text\n/group1/path/app\n/group2/path/app\n/group3/path/app\n```\nA client is configured for the service name only, excluding the group \u0026 path from the id:\n```yaml\napp:\n    ribbon:\n        \u003cyour settings are here\u003e\n```\nService Tasks for all three services will be discovered \u0026 used by ribbon.\n\nSometimes it is useful discover services that are advertising a specific capability; by API version for example:\nThree versions of a service have been deployed, with the following Marathon service ids and labels:\n```text\n/group1/path/app  \"labels\":{ \"API_VERSION\" : \"V1\" }\n/group2/path/app  \"labels\":{ \"API_VERSION\" : \"V2\" }\n/group3/path/app  \"labels\":{ \"API_VERSION\" : \"V2\" }\n```\nA client is configured to expect the \"V2\" API Version:\n```yaml\napp:\n    ribbon:\n        \u003cyour settings are here\u003e\n        MetaDataFilter:\n            API_VERSION: V2\n```\nOnly service instances that contain \"app\" in the service id and have matching labels will be discovered \u0026 used by ribbon.\n\nWhere multiple values are specified for MetaDataFilter, all values must match service labels before ribbon will use the service instance:\n```yaml\napp:\n    ribbon:\n        \u003cyour settings are here\u003e\n        MetaDataFilter:\n            API_VERSION: V2\n            ENVIRONMENT: UAT\n            APPLICATION_OWNER: fred.bloggs@company.com\n```\n\nCombining the loose service id matching with service label filtering permits us to get creative with service discovery:\n```yaml\ngroup.path:\n    ribbon:\n        \u003cyour settings are here\u003e\n        MetaDataFilter:\n            CUSTOMER_ENTITY: V1\n```\ni.e. select any service deployed to /group/path that supports Version 1 of the Customer Entity\n\nIgnore the service id entirely and only match using service labels:\n```yaml\ncustomer:\n    ribbon:\n      \u003cyour settings here\u003e\n      IgnoreServiceId: true\n      MetaDataFilter:\n        CUSTOMER_ENTITY: V1\n        ENVIRONMENT: UAT\n```\ni.e. select any service in the UAT environment that supports Version 1 of the Customer Entity.  \nNote: The service id of 'customer' is ignored, so all services will be filtered by service label\n\nSpecify equality based selector on service labels\n```yaml\ncustomer:\n    ribbon:\n    \u003cyour settings here\u003e\n    MetaDataFilter:\n      API_VERSION: '!=V3'  # not equal to V3; note: must be quoted to keep yaml happy\n      ENVIRONMENT: '==DEV' # equal to DEV; note: must be quoted to keep yaml happy\n      CUSTOMER_ENTITY: V1  # equal to V1; default is equals\n```\n\nSpecify set based selector on service labels\n```yaml\ncustomer:\n    ribbon:\n    \u003cyour settings here\u003e\n    MetaDataFilter:\n      API_VERSION: in(V1,V2)       # is V1 OR is V2\n      ENVIRONMENT: notin(UAT,PROD) # is not UAT AND is not PROD\n```\n\n#### Zones\nZones support is provided by fetching them from instance's hostname. For example, mesos slaves have hostname like following:\n```text\nslave1.dc1\nslave2.dc1\nslave1.dc2\n...\n```\nThere is regexp pattern `.+\\.(.+)` for fetching zone (or datacenter) exists. So, you could define it in service configuration:\n```yaml\ncustomer:\n    ribbon:\n      \u003cyour settings here\u003e\n      ZonePattern: '.+\\.(.+)'\n```\nFinally, you should define zone for app:\n```yaml\nspring.cloud.marathon.discovery.zone: dc1\n```\nAnd then different zone-aware filters and rules will be applied.\n\n## Running the example\n\nBuild sample application docker image:\n```bash\n./gradlew dockerBuild\n```\n\nInstall native docker on Linux or docker for MacOS X or Windows and run `docker-compose` for local environment deployment with zookeeper, mesos and marathon:\n```bash\ndocker-compose up -d\n```\n\nAdd following record into your `/etc/hosts` file:\n```bash\n127.0.0.1 mesos-slave.dc1\n127.0.0.1 mesos-slave.dc2\n```\n\nThen upload `test-marathon-app-manifest.json` as application manifest:\n```bash\ncurl -XPOST http://\u003cmarathon_host\u003e:8080/v2/apps?force=true -H \"Content-Type: application/json\" --data-binary @test-marathon-app-manifest.json -v\n```\n\nand run the example application:\n```bash\n./gradlew bootRun\n```\n\nNow you may test application by curl:\n```bash\ncurl localhost:9090/instances\ncurl localhost:9090/feign\n```\n\n## Enjoy!\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Faatarasoff%2Fspring-cloud-marathon","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Faatarasoff%2Fspring-cloud-marathon","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Faatarasoff%2Fspring-cloud-marathon/lists"}