Skip to the content.

Muscle and Fitness Server Social Image GitHub release Build Status GitHub issues GitHub forks GitHub stars GitHub license GitHub code size in bytes GitHub repo size Twitter

Muscle and Fitness Server

Muscle and Fitness Server a Spring Cloud microservice based, DDD structured, back-end server for managing data of muscle and fitness.

Official Docker Image

Features

Here is the highlights of Muscle and Fitness Server:

  1. Each microservice is organized by Domain Driven Design (DDD) structure.

  2. Based on Java - and Kotlin - , built by Gradle multi-module management . Inherited from the most modern and newest Spring frameworks:

    org.springframework.boot:spring-boot-starter-parent - Spring Boot org.springframework.cloud:spring-cloud-dependencies - Spring Cloud

  3. Spring Cloud Feature:

    • Consul - Service registration and discovery.
    • Spring Cloud Gateway - API Gateway on top of Spring WebFlux. Provide a simple, yet effective way to route to APIs and provide cross cutting concerns to them such as: security, monitoring/metrics, and resiliency.
    • Spring Cloud OpenFeign - Declarative REST Client: Feign creates a dynamic implementation of an interface decorated with JAX-RS or Spring MVC annotations. Enhanced connection by Okhttp 3.
    • Spring Boot Admin - Admin UI for administration of spring boot applications.
    • Zipkin - a distributed tracing system. It helps gather timing data needed to troubleshoot latency problems in service architectures.
  4. Customized Spring Cloud Starter for traditional Spring MVC and Reactive Spring WebFlux microservice. Encapsulated a bunch of libraries and dependencies. Developer can import those dependencies by demand.

  5. Advocate 𝛌 Java Functional Programming, provide developers with powerful and useful functions to make Java more sweeter.

  6. Secured API. RBAC by API gateway and Auth Center. JWT authentication, and RBAC authorization.

  7. MySQL Replication for High Availability. ShardingSphere as database access middleware to boost the database capacity better.

  8. Redis 6.x support. Master-slave replication for high availability. Redis cluster.

  9. Docker, Rancher Kubernetes support. Google JIB for building production-ready Docker container images.

  10. OSS service, based on Minio and SFTP integration. Asynchronous Progressive Download resources. Chunked resource upload. The media player will play back that content using sequential byte-range requests. Refers to a request for partial content (HTTP 206). This type of request is typically used to retrieve a large asset in smaller segments. This technique is employed by HTTP Progressive Download to avoid long buffering times.

  11. STOMP over WebSocket (SockJS), real time messaging, based on RabbitMQ STOMP message broker.

  12. Messaging with RabbitMQ, also supports delayed message, provided by RabbitMQ Delayed Message Plugin

  13. Quartz support. Distributed job scheduling, based on JDBC. Dynamic Quartz job configuration, served by served by database configuration table quartz_job_configuration. Reduce lots of Quartz job and trigger boilerplate codes.

  14. Multi-environment support.

  15. Knife4j API visualization. Enhanced Swagger API documentation.

  16. Async log output. Log file compressed by standard GNU zip (gzip) compression algorithm. ELK log aggregation.

  17. PMD code quality check for each every CI (during Maven verify phase), with Alibaba-p3c rulesets.

  18. JaCoCo for JUnit code coverage.

  19. JVM log configuration for JVM garbage collection.

  20. AOP based request log, configurable for turning on or off.

  21. Customized method argument validation.

  22. Docker container log persistence, Size and time based rolling policy. Daily rollover (at midnight 12 am) with automatic GZIP compression of the archived files.

  23. Startup and deployment statistics.

  24. Customized startup banner.

Architecture

architectur

Usage

  1. Clone or download this project.

    $ git clone https://github.com/johnnymillergh/muscle-and-fitness-server.git
    
  2. Build with newest IntelliJ IDEA.

  3. Click the green triangle to Run.

Useful Commands

Gradle

  1. Compilation:

    $ gradle classes testClasses
    
  2. Execute unit tests, see also Difference Between Gradle Test and Check:

    $ gradle test
    
  3. Build artifacts:

    $ gradle clean build
    
  4. Build and push Docker images:

    $ gradle clean build jib
    

Maven (deprecated)

  1. Compile:

    $ mvn clean validate compile --batch-mode --show-version --quiet -f pom.xml
    
  2. Package:

    $ mvn clean package -Djunit.jupiter.execution.parallel.enabled=true --batch-mode --show-version --quiet -f pom.xml
    
  3. Set Version:

    $ mvn versions:set -DgenerateBackupPoms=false -f pom.xml
    
  4. Build Docker Images:

    $ mvn clean verify --batch-mode --show-version --quiet -f pom.xml
    

Conventional Changelog CLI

  1. Install global dependencies (optional if installed):

    $ npm install -g conventional-changelog-cli
    
  2. This will not overwrite any previous changelogs. The above generates a changelog based on commits since the last semver tag that matches the pattern of “Feature”, “Fix”, “Performance Improvement” or “Breaking Changes”.

    $ conventional-changelog -p angular -i CHANGELOG.md -s
    
  3. If this is your first time using this tool and you want to generate all previous changelogs, you could do:

    $ conventional-changelog -p angular -i CHANGELOG.md -s -r 0
    

𝛌 Example

  1. Require the expression to be true, otherwise throws an exception (if provided).

    import com.jmsoftware.maf.springcloudstarter.function.*
       
    requireTrue(1 != 1) { anotherBoolean: Boolean? -> log.info("aBoolean = $anotherBoolean") }
        .orElseThrow { IllegalArgumentException("aBoolean is expected to be true") }
    
    import static com.jmsoftware.maf.springcloudstarter.function.BooleanCheck.requireTrue;
       
    requireTrue(1 != 1, anotherBoolean -> log.info("aBoolean = {}", anotherBoolean))
        .orElseThrow(() -> new IllegalArgumentException("aBoolean is expected to be true"));
    
  2. Make Function have cache ability.

    val cacheMap = mutableMapOf("key1" to "1", "key2" to "2")
    val stringProcess = Function { input: String ->
        log.info("No cache return value found. input: $input Re-calculating…")
        StrUtil.subSuf(input, 3)
    }
    val result1 = cacheFunction(stringProcess, "key1", cacheMap)
    val result2 = cacheFunction(stringProcess, "key2", cacheMap)
    val result3 = cacheFunction(stringProcess, "key3", cacheMap)
    assertEquals("1", result1)
    assertEquals("2", result2)
    assertEquals("3", result3)
    assertEquals(3, cacheMap.size)
    
    val cacheMap = Maps.<String, String>newHashMap();
    cacheMap.put("key1", "1");
    cacheMap.put("key2", "2");
    final Function<String, String> stringProcess = input -> {
        log.info("No cache return value found. input: {} Re-calculating…", input);
        return StrUtil.subSuf(input, 3);
    };
    val result1 = cacheFunction(stringProcess, "key1", cacheMap);
    val result2 = cacheFunction(stringProcess, "key2", cacheMap);
    val result3 = cacheFunction(stringProcess, "key3", cacheMap);
    assertEquals("1", result1);
    assertEquals("2", result2);
    assertEquals("3", result3);
    assertEquals(3, cacheMap.size);
    

CI (Continuous Integration)

Maintainers

@johnnymillergh.

Contributing

Feel free to dive in! Open an issue.

Contributors

This project exists thanks to all the people who contribute.

Sponsors

Support this project by becoming a sponsor. Your logo will show up here with a link to your website. [Become a sponsor]

License

Apache License © Johnny Miller

2020 - Present