├── .gitattributes ├── .gitignore ├── .idea ├── .gitignore ├── compiler.xml ├── fastcampus-spring-cloud.iml ├── jarRepositories.xml ├── misc.xml ├── modules.xml ├── modules │ └── fastcam-spring-config │ │ ├── fastcampus-spring-cloud.fastcam-spring-config.iml │ │ ├── fastcampus-spring-cloud.fastcam-spring-config.main.iml │ │ └── fastcampus-spring-cloud.fastcam-spring-config.test.iml └── vcs.xml ├── fastcam-feignclient ├── build.gradle.kts ├── gradlew ├── gradlew.bat └── src │ ├── main │ ├── java │ │ └── info │ │ │ └── thecodinglive │ │ │ └── feignclient │ │ │ ├── FeignApp.java │ │ │ ├── config │ │ │ ├── ConfigController.java │ │ │ ├── ConfigProp.java │ │ │ ├── EurekaFeignClientConfig.java │ │ │ └── MapServiceFeignClientConfig.java │ │ │ ├── eureka │ │ │ └── PhotoAppController.java │ │ │ └── mapService │ │ │ ├── KakaoLocalSearchClient.java │ │ │ ├── LocalSearchResponse.java │ │ │ ├── LocalSearchResponseWrapper.java │ │ │ └── LocalSearchService.java │ └── resources │ │ └── application.yml │ └── test │ └── java │ └── info │ └── thecodinglive │ └── feignClient │ └── mapService │ ├── KakoLocalSearchTest.java │ └── MapServiceTest.java ├── fastcam-photoapp ├── .gitignore ├── build.gradle.kts ├── gradle │ └── wrapper │ │ ├── gradle-wrapper.jar │ │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat ├── lombok.config └── src │ ├── main │ ├── java │ │ └── info │ │ │ └── thecodinglive │ │ │ └── photoapp │ │ │ ├── PhotoApp.java │ │ │ ├── api │ │ │ ├── FeignController.java │ │ │ ├── MDCLogFilter.java │ │ │ └── post │ │ │ │ ├── Content.java │ │ │ │ ├── HeadController.java │ │ │ │ ├── MdcController.java │ │ │ │ ├── NewServiceController.java │ │ │ │ ├── PostImage.java │ │ │ │ └── PostReadController.java │ │ │ ├── circuit │ │ │ ├── InternalServerErrorException.java │ │ │ └── MessageController.java │ │ │ ├── config │ │ │ ├── MDCKeys.java │ │ │ ├── MutlpartConfig.java │ │ │ ├── PhotoAppProperties.java │ │ │ ├── SwaggerConfig.java │ │ │ └── WebConfig.java │ │ │ └── storage │ │ │ ├── FastcamJacksonConverter.java │ │ │ ├── FileUploadController.java │ │ │ ├── FileUploadService.java │ │ │ ├── FileWriter.java │ │ │ ├── ImageFile.java │ │ │ ├── ImageFileUploadResult.java │ │ │ └── gcp │ │ │ ├── GCPStorageComponent.java │ │ │ ├── GcpFileDownloadController.java │ │ │ ├── GcpFileUploadController.java │ │ │ └── GcpStorageService.java │ └── resources │ │ ├── admin.yml │ │ ├── application.yml │ │ ├── test-down.jpg │ │ └── test.jpg │ └── test │ └── java │ └── info │ └── thecodinglive │ └── photoapp │ ├── DateFormatTest.java │ └── GcpStorageServiceTest.java ├── fastcam-resilience4j-server ├── build.gradle.kts ├── gradlew ├── gradlew.bat └── src │ └── main │ ├── java │ └── info │ │ └── thecodinglive │ │ └── resilience4j │ │ └── provide │ │ ├── ProvideApp.java │ │ └── service │ │ ├── BulkHeadController.java │ │ ├── CircuitController.java │ │ └── InternalServerErrorException.java │ └── resources │ └── application.yml ├── fastcam-resilience4j ├── build.gradle.kts ├── docker │ ├── dashboard.json │ ├── docker-compose.yml │ ├── grafana.env │ └── prometheus.yml ├── gradlew ├── gradlew.bat └── src │ └── main │ ├── java │ └── info │ │ └── thecodinglive │ │ └── resilience4j │ │ ├── ResilienceApp.java │ │ ├── config │ │ ├── CircuitConfig.java │ │ └── WebConfig.java │ │ └── service │ │ ├── BulkHeadController.java │ │ └── circuit │ │ ├── CircuitAnnotationService.java │ │ ├── CircuitController.java │ │ ├── HttpBinService.java │ │ └── MyException.java │ └── resources │ └── application.yml ├── fastcam-spring-admin ├── build.gradle.kts ├── gradlew ├── gradlew.bat └── src │ └── main │ ├── java │ └── info │ │ └── thecodinglive │ │ └── admin │ │ └── AdminServerApp.java │ └── resources │ ├── application.yml │ └── eureka-client.yml ├── fastcam-spring-apigw ├── build.gradle.kts ├── gradlew ├── gradlew.bat ├── out │ └── production │ │ └── resources │ │ ├── api-gw.yml │ │ ├── application.yml │ │ └── eureka-client.yml └── src │ └── main │ ├── java │ └── info │ │ └── thecodinglive │ │ └── spgw │ │ ├── SpGwApp.java │ │ └── filters │ │ └── errors │ │ ├── GWErrorResponse.java │ │ └── GlobalExceptionHandler.java │ └── resources │ ├── api-gw.yml │ ├── application.yml │ └── eureka-client.yml ├── fastcam-spring-config-consumer ├── build.gradle.kts ├── gradlew ├── gradlew.bat └── src │ └── main │ ├── java │ └── info │ │ └── thecodinglive │ │ └── cloud │ │ ├── ConfigConsumerApp.java │ │ └── config │ │ ├── ConfigChangeListener.java │ │ ├── ConfigController.java │ │ ├── ConfigMgmt.java │ │ ├── ConfigProp.java │ │ └── TestController.java │ └── resources │ ├── application.yml │ └── bootstrap.yml ├── fastcam-spring-config ├── build.gradle.kts ├── gradlew ├── gradlew.bat ├── out │ └── production │ │ └── resources │ │ ├── app12.yml │ │ ├── application.properties │ │ ├── application.yml │ │ └── config │ │ ├── mongo-dev.yml │ │ └── mongo-real.yml └── src │ └── main │ ├── java │ └── info │ │ └── thecodinglive │ │ └── cloud │ │ └── ConfigServer.java │ └── resources │ ├── application.yml │ └── config │ ├── mongo-default.yml │ ├── mongo-dev.yml │ └── mongo-real.yml ├── fastcam-spring-eureka ├── build.gradle.kts ├── gradlew ├── gradlew.bat └── src │ └── main │ ├── java │ └── info │ │ └── thecodinglive │ │ └── eureka │ │ └── EurekaServerApp.java │ └── resources │ └── application.yml ├── fastcam-spring-kafka ├── build.gradle.kts ├── docker │ └── docker-compose.yml ├── gradlew ├── gradlew.bat ├── out │ └── production │ │ └── resources │ │ └── application.yml └── src │ ├── main │ ├── java │ │ └── info │ │ │ └── thecodinglive │ │ │ └── kafka │ │ │ ├── KafkaApp.java │ │ │ ├── eventService │ │ │ ├── EventController.java │ │ │ ├── FastcamJacksonConverter.java │ │ │ ├── MyEvent.java │ │ │ └── MyEventService.java │ │ │ ├── receiver │ │ │ └── KafkaReceiver.java │ │ │ └── sender │ │ │ └── KafkaProducer.java │ └── resources │ │ └── application.yml │ └── test │ └── java │ └── info │ └── thecodinglive │ └── kafka │ └── SenderTest.java ├── fastcam-spring-rabbitmq ├── build.gradle.kts ├── docker │ └── docker-compose.yml ├── gradlew ├── gradlew.bat ├── lombok.config ├── out │ └── production │ │ └── resources │ │ ├── application.yml │ │ └── docker │ │ └── docker-compose.yml └── src │ ├── main │ ├── java │ │ └── info │ │ │ └── thecodinglive │ │ │ └── rabbitmq │ │ │ ├── RabbitMQApp.java │ │ │ ├── config │ │ │ ├── FastcamRabbitQueue.java │ │ │ └── RabbitMQConfig.java │ │ │ ├── receiver │ │ │ └── RabbitMQReceiver.java │ │ │ ├── sample │ │ │ └── model │ │ │ │ └── MyTask.java │ │ │ └── sender │ │ │ ├── MessageController.java │ │ │ └── RabbitMessagePublisher.java │ └── resources │ │ ├── application.yml │ │ └── docker │ │ └── docker-compose.yml │ └── test │ └── java │ └── info │ └── thecodinglive │ └── rabbitmq │ └── sender │ └── RabbitMQSenderTest.java ├── fastcam-spring-sleuth ├── build.gradle.kts ├── gradlew ├── gradlew.bat └── src │ └── main │ ├── java │ └── info │ │ └── thecodinglive │ │ └── monitoring │ │ ├── SpringSleuth.java │ │ ├── config │ │ └── SleuthConfig.java │ │ └── sleuth │ │ └── TestController.java │ └── resources │ └── application.yml ├── fastcam-spring-utils ├── build.gradle.kts ├── gradlew ├── gradlew.bat └── src │ └── main │ └── java │ └── info │ └── thecodinglive │ └── utils │ └── jackson │ └── FastcamJacksonConverter.java ├── fastcam-spring-vault ├── build.gradle.kts ├── gradlew ├── gradlew.bat └── src │ └── main │ ├── java │ └── info │ │ └── thecodinglive │ │ └── cloud │ │ ├── app │ │ └── SpringVaultApp.java │ │ └── config │ │ └── MySqlConfig.java │ └── resources │ ├── application.yml │ ├── bootstrap.yml │ └── config │ ├── mongo-default.yml │ ├── mongo-dev.yml │ └── mongo-real.yml ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat ├── readme.md └── settings.gradle.kts /.gitattributes: -------------------------------------------------------------------------------- 1 | # 2 | # https://help.github.com/articles/dealing-with-line-endings/ 3 | # 4 | # These are explicitly windows files and should use crlf 5 | *.bat text eol=crlf 6 | 7 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | ### Java template 2 | *.class 3 | 4 | # Mobile Tools for Java (J2ME) 5 | .mtj.tmp/ 6 | 7 | # Package Files # 8 | *.jar 9 | *.war 10 | *.ear 11 | 12 | # virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml 13 | hs_err_pid* 14 | ### JetBrains template 15 | # Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio 16 | 17 | *.iml 18 | 19 | ## Directory-based project format: 20 | .idea/ 21 | # if you remove the above rule, at least ignore the following: 22 | 23 | # User-specific stuff: 24 | # .idea/workspace.xml 25 | # .idea/tasks.xml 26 | # .idea/dictionaries 27 | 28 | # Sensitive or high-churn files: 29 | # .idea/dataSources.ids 30 | # .idea/dataSources.xml 31 | # .idea/sqlDataSources.xml 32 | # .idea/dynamic.xml 33 | # .idea/uiDesigner.xml 34 | 35 | # Gradle: 36 | # .idea/gradle.xml 37 | # .idea/libraries 38 | 39 | # Mongo Explorer plugin: 40 | # .idea/mongoSettings.xml 41 | 42 | ## File-based project format: 43 | *.ipr 44 | *.iws 45 | 46 | ## Plugin-specific files: 47 | 48 | # IntelliJ 49 | out/ 50 | 51 | # mpeltonen/sbt-idea plugin 52 | .idea_modules/ 53 | 54 | # JIRA plugin 55 | atlassian-ide-plugin.xml 56 | 57 | # Crashlytics plugin (for Android Studio and IntelliJ) 58 | com_crashlytics_export_strings.xml 59 | crashlytics.properties 60 | crashlytics-build.properties 61 | <<<<<<< HEAD 62 | ### Gradle template 63 | ======= 64 | fabric.properties 65 | 66 | # Editor-based Rest Client 67 | .idea/httpRequests 68 | 69 | # Android studio 3.1+ serialized cache file 70 | .idea/caches/build_file_checksums.ser 71 | 72 | ### Intellij Patch ### 73 | # Comment Reason: https://github.com/joeblau/gitignore.io/issues/186#issuecomment-215987721 74 | 75 | *.iml 76 | modules.xml 77 | .idea/misc.xml 78 | *.ipr 79 | 80 | # Sonarlint plugin 81 | # https://plugins.jetbrains.com/plugin/7973-sonarlint 82 | .idea/**/sonarlint/ 83 | 84 | # SonarQube Plugin 85 | # https://plugins.jetbrains.com/plugin/7238-sonarqube-community-plugin 86 | .idea/**/sonarIssues.xml 87 | 88 | # Markdown Navigator plugin 89 | # https://plugins.jetbrains.com/plugin/7896-markdown-navigator-enhanced 90 | .idea/**/markdown-navigator.xml 91 | .idea/**/markdown-navigator-enh.xml 92 | .idea/**/markdown-navigator/ 93 | 94 | # Cache file creation bug 95 | # See https://youtrack.jetbrains.com/issue/JBR-2257 96 | .idea/$CACHE_FILE$ 97 | 98 | # CodeStream plugin 99 | # https://plugins.jetbrains.com/plugin/12206-codestream 100 | .idea/codestream.xml 101 | 102 | ### Java ### 103 | # Compiled class file 104 | *.class 105 | 106 | # Log file 107 | *.log 108 | 109 | # BlueJ files 110 | *.ctxt 111 | 112 | # Mobile Tools for Java (J2ME) 113 | .mtj.tmp/ 114 | 115 | # Package Files # 116 | *.jar 117 | *.war 118 | *.nar 119 | *.ear 120 | *.zip 121 | *.tar.gz 122 | *.rar 123 | 124 | # virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml 125 | hs_err_pid* 126 | 127 | ### Gradle ### 128 | >>>>>>> spring-admin 129 | .gradle 130 | build/ 131 | 132 | # Ignore Gradle GUI config 133 | gradle-app.setting 134 | 135 | # Avoid ignoring Gradle wrapper jar file (.jar files are usually ignored) 136 | !gradle-wrapper.jar 137 | ### Eclipse template 138 | *.pydevproject 139 | .metadata 140 | .gradle 141 | bin/ 142 | tmp/ 143 | *.tmp 144 | *.bak 145 | *.swp 146 | *~.nib 147 | local.properties 148 | .settings/ 149 | .loadpath 150 | 151 | # Eclipse Core 152 | .project 153 | 154 | # External tool builders 155 | .externalToolBuilders/ 156 | 157 | # Locally stored "Eclipse launch configurations" 158 | *.launch 159 | 160 | # CDT-specific 161 | .cproject 162 | 163 | # JDT-specific (Eclipse Java Development Tools) 164 | .classpath 165 | 166 | # Java annotation processor (APT) 167 | .factorypath 168 | 169 | # PDT-specific 170 | .buildpath 171 | 172 | # sbteclipse plugin 173 | .target 174 | 175 | # TeXlipse plugin 176 | .texlipse 177 | 178 | # Created by .ignore support plugin (hsz.mobi) -------------------------------------------------------------------------------- /.idea/.gitignore: -------------------------------------------------------------------------------- 1 | # Default ignored files 2 | /shelf/ 3 | /workspace.xml 4 | -------------------------------------------------------------------------------- /.idea/compiler.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /.idea/fastcampus-spring-cloud.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /.idea/jarRepositories.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 9 | 10 | 14 | 15 | 19 | 20 | 24 | 25 | -------------------------------------------------------------------------------- /.idea/misc.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /.idea/modules.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /.idea/modules/fastcam-spring-config/fastcampus-spring-cloud.fastcam-spring-config.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /.idea/vcs.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /fastcam-feignclient/build.gradle.kts: -------------------------------------------------------------------------------- 1 | import org.jetbrains.kotlin.gradle.tasks.KotlinCompile 2 | 3 | plugins { 4 | id("org.springframework.boot") version "2.4.3" 5 | id("io.spring.dependency-management") version "1.0.11.RELEASE" 6 | kotlin("jvm") version "1.4.30" 7 | kotlin("plugin.spring") version "1.4.30" 8 | } 9 | 10 | group = "info.thecodinglive.feign" 11 | version = "0.0.1-SNAPSHOT" 12 | java.sourceCompatibility = JavaVersion.VERSION_11 13 | 14 | configurations { 15 | compileOnly { 16 | extendsFrom(configurations.annotationProcessor.get()) 17 | } 18 | } 19 | 20 | repositories { 21 | jcenter() 22 | } 23 | 24 | dependencies { 25 | implementation("org.springframework.boot:spring-boot-starter-web") 26 | implementation("org.springframework.cloud:spring-cloud-starter-openfeign") 27 | 28 | implementation("org.springframework.cloud:spring-cloud-config-client") 29 | implementation("org.springframework.cloud:spring-cloud-starter-bootstrap") 30 | implementation("org.springframework.boot:spring-boot-starter-actuator") 31 | 32 | compileOnly("org.projectlombok:lombok") 33 | annotationProcessor("org.projectlombok:lombok") 34 | 35 | 36 | implementation("org.springframework.cloud:spring-cloud-starter-netflix-eureka-client") 37 | //test 38 | 39 | testImplementation("org.springframework.boot:spring-boot-starter-test") 40 | } 41 | 42 | dependencyManagement { 43 | imports { 44 | mavenBom ("org.springframework.cloud:spring-cloud-dependencies:2020.0.1") 45 | } 46 | } 47 | 48 | 49 | tasks.withType { 50 | kotlinOptions { 51 | freeCompilerArgs = listOf("-Xjsr305=strict") 52 | jvmTarget = "11" 53 | } 54 | } 55 | 56 | tasks.withType { 57 | useJUnitPlatform() 58 | } 59 | -------------------------------------------------------------------------------- /fastcam-feignclient/gradlew.bat: -------------------------------------------------------------------------------- 1 | @rem 2 | @rem Copyright 2015 the original author or authors. 3 | @rem 4 | @rem Licensed under the Apache License, Version 2.0 (the "License"); 5 | @rem you may not use this file except in compliance with the License. 6 | @rem You may obtain a copy of the License at 7 | @rem 8 | @rem https://www.apache.org/licenses/LICENSE-2.0 9 | @rem 10 | @rem Unless required by applicable law or agreed to in writing, software 11 | @rem distributed under the License is distributed on an "AS IS" BASIS, 12 | @rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | @rem See the License for the specific language governing permissions and 14 | @rem limitations under the License. 15 | @rem 16 | 17 | @if "%DEBUG%" == "" @echo off 18 | @rem ########################################################################## 19 | @rem 20 | @rem Gradle startup script for Windows 21 | @rem 22 | @rem ########################################################################## 23 | 24 | @rem Set local scope for the variables with windows NT shell 25 | if "%OS%"=="Windows_NT" setlocal 26 | 27 | set DIRNAME=%~dp0 28 | if "%DIRNAME%" == "" set DIRNAME=. 29 | set APP_BASE_NAME=%~n0 30 | set APP_HOME=%DIRNAME% 31 | 32 | @rem Resolve any "." and ".." in APP_HOME to make it shorter. 33 | for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi 34 | 35 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 36 | set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" 37 | 38 | @rem Find java.exe 39 | if defined JAVA_HOME goto findJavaFromJavaHome 40 | 41 | set JAVA_EXE=java.exe 42 | %JAVA_EXE% -version >NUL 2>&1 43 | if "%ERRORLEVEL%" == "0" goto execute 44 | 45 | echo. 46 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 47 | echo. 48 | echo Please set the JAVA_HOME variable in your environment to match the 49 | echo location of your Java installation. 50 | 51 | goto fail 52 | 53 | :findJavaFromJavaHome 54 | set JAVA_HOME=%JAVA_HOME:"=% 55 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe 56 | 57 | if exist "%JAVA_EXE%" goto execute 58 | 59 | echo. 60 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 61 | echo. 62 | echo Please set the JAVA_HOME variable in your environment to match the 63 | echo location of your Java installation. 64 | 65 | goto fail 66 | 67 | :execute 68 | @rem Setup the command line 69 | 70 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar 71 | 72 | 73 | @rem Execute Gradle 74 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* 75 | 76 | :end 77 | @rem End local scope for the variables with windows NT shell 78 | if "%ERRORLEVEL%"=="0" goto mainEnd 79 | 80 | :fail 81 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of 82 | rem the _cmd.exe /c_ return code! 83 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 84 | exit /b 1 85 | 86 | :mainEnd 87 | if "%OS%"=="Windows_NT" endlocal 88 | 89 | :omega 90 | -------------------------------------------------------------------------------- /fastcam-feignclient/src/main/java/info/thecodinglive/feignclient/FeignApp.java: -------------------------------------------------------------------------------- 1 | package info.thecodinglive.feignclient; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.EnableAutoConfiguration; 5 | import org.springframework.boot.autoconfigure.SpringBootApplication; 6 | 7 | import org.springframework.context.annotation.Configuration; 8 | 9 | import org.springframework.cloud.client.discovery.EnableDiscoveryClient; 10 | 11 | 12 | @EnableDiscoveryClient 13 | @SpringBootApplication 14 | public class FeignApp { 15 | public static void main(String ar[]) { 16 | SpringApplication.run(FeignApp.class, ar); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /fastcam-feignclient/src/main/java/info/thecodinglive/feignclient/config/ConfigController.java: -------------------------------------------------------------------------------- 1 | package info.thecodinglive.feignclient.config; 2 | 3 | 4 | import lombok.RequiredArgsConstructor; 5 | import lombok.extern.slf4j.Slf4j; 6 | import org.springframework.beans.factory.annotation.Autowired; 7 | import org.springframework.beans.factory.annotation.Value; 8 | import org.springframework.cloud.context.config.annotation.RefreshScope; 9 | import org.springframework.web.bind.annotation.GetMapping; 10 | import org.springframework.web.bind.annotation.RestController; 11 | 12 | @Slf4j 13 | @RestController 14 | public class ConfigController { 15 | @Autowired 16 | private ConfigProp configProp; 17 | 18 | 19 | @GetMapping("/v1/check/prop") 20 | public String findPropMessage() { 21 | log.info("config:: {}", configProp.toString()); 22 | return "ok"; 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /fastcam-feignclient/src/main/java/info/thecodinglive/feignclient/config/ConfigProp.java: -------------------------------------------------------------------------------- 1 | package info.thecodinglive.feignclient.config; 2 | 3 | import lombok.Data; 4 | import org.springframework.boot.context.properties.ConfigurationProperties; 5 | import org.springframework.boot.context.properties.EnableConfigurationProperties; 6 | import org.springframework.stereotype.Component; 7 | 8 | @Component 9 | @Data 10 | @EnableConfigurationProperties 11 | @ConfigurationProperties(prefix = "mongodbserver") 12 | public class ConfigProp { 13 | private String url; 14 | private String username; 15 | private String password; 16 | } 17 | -------------------------------------------------------------------------------- /fastcam-feignclient/src/main/java/info/thecodinglive/feignclient/config/EurekaFeignClientConfig.java: -------------------------------------------------------------------------------- 1 | package info.thecodinglive.feignclient.config; 2 | 3 | import org.springframework.cloud.openfeign.EnableFeignClients; 4 | import org.springframework.context.annotation.Configuration; 5 | 6 | @Configuration 7 | @EnableFeignClients(basePackages = "info.thecodinglive.feignclient.eureka") 8 | public class EurekaFeignClientConfig { 9 | } 10 | -------------------------------------------------------------------------------- /fastcam-feignclient/src/main/java/info/thecodinglive/feignclient/config/MapServiceFeignClientConfig.java: -------------------------------------------------------------------------------- 1 | package info.thecodinglive.feignclient.config; 2 | 3 | import org.springframework.cloud.openfeign.EnableFeignClients; 4 | import org.springframework.context.annotation.Configuration; 5 | 6 | @Configuration 7 | @EnableFeignClients(basePackages = "info.thecodinglive.feignclient.mapService") 8 | public class MapServiceFeignClientConfig { 9 | } 10 | -------------------------------------------------------------------------------- /fastcam-feignclient/src/main/java/info/thecodinglive/feignclient/eureka/PhotoAppController.java: -------------------------------------------------------------------------------- 1 | package info.thecodinglive.feignclient.eureka; 2 | 3 | import org.springframework.beans.factory.annotation.Autowired; 4 | import org.springframework.cloud.openfeign.FeignClient; 5 | import org.springframework.web.bind.annotation.GetMapping; 6 | import org.springframework.web.bind.annotation.RestController; 7 | 8 | @RestController 9 | public class PhotoAppController { 10 | 11 | @Autowired 12 | PhotoClient photoClient; 13 | 14 | @GetMapping("/photo") 15 | public String findServer() { 16 | return photoClient.sayHello(); 17 | } 18 | 19 | 20 | 21 | @FeignClient("photoapp") //도메인 정보 22 | interface PhotoClient { 23 | @GetMapping("/clients") 24 | String sayHello(); 25 | } 26 | 27 | 28 | } 29 | -------------------------------------------------------------------------------- /fastcam-feignclient/src/main/java/info/thecodinglive/feignclient/mapService/KakaoLocalSearchClient.java: -------------------------------------------------------------------------------- 1 | package info.thecodinglive.feignclient.mapService; 2 | 3 | import org.springframework.cloud.openfeign.FeignClient; 4 | import org.springframework.http.ResponseEntity; 5 | import org.springframework.web.bind.annotation.GetMapping; 6 | import org.springframework.web.bind.annotation.RequestHeader; 7 | import org.springframework.web.bind.annotation.RequestParam; 8 | 9 | @FeignClient(value = "kakao", url = "http://dapi.kakao.com") 10 | /** 11 | * @See https://developers.kakao.com/docs/latest/ko/local/dev-guide 12 | * **/ 13 | public interface KakaoLocalSearchClient { 14 | @GetMapping("/v2/local/search/keyword.json") 15 | ResponseEntity findLocationNotIncludeHeader(String query); //fail not include header 16 | 17 | @GetMapping("/v2/local/search/keyword.json") 18 | ResponseEntity findLocationWithHeader(@RequestHeader("Authorization") String authHeader, 19 | @RequestParam("query") String query); 20 | 21 | @GetMapping("/v2/local/search/keyword.json") 22 | ResponseEntity findLocation(@RequestHeader("Authorization") String authHeader, 23 | @RequestParam("query") String query); 24 | 25 | @GetMapping("/v2/local/search/keyword.json") 26 | ResponseEntity findResponse(@RequestHeader("Authorization") String authHeader, 27 | @RequestParam("query") String query); 28 | } 29 | -------------------------------------------------------------------------------- /fastcam-feignclient/src/main/java/info/thecodinglive/feignclient/mapService/LocalSearchResponse.java: -------------------------------------------------------------------------------- 1 | package info.thecodinglive.feignclient.mapService; 2 | 3 | import com.fasterxml.jackson.annotation.JsonIgnoreProperties; 4 | import com.fasterxml.jackson.annotation.JsonProperty; 5 | 6 | @JsonIgnoreProperties(ignoreUnknown = true) 7 | public class LocalSearchResponse { 8 | private Integer id; 9 | @JsonProperty("address_name") 10 | private String addressName; 11 | @JsonProperty("category_group_name") 12 | private String categoryGroupName; 13 | @JsonProperty("category_group_code") 14 | private String categoryGroupCode; 15 | @JsonProperty("category_name") 16 | private String categoryName; 17 | private String distance; 18 | private String phone; 19 | @JsonProperty("place_name") 20 | private String placeName; 21 | @JsonProperty("place_url") 22 | private String placeUrl; 23 | @JsonProperty("road_address_name") 24 | private String roadAddressName; 25 | private String x; 26 | private String y; 27 | 28 | public LocalSearchResponse() { 29 | } 30 | 31 | public void setId(Integer id) { 32 | this.id = id; 33 | } 34 | 35 | public void setAddressName(String addressName) { 36 | this.addressName = addressName; 37 | } 38 | 39 | public void setCategoryGroupName(String categoryGroupName) { 40 | this.categoryGroupName = categoryGroupName; 41 | } 42 | 43 | public void setCategoryGroupCode(String categoryGroupCode) { 44 | this.categoryGroupCode = categoryGroupCode; 45 | } 46 | 47 | public void setCategoryName(String categoryName) { 48 | this.categoryName = categoryName; 49 | } 50 | 51 | public void setDistance(String distance) { 52 | this.distance = distance; 53 | } 54 | 55 | public void setPhone(String phone) { 56 | this.phone = phone; 57 | } 58 | 59 | public void setPlaceName(String placeName) { 60 | this.placeName = placeName; 61 | } 62 | 63 | public void setPlaceUrl(String placeUrl) { 64 | this.placeUrl = placeUrl; 65 | } 66 | 67 | public void setRoadAddressName(String roadAddressName) { 68 | this.roadAddressName = roadAddressName; 69 | } 70 | 71 | public void setX(String x) { 72 | this.x = x; 73 | } 74 | 75 | public void setY(String y) { 76 | this.y = y; 77 | } 78 | 79 | public Integer getId() { 80 | return id; 81 | } 82 | 83 | public String getAddressName() { 84 | return addressName; 85 | } 86 | 87 | public String getCategoryGroupName() { 88 | return categoryGroupName; 89 | } 90 | 91 | public String getCategoryGroupCode() { 92 | return categoryGroupCode; 93 | } 94 | 95 | public String getCategoryName() { 96 | return categoryName; 97 | } 98 | 99 | public String getDistance() { 100 | return distance; 101 | } 102 | 103 | public String getPhone() { 104 | return phone; 105 | } 106 | 107 | public String getPlaceName() { 108 | return placeName; 109 | } 110 | 111 | public String getPlaceUrl() { 112 | return placeUrl; 113 | } 114 | 115 | public String getRoadAddressName() { 116 | return roadAddressName; 117 | } 118 | 119 | public String getX() { 120 | return x; 121 | } 122 | 123 | public String getY() { 124 | return y; 125 | } 126 | 127 | @Override 128 | public String toString() { 129 | return "LocalSearchResponse{" + 130 | "id=" + id + 131 | ", addressName='" + addressName + '\'' + 132 | ", categoryGroupName='" + categoryGroupName + '\'' + 133 | ", categoryGroupCode='" + categoryGroupCode + '\'' + 134 | ", categoryName='" + categoryName + '\'' + 135 | ", distance='" + distance + '\'' + 136 | ", phone='" + phone + '\'' + 137 | ", placeName='" + placeName + '\'' + 138 | ", placeUrl='" + placeUrl + '\'' + 139 | ", roadAddressName='" + roadAddressName + '\'' + 140 | ", x='" + x + '\'' + 141 | ", y='" + y + '\'' + 142 | '}'; 143 | } 144 | } 145 | -------------------------------------------------------------------------------- /fastcam-feignclient/src/main/java/info/thecodinglive/feignclient/mapService/LocalSearchResponseWrapper.java: -------------------------------------------------------------------------------- 1 | package info.thecodinglive.feignclient.mapService; 2 | 3 | import com.fasterxml.jackson.annotation.JsonProperty; 4 | 5 | import java.util.List; 6 | 7 | public class LocalSearchResponseWrapper { 8 | public LocalSearchResponseWrapper() { 9 | } 10 | 11 | public LocalSearchResponseWrapper(List localSearchResponse, LocalSearchMeta localSearchMeta) { 12 | this.localSearchResponse = localSearchResponse; 13 | this.localSearchMeta = localSearchMeta; 14 | } 15 | 16 | @JsonProperty("documents") 17 | private List localSearchResponse; 18 | @JsonProperty("meta") 19 | private LocalSearchMeta localSearchMeta; 20 | 21 | public List getLocalSearchResponse() { 22 | return localSearchResponse; 23 | } 24 | 25 | public void setLocalSearchResponse(List localSearchResponse) { 26 | this.localSearchResponse = localSearchResponse; 27 | } 28 | 29 | public LocalSearchMeta getLocalSearchMeta() { 30 | return localSearchMeta; 31 | } 32 | 33 | public void setLocalSearchMeta(LocalSearchMeta localSearchMeta) { 34 | this.localSearchMeta = localSearchMeta; 35 | } 36 | 37 | private static class LocalSearchMeta {} 38 | 39 | } 40 | -------------------------------------------------------------------------------- /fastcam-feignclient/src/main/java/info/thecodinglive/feignclient/mapService/LocalSearchService.java: -------------------------------------------------------------------------------- 1 | package info.thecodinglive.feignclient.mapService; 2 | 3 | import org.springframework.http.ResponseEntity; 4 | import org.springframework.stereotype.Service; 5 | 6 | @Service 7 | public class LocalSearchService { 8 | private static final String authKey = "KakaoAK 464b4c25cadd87ca45f1ea99a7822608"; 9 | private KakaoLocalSearchClient kakaoLocalSearchClient; 10 | 11 | public LocalSearchService(KakaoLocalSearchClient kakaoLocalSearchClient) { 12 | this.kakaoLocalSearchClient = kakaoLocalSearchClient; 13 | } 14 | 15 | public ResponseEntity findLocationRetrunMap(String keyword) { 16 | return kakaoLocalSearchClient.findLocation(authKey, keyword); 17 | } 18 | 19 | public ResponseEntity findResponse(String keyword) { 20 | return kakaoLocalSearchClient.findResponse(authKey, keyword); 21 | } 22 | 23 | 24 | 25 | public ResponseEntity findLocaion(String keyword) { 26 | return kakaoLocalSearchClient.findLocationWithHeader(authKey, keyword); 27 | } 28 | 29 | 30 | 31 | } 32 | -------------------------------------------------------------------------------- /fastcam-feignclient/src/main/resources/application.yml: -------------------------------------------------------------------------------- 1 | #https://cloud.spring.io/spring-cloud-netflix/multi/multi_spring-cloud-feign.html#_feign_logging 2 | 3 | feign: 4 | cleint: 5 | config: 6 | default: 7 | connectionTimeout: 1000 8 | readTimeout: 3000 9 | loggerLevel: FULL 10 | logging: 11 | level: 12 | info.thecodinglive.feignclient: debug 13 | 14 | 15 | 16 | server.port: 8083 17 | 18 | spring.config.import: 19 | configserver: http://127.0.0.1:8888 20 | spring.profiles.active: dev 21 | 22 | spring.cloud: 23 | config.enabled: true 24 | config.name: mongo 25 | #import=configserver: http://localhost:8888 26 | #fail-fast: true 27 | 28 | spring.application.name: fastCamFeign 29 | 30 | 31 | 32 | eureka: 33 | client: 34 | serviceUrl: 35 | defaultZone: http://localhost:8761/eureka/ 36 | instance: 37 | leaseRenewalIntervalInSeconds: 10 38 | metadataMap: 39 | instanceId: ${vcap.application.instance_id:${spring.application.name}:${spring.application.instance_id:${server.port}}} 40 | 41 | -------------------------------------------------------------------------------- /fastcam-feignclient/src/test/java/info/thecodinglive/feignClient/mapService/MapServiceTest.java: -------------------------------------------------------------------------------- 1 | package info.thecodinglive.feignClient.mapService; 2 | 3 | import info.thecodinglive.feignclient.mapService.LocalSearchResponse; 4 | import info.thecodinglive.feignclient.mapService.LocalSearchResponseWrapper; 5 | import info.thecodinglive.feignclient.mapService.LocalSearchService; 6 | import org.junit.jupiter.api.Assertions; 7 | import org.junit.jupiter.api.Test; 8 | import org.junit.jupiter.api.extension.ExtendWith; 9 | import org.springframework.beans.factory.annotation.Autowired; 10 | import org.springframework.boot.test.context.SpringBootTest; 11 | import org.springframework.test.context.junit.jupiter.SpringExtension; 12 | 13 | import java.util.List; 14 | import java.util.stream.Collectors; 15 | 16 | @ExtendWith(SpringExtension.class) 17 | @SpringBootTest 18 | public class MapServiceTest { 19 | @Autowired 20 | LocalSearchService localSearchService; 21 | Integer locationId = 26358363; 22 | 23 | @Test 24 | public void localSearch() { 25 | 26 | //given 27 | //12455726 28 | LocalSearchResponse searchRespose = new LocalSearchResponse(); 29 | 30 | LocalSearchResponseWrapper localSearchResponseWrapper = localSearchService 31 | .findLocationRetrunMap("율동공원").getBody(); 32 | 33 | System.out.println( localSearchResponseWrapper.getLocalSearchResponse()); 34 | // 35 | // //when 36 | List localSearchResultList = localSearchResponseWrapper.getLocalSearchResponse().stream() 37 | .filter( p -> p.getId().equals(locationId)) 38 | .collect(Collectors.toList()); 39 | // 40 | Assertions.assertEquals(1, localSearchResultList.size(), "사이즈는 1이어야 합니다."); 41 | 42 | localSearchResultList.forEach( p -> { 43 | searchRespose.setPlaceUrl(p.getPlaceUrl()); 44 | searchRespose.setPhone(p.getPhone()); 45 | }); 46 | 47 | String searchLocationResult = String.format("전화번호: %s, 지도url: %s", searchRespose.getPhone(), 48 | searchRespose.getPlaceUrl()); 49 | 50 | System.out.println(searchLocationResult); 51 | 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /fastcam-photoapp/.gitignore: -------------------------------------------------------------------------------- 1 | HELP.md 2 | .gradle 3 | build/ 4 | !gradle/wrapper/gradle-wrapper.jar 5 | !**/src/main/**/build/ 6 | !**/src/test/**/build/ 7 | 8 | ### STS ### 9 | .apt_generated 10 | .classpath 11 | .factorypath 12 | .project 13 | .settings 14 | .springBeans 15 | .sts4-cache 16 | bin/ 17 | !**/src/main/**/bin/ 18 | !**/src/test/**/bin/ 19 | 20 | ### IntelliJ IDEA ### 21 | .idea 22 | *.iws 23 | *.iml 24 | *.ipr 25 | out/ 26 | !**/src/main/**/out/ 27 | !**/src/test/**/out/ 28 | 29 | ### NetBeans ### 30 | /nbproject/private/ 31 | /nbbuild/ 32 | /dist/ 33 | /nbdist/ 34 | /.nb-gradle/ 35 | 36 | ### VS Code ### 37 | .vscode/ 38 | -------------------------------------------------------------------------------- /fastcam-photoapp/build.gradle.kts: -------------------------------------------------------------------------------- 1 | import org.jetbrains.kotlin.gradle.tasks.KotlinCompile 2 | 3 | plugins { 4 | id("org.springframework.boot") version "2.4.3" 5 | id("io.spring.dependency-management") version "1.0.11.RELEASE" 6 | kotlin("jvm") version "1.4.30" 7 | kotlin("plugin.spring") version "1.4.30" 8 | } 9 | 10 | group = "info.thecodinglive.photoapp" 11 | version = "0.0.1-SNAPSHOT" 12 | java.sourceCompatibility = JavaVersion.VERSION_11 13 | 14 | configurations { 15 | compileOnly { 16 | extendsFrom(configurations.annotationProcessor.get()) 17 | } 18 | } 19 | 20 | repositories { 21 | mavenCentral() 22 | } 23 | 24 | dependencies { 25 | implementation(project(":fastcam-spring-utils")) 26 | implementation("org.springframework.boot:spring-boot-starter-web") 27 | implementation("org.springframework.boot:spring-boot-starter-actuator") 28 | implementation("com.fasterxml.jackson.module:jackson-module-kotlin") 29 | implementation("org.jetbrains.kotlin:kotlin-reflect") 30 | implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk8") 31 | implementation("commons-fileupload:commons-fileupload:1.4") 32 | implementation("io.springfox:springfox-swagger2:2.9.2") 33 | implementation("io.springfox:springfox-swagger-ui:2.9.2") 34 | 35 | implementation ("org.springframework.cloud:spring-cloud-gcp-starter-storage") 36 | 37 | implementation("org.springframework.cloud:spring-cloud-config:3.0.1") 38 | implementation("org.springframework.cloud:spring-cloud-context:3.0.1") 39 | implementation("org.springframework.boot:spring-boot-starter-actuator") 40 | 41 | 42 | implementation("org.springframework.cloud:spring-cloud-starter-netflix-eureka-client") 43 | implementation ("org.springframework.cloud:spring-cloud-gcp-starter-storage") 44 | 45 | implementation("org.springframework.cloud:spring-cloud-starter-sleuth") 46 | implementation("org.springframework.cloud:spring-cloud-sleuth-zipkin") 47 | implementation ("de.codecentric:spring-boot-admin-starter-client:2.4.0") 48 | 49 | 50 | compileOnly("org.projectlombok:lombok") 51 | annotationProcessor("org.projectlombok:lombok") 52 | testImplementation("org.springframework.boot:spring-boot-starter-test") 53 | } 54 | 55 | dependencyManagement { 56 | imports { 57 | mavenBom ("org.springframework.cloud:spring-cloud-dependencies:2020.0.1") 58 | mavenBom ("org.springframework.cloud:spring-cloud-gcp-dependencies:1.2.7.RELEASE") 59 | mavenBom ("org.springframework.cloud:spring-cloud-dependencies:2020.0.1") 60 | } 61 | } 62 | 63 | tasks.withType { 64 | kotlinOptions { 65 | freeCompilerArgs = listOf("-Xjsr305=strict") 66 | jvmTarget = "11" 67 | } 68 | } 69 | 70 | tasks.withType { 71 | useJUnitPlatform() 72 | } -------------------------------------------------------------------------------- /fastcam-photoapp/gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thecodinglive/fastcampus-example/8fc38f151532d7fc4168fd2cbb6e9cf42e9dd472/fastcam-photoapp/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /fastcam-photoapp/gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionBase=GRADLE_USER_HOME 2 | distributionPath=wrapper/dists 3 | distributionUrl=https\://services.gradle.org/distributions/gradle-6.8.2-bin.zip 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | -------------------------------------------------------------------------------- /fastcam-photoapp/gradlew: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env sh 2 | 3 | # 4 | # Copyright 2015 the original author or authors. 5 | # 6 | # Licensed under the Apache License, Version 2.0 (the "License"); 7 | # you may not use this file except in compliance with the License. 8 | # You may obtain a copy of the License at 9 | # 10 | # https://www.apache.org/licenses/LICENSE-2.0 11 | # 12 | # Unless required by applicable law or agreed to in writing, software 13 | # distributed under the License is distributed on an "AS IS" BASIS, 14 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | # See the License for the specific language governing permissions and 16 | # limitations under the License. 17 | # 18 | 19 | ############################################################################## 20 | ## 21 | ## Gradle start up script for UN*X 22 | ## 23 | ############################################################################## 24 | 25 | # Attempt to set APP_HOME 26 | # Resolve links: $0 may be a link 27 | PRG="$0" 28 | # Need this for relative symlinks. 29 | while [ -h "$PRG" ] ; do 30 | ls=`ls -ld "$PRG"` 31 | link=`expr "$ls" : '.*-> \(.*\)$'` 32 | if expr "$link" : '/.*' > /dev/null; then 33 | PRG="$link" 34 | else 35 | PRG=`dirname "$PRG"`"/$link" 36 | fi 37 | done 38 | SAVED="`pwd`" 39 | cd "`dirname \"$PRG\"`/" >/dev/null 40 | APP_HOME="`pwd -P`" 41 | cd "$SAVED" >/dev/null 42 | 43 | APP_NAME="Gradle" 44 | APP_BASE_NAME=`basename "$0"` 45 | 46 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 47 | DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' 48 | 49 | # Use the maximum available, or set MAX_FD != -1 to use that value. 50 | MAX_FD="maximum" 51 | 52 | warn () { 53 | echo "$*" 54 | } 55 | 56 | die () { 57 | echo 58 | echo "$*" 59 | echo 60 | exit 1 61 | } 62 | 63 | # OS specific support (must be 'true' or 'false'). 64 | cygwin=false 65 | msys=false 66 | darwin=false 67 | nonstop=false 68 | case "`uname`" in 69 | CYGWIN* ) 70 | cygwin=true 71 | ;; 72 | Darwin* ) 73 | darwin=true 74 | ;; 75 | MINGW* ) 76 | msys=true 77 | ;; 78 | NONSTOP* ) 79 | nonstop=true 80 | ;; 81 | esac 82 | 83 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar 84 | 85 | 86 | # Determine the Java command to use to start the JVM. 87 | if [ -n "$JAVA_HOME" ] ; then 88 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then 89 | # IBM's JDK on AIX uses strange locations for the executables 90 | JAVACMD="$JAVA_HOME/jre/sh/java" 91 | else 92 | JAVACMD="$JAVA_HOME/bin/java" 93 | fi 94 | if [ ! -x "$JAVACMD" ] ; then 95 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME 96 | 97 | Please set the JAVA_HOME variable in your environment to match the 98 | location of your Java installation." 99 | fi 100 | else 101 | JAVACMD="java" 102 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 103 | 104 | Please set the JAVA_HOME variable in your environment to match the 105 | location of your Java installation." 106 | fi 107 | 108 | # Increase the maximum file descriptors if we can. 109 | if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then 110 | MAX_FD_LIMIT=`ulimit -H -n` 111 | if [ $? -eq 0 ] ; then 112 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then 113 | MAX_FD="$MAX_FD_LIMIT" 114 | fi 115 | ulimit -n $MAX_FD 116 | if [ $? -ne 0 ] ; then 117 | warn "Could not set maximum file descriptor limit: $MAX_FD" 118 | fi 119 | else 120 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" 121 | fi 122 | fi 123 | 124 | # For Darwin, add options to specify how the application appears in the dock 125 | if $darwin; then 126 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" 127 | fi 128 | 129 | # For Cygwin or MSYS, switch paths to Windows format before running java 130 | if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then 131 | APP_HOME=`cygpath --path --mixed "$APP_HOME"` 132 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` 133 | 134 | JAVACMD=`cygpath --unix "$JAVACMD"` 135 | 136 | # We build the pattern for arguments to be converted via cygpath 137 | ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` 138 | SEP="" 139 | for dir in $ROOTDIRSRAW ; do 140 | ROOTDIRS="$ROOTDIRS$SEP$dir" 141 | SEP="|" 142 | done 143 | OURCYGPATTERN="(^($ROOTDIRS))" 144 | # Add a user-defined pattern to the cygpath arguments 145 | if [ "$GRADLE_CYGPATTERN" != "" ] ; then 146 | OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" 147 | fi 148 | # Now convert the arguments - kludge to limit ourselves to /bin/sh 149 | i=0 150 | for arg in "$@" ; do 151 | CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` 152 | CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option 153 | 154 | if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition 155 | eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` 156 | else 157 | eval `echo args$i`="\"$arg\"" 158 | fi 159 | i=`expr $i + 1` 160 | done 161 | case $i in 162 | 0) set -- ;; 163 | 1) set -- "$args0" ;; 164 | 2) set -- "$args0" "$args1" ;; 165 | 3) set -- "$args0" "$args1" "$args2" ;; 166 | 4) set -- "$args0" "$args1" "$args2" "$args3" ;; 167 | 5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; 168 | 6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; 169 | 7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; 170 | 8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; 171 | 9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; 172 | esac 173 | fi 174 | 175 | # Escape application args 176 | save () { 177 | for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done 178 | echo " " 179 | } 180 | APP_ARGS=`save "$@"` 181 | 182 | # Collect all arguments for the java command, following the shell quoting and substitution rules 183 | eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS" 184 | 185 | exec "$JAVACMD" "$@" 186 | -------------------------------------------------------------------------------- /fastcam-photoapp/gradlew.bat: -------------------------------------------------------------------------------- 1 | @rem 2 | @rem Copyright 2015 the original author or authors. 3 | @rem 4 | @rem Licensed under the Apache License, Version 2.0 (the "License"); 5 | @rem you may not use this file except in compliance with the License. 6 | @rem You may obtain a copy of the License at 7 | @rem 8 | @rem https://www.apache.org/licenses/LICENSE-2.0 9 | @rem 10 | @rem Unless required by applicable law or agreed to in writing, software 11 | @rem distributed under the License is distributed on an "AS IS" BASIS, 12 | @rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | @rem See the License for the specific language governing permissions and 14 | @rem limitations under the License. 15 | @rem 16 | 17 | @if "%DEBUG%" == "" @echo off 18 | @rem ########################################################################## 19 | @rem 20 | @rem Gradle startup script for Windows 21 | @rem 22 | @rem ########################################################################## 23 | 24 | @rem Set local scope for the variables with windows NT shell 25 | if "%OS%"=="Windows_NT" setlocal 26 | 27 | set DIRNAME=%~dp0 28 | if "%DIRNAME%" == "" set DIRNAME=. 29 | set APP_BASE_NAME=%~n0 30 | set APP_HOME=%DIRNAME% 31 | 32 | @rem Resolve any "." and ".." in APP_HOME to make it shorter. 33 | for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi 34 | 35 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 36 | set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" 37 | 38 | @rem Find java.exe 39 | if defined JAVA_HOME goto findJavaFromJavaHome 40 | 41 | set JAVA_EXE=java.exe 42 | %JAVA_EXE% -version >NUL 2>&1 43 | if "%ERRORLEVEL%" == "0" goto execute 44 | 45 | echo. 46 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 47 | echo. 48 | echo Please set the JAVA_HOME variable in your environment to match the 49 | echo location of your Java installation. 50 | 51 | goto fail 52 | 53 | :findJavaFromJavaHome 54 | set JAVA_HOME=%JAVA_HOME:"=% 55 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe 56 | 57 | if exist "%JAVA_EXE%" goto execute 58 | 59 | echo. 60 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 61 | echo. 62 | echo Please set the JAVA_HOME variable in your environment to match the 63 | echo location of your Java installation. 64 | 65 | goto fail 66 | 67 | :execute 68 | @rem Setup the command line 69 | 70 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar 71 | 72 | 73 | @rem Execute Gradle 74 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* 75 | 76 | :end 77 | @rem End local scope for the variables with windows NT shell 78 | if "%ERRORLEVEL%"=="0" goto mainEnd 79 | 80 | :fail 81 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of 82 | rem the _cmd.exe /c_ return code! 83 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 84 | exit /b 1 85 | 86 | :mainEnd 87 | if "%OS%"=="Windows_NT" endlocal 88 | 89 | :omega 90 | -------------------------------------------------------------------------------- /fastcam-photoapp/lombok.config: -------------------------------------------------------------------------------- 1 | lombok.log.fieldName = LOG -------------------------------------------------------------------------------- /fastcam-photoapp/src/main/java/info/thecodinglive/photoapp/PhotoApp.java: -------------------------------------------------------------------------------- 1 | package info.thecodinglive.photoapp; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | import org.springframework.cloud.client.discovery.EnableDiscoveryClient; 6 | 7 | @EnableDiscoveryClient 8 | @SpringBootApplication 9 | public class PhotoApp { 10 | public static void main(String ar[]) { 11 | SpringApplication.run(PhotoApp.class, ar); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /fastcam-photoapp/src/main/java/info/thecodinglive/photoapp/api/FeignController.java: -------------------------------------------------------------------------------- 1 | package info.thecodinglive.photoapp.api; 2 | 3 | import org.springframework.beans.factory.annotation.Autowired; 4 | import org.springframework.cloud.client.ServiceInstance; 5 | import org.springframework.cloud.client.discovery.DiscoveryClient; 6 | import org.springframework.web.bind.annotation.GetMapping; 7 | import org.springframework.web.bind.annotation.RestController; 8 | 9 | import java.util.List; 10 | 11 | @RestController 12 | public class FeignController { 13 | @Autowired 14 | DiscoveryClient discoveryClient; 15 | 16 | @GetMapping("/clients") 17 | public String welcome() { 18 | List instances = discoveryClient.getInstances("photoapp"); 19 | ServiceInstance selectedInstance = instances.get(0); 20 | 21 | return "welcome to spring cloud:" + selectedInstance.getInstanceId() + ":" + selectedInstance.getPort(); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /fastcam-photoapp/src/main/java/info/thecodinglive/photoapp/api/MDCLogFilter.java: -------------------------------------------------------------------------------- 1 | package info.thecodinglive.photoapp.api; 2 | 3 | import lombok.extern.slf4j.Slf4j; 4 | import org.slf4j.MDC; 5 | import org.springframework.stereotype.Component; 6 | import org.springframework.util.StringUtils; 7 | 8 | import javax.servlet.*; 9 | import javax.servlet.http.HttpServletRequest; 10 | import java.io.IOException; 11 | import java.util.UUID; 12 | 13 | @Slf4j 14 | public class MDCLogFilter implements Filter { 15 | @Override 16 | public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { 17 | HttpServletRequest req = (HttpServletRequest) request; 18 | 19 | String requestId = UUID.randomUUID().toString(); 20 | String requestUrl = req.getRequestURI(); 21 | String userAgent = req.getHeader("User-Agent"); 22 | String clientIP = getClientIP(req); 23 | 24 | MDC.put("requestId", requestId); 25 | MDC.put("requestUrl", requestUrl); 26 | MDC.put("userAgent", userAgent); 27 | MDC.put("clientIP", clientIP); 28 | 29 | chain.doFilter(req, response); 30 | } 31 | 32 | @Override 33 | public void init(FilterConfig filterConfig) throws ServletException { 34 | LOG.info("MDC filter initialize"); 35 | } 36 | 37 | @Override 38 | public void destroy() { 39 | MDC.clear(); 40 | } 41 | 42 | 43 | private String getClientIP(HttpServletRequest request) { 44 | String ip = request.getHeader("X-Forwarded-For"); 45 | LOG.info("ip: {}", ip); 46 | 47 | if(!StringUtils.hasLength(ip)) { 48 | ip = request.getRemoteAddr(); 49 | } 50 | return ip; 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /fastcam-photoapp/src/main/java/info/thecodinglive/photoapp/api/post/Content.java: -------------------------------------------------------------------------------- 1 | package info.thecodinglive.photoapp.api.post; 2 | 3 | import lombok.*; 4 | import org.springframework.util.Assert; 5 | 6 | 7 | @EqualsAndHashCode 8 | @Getter 9 | @ToString 10 | @Builder 11 | public class Content { 12 | private String contentId; 13 | private String title; 14 | private String body; 15 | private String writerNickName; 16 | private PostImage attachImage; 17 | } 18 | -------------------------------------------------------------------------------- /fastcam-photoapp/src/main/java/info/thecodinglive/photoapp/api/post/HeadController.java: -------------------------------------------------------------------------------- 1 | package info.thecodinglive.photoapp.api.post; 2 | 3 | import lombok.extern.slf4j.Slf4j; 4 | import org.springframework.http.ResponseEntity; 5 | import org.springframework.web.bind.annotation.GetMapping; 6 | import org.springframework.web.bind.annotation.RequestHeader; 7 | import org.springframework.web.bind.annotation.RestController; 8 | 9 | 10 | 11 | @Slf4j 12 | @RestController 13 | public class HeadController { 14 | @GetMapping("/v1.0/headservice") 15 | public ResponseEntity retriveHeadData(@RequestHeader(value = "X-PHOTO-API-VERSION") String apiVersion) { 16 | LOG.info("header data: {}", apiVersion); 17 | return ResponseEntity.ok("ok"); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /fastcam-photoapp/src/main/java/info/thecodinglive/photoapp/api/post/MdcController.java: -------------------------------------------------------------------------------- 1 | package info.thecodinglive.photoapp.api.post; 2 | 3 | import info.thecodinglive.photoapp.config.MDCKeys; 4 | import lombok.extern.slf4j.Slf4j; 5 | import org.slf4j.MDC; 6 | import org.springframework.http.ResponseEntity; 7 | import org.springframework.web.bind.annotation.GetMapping; 8 | import org.springframework.web.bind.annotation.RestController; 9 | 10 | @Slf4j 11 | @RestController 12 | public class MdcController { 13 | @GetMapping("/v1/mdc") 14 | public ResponseEntity getData() { 15 | String requestId = MDC.get(MDCKeys.REQUEST_ID.getPropertyKey()); 16 | String clientIP = MDC.get(MDCKeys.CLIENT_IP.getPropertyKey()); 17 | String userAgent = MDC.get(MDCKeys.USER_AGENT.getPropertyKey()); 18 | 19 | LOG.info("requestId: {} clientIP: {} userAgent {}", requestId, clientIP, userAgent); 20 | 21 | return ResponseEntity.ok("ok"); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /fastcam-photoapp/src/main/java/info/thecodinglive/photoapp/api/post/NewServiceController.java: -------------------------------------------------------------------------------- 1 | package info.thecodinglive.photoapp.api.post; 2 | 3 | import org.springframework.web.bind.annotation.GetMapping; 4 | import org.springframework.web.bind.annotation.RestController; 5 | 6 | @RestController 7 | public class NewServiceController { 8 | @GetMapping("/v1.0/newservice") 9 | public String releaseNewService() { 10 | return "open new service"; 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /fastcam-photoapp/src/main/java/info/thecodinglive/photoapp/api/post/PostImage.java: -------------------------------------------------------------------------------- 1 | package info.thecodinglive.photoapp.api.post; 2 | 3 | import lombok.Builder; 4 | import lombok.Getter; 5 | 6 | @Getter 7 | @Builder 8 | public class PostImage { 9 | private String fileName; 10 | private String path; 11 | private Integer width; 12 | private Integer height; 13 | } 14 | -------------------------------------------------------------------------------- /fastcam-photoapp/src/main/java/info/thecodinglive/photoapp/api/post/PostReadController.java: -------------------------------------------------------------------------------- 1 | package info.thecodinglive.photoapp.api.post; 2 | 3 | import org.springframework.http.ResponseEntity; 4 | import org.springframework.web.bind.annotation.GetMapping; 5 | import org.springframework.web.bind.annotation.PostMapping; 6 | import org.springframework.web.bind.annotation.RequestBody; 7 | import org.springframework.web.bind.annotation.RestController; 8 | 9 | import java.util.UUID; 10 | 11 | @RestController 12 | public class PostReadController { 13 | @GetMapping("/v1.0/contents/1") 14 | public ResponseEntity retriveInMemoryData() { 15 | Content content = Content.builder() 16 | .contentId(UUID.randomUUID().toString()) 17 | .body("get data") 18 | .title("sp gateway test") 19 | .writerNickName("testnick") 20 | .build(); 21 | 22 | return ResponseEntity.ok(content); 23 | } 24 | 25 | @GetMapping("/v1.0/contents/2") 26 | public ResponseEntity throwTimeOut() { 27 | try { 28 | Thread.sleep(1000 * 30); 29 | } catch (Exception e) { 30 | 31 | } 32 | return ResponseEntity.ok("timeout"); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /fastcam-photoapp/src/main/java/info/thecodinglive/photoapp/circuit/InternalServerErrorException.java: -------------------------------------------------------------------------------- 1 | package info.thecodinglive.photoapp.circuit; 2 | 3 | import org.springframework.http.HttpStatus; 4 | import org.springframework.web.bind.annotation.ResponseStatus; 5 | 6 | /** 7 | * InternalServerErrorException 8 | */ 9 | @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR) 10 | public class InternalServerErrorException extends RuntimeException { 11 | 12 | public InternalServerErrorException(String msg) { 13 | super(msg); 14 | } 15 | 16 | } -------------------------------------------------------------------------------- /fastcam-photoapp/src/main/java/info/thecodinglive/photoapp/circuit/MessageController.java: -------------------------------------------------------------------------------- 1 | package info.thecodinglive.photoapp.circuit; 2 | 3 | import org.springframework.web.bind.annotation.GetMapping; 4 | import org.springframework.web.bind.annotation.RestController; 5 | 6 | @RestController 7 | public class MessageController { 8 | private static final int SECOND = 1000; 9 | 10 | @GetMapping("/") 11 | public String okay() { 12 | return "I'm fine."; 13 | } 14 | 15 | @GetMapping("/slow") 16 | public String slow() throws InterruptedException { 17 | Thread.sleep(SECOND); 18 | return "I'm fine, just slow"; 19 | } 20 | 21 | @GetMapping("/error") 22 | public String error() { 23 | throw new InternalServerErrorException("I'm definitely not fine!"); 24 | } 25 | 26 | 27 | } 28 | -------------------------------------------------------------------------------- /fastcam-photoapp/src/main/java/info/thecodinglive/photoapp/config/MDCKeys.java: -------------------------------------------------------------------------------- 1 | package info.thecodinglive.photoapp.config; 2 | 3 | public enum MDCKeys { 4 | /** 5 | * MDC.put("requestId", requestId); 6 | * MDC.put("requestUrl", requestUrl); 7 | * MDC.put("userAgent", userAgent); 8 | * MDC.put("clientIP", clientIP); 9 | */ 10 | 11 | REQUEST_ID("requestId"), 12 | REQUEST_URL("requestUrl"), 13 | USER_AGENT("userAgent"), 14 | CLIENT_IP("clientIP"); 15 | 16 | MDCKeys(String propertyKey) { 17 | this.propertyKey = propertyKey; 18 | } 19 | 20 | public String getPropertyKey() { 21 | return propertyKey; 22 | } 23 | 24 | private String propertyKey; 25 | } 26 | -------------------------------------------------------------------------------- /fastcam-photoapp/src/main/java/info/thecodinglive/photoapp/config/MutlpartConfig.java: -------------------------------------------------------------------------------- 1 | package info.thecodinglive.photoapp.config; 2 | 3 | 4 | import lombok.Getter; 5 | import lombok.extern.slf4j.Slf4j; 6 | import org.springframework.beans.factory.annotation.Value; 7 | import org.springframework.context.annotation.Bean; 8 | import org.springframework.context.annotation.Configuration; 9 | import org.springframework.context.annotation.Profile; 10 | import org.springframework.core.io.FileSystemResource; 11 | import org.springframework.web.multipart.commons.CommonsMultipartResolver; 12 | 13 | import java.io.IOException; 14 | import java.nio.charset.StandardCharsets; 15 | 16 | 17 | @Slf4j 18 | @Configuration 19 | public class MutlpartConfig { 20 | 21 | @Value("${photoapp.file.defaultPath}") 22 | public String defaultPath =""; 23 | 24 | @Bean 25 | public CommonsMultipartResolver multipartResolver() { 26 | CommonsMultipartResolver multipartResolver = new CommonsMultipartResolver(); 27 | multipartResolver.setResolveLazily(true); 28 | multipartResolver.setMaxUploadSize(1024 * 1024 * 10); 29 | multipartResolver.setDefaultEncoding(StandardCharsets.UTF_8.displayName()); 30 | //try { 31 | LOG.info("path:" + defaultPath); 32 | //multipartResolver.setUploadTempDir(new FileSystemResource(defaultPath)); 33 | // } catch (IOException e) { 34 | // LOG.error("init error", e); 35 | //} 36 | return multipartResolver; 37 | } 38 | 39 | 40 | } 41 | -------------------------------------------------------------------------------- /fastcam-photoapp/src/main/java/info/thecodinglive/photoapp/config/PhotoAppProperties.java: -------------------------------------------------------------------------------- 1 | package info.thecodinglive.photoapp.config; 2 | 3 | import lombok.Getter; 4 | import lombok.Setter; 5 | import lombok.extern.slf4j.Slf4j; 6 | import org.springframework.beans.factory.annotation.Value; 7 | import org.springframework.boot.context.properties.ConfigurationProperties; 8 | import org.springframework.context.annotation.Configuration; 9 | 10 | import javax.annotation.PostConstruct; 11 | 12 | @Slf4j 13 | @Configuration 14 | @Setter 15 | @Getter 16 | public class PhotoAppProperties { 17 | @Value("${photoapp.file.defaultPath}") 18 | private String defaultPath; 19 | 20 | @PostConstruct 21 | private void init() { 22 | LOG.info("path:: {}",this.defaultPath); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /fastcam-photoapp/src/main/java/info/thecodinglive/photoapp/config/SwaggerConfig.java: -------------------------------------------------------------------------------- 1 | package info.thecodinglive.photoapp.config; 2 | 3 | import io.swagger.annotations.ApiOperation; 4 | import org.springframework.context.annotation.Bean; 5 | import org.springframework.context.annotation.Configuration; 6 | import org.springframework.http.ResponseEntity; 7 | import springfox.documentation.builders.ApiInfoBuilder; 8 | import springfox.documentation.builders.PathSelectors; 9 | import springfox.documentation.builders.RequestHandlerSelectors; 10 | import springfox.documentation.service.ApiInfo; 11 | import springfox.documentation.spi.DocumentationType; 12 | import springfox.documentation.spring.web.plugins.Docket; 13 | import springfox.documentation.swagger.web.DocExpansion; 14 | import springfox.documentation.swagger.web.ModelRendering; 15 | import springfox.documentation.swagger.web.UiConfiguration; 16 | import springfox.documentation.swagger.web.UiConfigurationBuilder; 17 | import springfox.documentation.swagger2.annotations.EnableSwagger2; 18 | 19 | @Configuration 20 | @EnableSwagger2 21 | public class SwaggerConfig { 22 | @Bean 23 | public UiConfiguration uiConfig() { 24 | return UiConfigurationBuilder.builder() 25 | .deepLinking(true) 26 | .displayOperationId(false) 27 | .defaultModelExpandDepth(3) 28 | .defaultModelExpandDepth(3) 29 | .docExpansion(DocExpansion.LIST) 30 | .displayRequestDuration(false) 31 | .supportedSubmitMethods(UiConfiguration.Constants.DEFAULT_SUBMIT_METHODS) 32 | .validatorUrl(null) 33 | .build(); 34 | } 35 | 36 | @Bean 37 | public Docket api() { 38 | return new Docket(DocumentationType.SWAGGER_2) 39 | .groupName("photo api") 40 | .apiInfo(apiInfo()) 41 | .select() 42 | .apis(RequestHandlerSelectors.withMethodAnnotation(ApiOperation.class)) 43 | .paths(PathSelectors.any()) 44 | .build(); 45 | } 46 | 47 | 48 | private ApiInfo apiInfo() { 49 | return new ApiInfoBuilder() 50 | .title("photo upload api") 51 | .description("사진 업로드 api") 52 | .version("1.0.0") 53 | .build(); 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /fastcam-photoapp/src/main/java/info/thecodinglive/photoapp/config/WebConfig.java: -------------------------------------------------------------------------------- 1 | package info.thecodinglive.photoapp.config; 2 | 3 | import info.thecodinglive.photoapp.api.MDCLogFilter; 4 | import org.springframework.boot.web.servlet.FilterRegistrationBean; 5 | import org.springframework.context.annotation.Bean; 6 | import org.springframework.context.annotation.Configuration; 7 | 8 | import java.util.Arrays; 9 | 10 | @Configuration 11 | public class WebConfig { 12 | @Bean 13 | public FilterRegistrationBean getFilterRegistrationBean() { 14 | FilterRegistrationBean registrationBean = new FilterRegistrationBean(new MDCLogFilter()); 15 | registrationBean.setUrlPatterns(Arrays.asList("/v1/*")); 16 | return registrationBean; 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /fastcam-photoapp/src/main/java/info/thecodinglive/photoapp/storage/FastcamJacksonConverter.java: -------------------------------------------------------------------------------- 1 | package info.thecodinglive.photoapp.storage; 2 | 3 | import com.fasterxml.jackson.annotation.JsonInclude; 4 | import com.fasterxml.jackson.core.type.TypeReference; 5 | import com.fasterxml.jackson.databind.DeserializationFeature; 6 | import com.fasterxml.jackson.databind.ObjectMapper; 7 | import com.fasterxml.jackson.databind.SerializationFeature; 8 | import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule; 9 | 10 | public class FastcamJacksonConverter { 11 | private static final ObjectMapper mapper; 12 | 13 | static { 14 | mapper = new ObjectMapper() 15 | .setSerializationInclusion(JsonInclude.Include.NON_NULL) 16 | .configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false) 17 | .configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false) 18 | .configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false) 19 | .configure(DeserializationFeature.ADJUST_DATES_TO_CONTEXT_TIME_ZONE, false) 20 | .registerModule(new JavaTimeModule()); 21 | } 22 | 23 | private FastcamJacksonConverter() { 24 | throw new RuntimeException("construct not support"); 25 | } 26 | 27 | public static ObjectMapper getInstance() { 28 | return mapper; 29 | } 30 | 31 | public static String toJson(Object value) { 32 | try{ 33 | return mapper.writeValueAsString(value); 34 | } catch (Exception e) { 35 | throw new RuntimeException("convert error"); 36 | } 37 | } 38 | 39 | public static T toObject(String content, Class valueType) { 40 | try { 41 | return mapper.readValue(content, valueType); 42 | } catch (Exception e) { 43 | throw new RuntimeException("convert error"); 44 | } 45 | } 46 | 47 | public static T toObject(String content, TypeReference type) { 48 | try { 49 | return mapper.readValue(content, type); 50 | } catch (Exception e) { 51 | throw new RuntimeException("convert error"); 52 | } 53 | } 54 | 55 | public static T convert(Object obj, Class type) { 56 | try { 57 | return mapper.convertValue(obj, type); 58 | } catch (Exception e) { 59 | throw new RuntimeException("convert error"); 60 | } 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /fastcam-photoapp/src/main/java/info/thecodinglive/photoapp/storage/FileUploadController.java: -------------------------------------------------------------------------------- 1 | package info.thecodinglive.photoapp.storage; 2 | 3 | import io.swagger.annotations.Api; 4 | import io.swagger.annotations.ApiOperation; 5 | import org.springframework.beans.factory.annotation.Autowired; 6 | import org.springframework.web.bind.annotation.PostMapping; 7 | 8 | import org.springframework.web.bind.annotation.RequestParam; 9 | import org.springframework.web.bind.annotation.RequestPart; 10 | import org.springframework.web.bind.annotation.RestController; 11 | import org.springframework.web.multipart.MultipartFile; 12 | 13 | 14 | @Api 15 | @RestController 16 | public class FileUploadController { 17 | 18 | @Autowired 19 | FileUploadService fileUploadService; 20 | 21 | @ApiOperation("이미지 파일 업로드") 22 | @PostMapping("/v1.0/upload/image") 23 | public ImageFileUploadResult transfer( 24 | @RequestParam("userKey") String userKey, 25 | @RequestPart("imageFile") MultipartFile multipartFile) { 26 | ImageFile imageFile = fileUploadService.upload(multipartFile); 27 | return ImageFileUploadResult.builder() 28 | .fileName(imageFile.getFileName()) 29 | .fileId(imageFile.getFileId()) 30 | .fileSize(imageFile.getFileSize()) 31 | .build(); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /fastcam-photoapp/src/main/java/info/thecodinglive/photoapp/storage/FileUploadService.java: -------------------------------------------------------------------------------- 1 | package info.thecodinglive.photoapp.storage; 2 | 3 | import com.fasterxml.jackson.databind.ObjectMapper; 4 | 5 | import lombok.extern.slf4j.Slf4j; 6 | import org.springframework.beans.factory.annotation.Autowired; 7 | import org.springframework.stereotype.Service; 8 | import org.springframework.web.multipart.MultipartFile; 9 | 10 | import javax.servlet.annotation.MultipartConfig; 11 | import java.util.UUID; 12 | 13 | @Slf4j 14 | @Service 15 | public class FileUploadService { 16 | @Autowired 17 | private FileWriter fileWriter; 18 | 19 | public ImageFile upload(MultipartFile sourceFile) { 20 | String fileId = UUID.randomUUID().toString(); 21 | String filePath = fileWriter.getFilePath(fileId, sourceFile); 22 | LOG.info("filePath:: {}", filePath ); 23 | fileWriter.writeFile(sourceFile, filePath); 24 | 25 | return ImageFile.builder() 26 | .fileName(sourceFile.getName()) 27 | .filePath(filePath) 28 | .fileId(fileId) 29 | .fileSize(sourceFile.getSize()) 30 | .build(); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /fastcam-photoapp/src/main/java/info/thecodinglive/photoapp/storage/FileWriter.java: -------------------------------------------------------------------------------- 1 | package info.thecodinglive.photoapp.storage; 2 | 3 | import info.thecodinglive.photoapp.config.PhotoAppProperties; 4 | import lombok.extern.slf4j.Slf4j; 5 | import org.apache.commons.io.FilenameUtils; 6 | import org.springframework.beans.factory.annotation.Autowired; 7 | import org.springframework.stereotype.Service; 8 | import org.springframework.web.multipart.MultipartFile; 9 | 10 | import javax.servlet.annotation.MultipartConfig; 11 | import java.io.File; 12 | import java.io.IOException; 13 | import java.time.LocalDateTime; 14 | import java.time.format.DateTimeFormatter; 15 | 16 | @Slf4j 17 | @Service 18 | public class FileWriter { 19 | @Autowired 20 | PhotoAppProperties photoAppProperties; 21 | 22 | public long writeFile(MultipartFile multipartFile, String filePath) { 23 | try { 24 | multipartFile.transferTo(new File(filePath)); 25 | } catch (IllegalStateException ile) { 26 | throw new RuntimeException("file write error"); 27 | } catch (IOException ioe) { 28 | throw new RuntimeException("ioe error"); 29 | } 30 | return multipartFile.getSize(); 31 | } 32 | 33 | public String getFilePath(String fileId, MultipartFile sourceFile) { 34 | return photoAppProperties.getDefaultPath() +"/" + dateStr() + "/" + fileId + "." + getMimeType(sourceFile.getOriginalFilename()); 35 | } 36 | 37 | 38 | private static String getMimeType(String filePath) { 39 | return FilenameUtils.getExtension(filePath); 40 | } 41 | 42 | public static String dateStr() { 43 | LocalDateTime now = LocalDateTime.now(); 44 | DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyyMMdd"); 45 | return now.format(dateTimeFormatter); 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /fastcam-photoapp/src/main/java/info/thecodinglive/photoapp/storage/ImageFile.java: -------------------------------------------------------------------------------- 1 | package info.thecodinglive.photoapp.storage; 2 | 3 | import lombok.Builder; 4 | import lombok.Getter; 5 | 6 | @Getter 7 | @Builder 8 | public class ImageFile { 9 | private String fileId; 10 | private Long fileSize; 11 | private String fileName; 12 | private String fileType; 13 | private String filePath; 14 | } 15 | -------------------------------------------------------------------------------- /fastcam-photoapp/src/main/java/info/thecodinglive/photoapp/storage/ImageFileUploadResult.java: -------------------------------------------------------------------------------- 1 | package info.thecodinglive.photoapp.storage; 2 | 3 | import lombok.Builder; 4 | import lombok.Getter; 5 | 6 | @Builder 7 | @Getter 8 | public class ImageFileUploadResult { 9 | private String fileId; 10 | private String fileName; 11 | private Long fileSize; 12 | } 13 | -------------------------------------------------------------------------------- /fastcam-photoapp/src/main/java/info/thecodinglive/photoapp/storage/gcp/GCPStorageComponent.java: -------------------------------------------------------------------------------- 1 | package info.thecodinglive.photoapp.storage.gcp; 2 | 3 | 4 | import com.google.api.services.storage.model.StorageObject; 5 | import com.google.auth.Credentials; 6 | import com.google.auth.oauth2.GoogleCredentials; 7 | import com.google.cloud.storage.*; 8 | import lombok.RequiredArgsConstructor; 9 | import lombok.extern.slf4j.Slf4j; 10 | import org.springframework.stereotype.Component; 11 | import org.springframework.stereotype.Service; 12 | import org.springframework.util.ResourceUtils; 13 | 14 | import javax.annotation.PostConstruct; 15 | import javax.servlet.http.HttpServletResponse; 16 | import java.io.FileInputStream; 17 | import java.io.FileOutputStream; 18 | import java.io.InputStream; 19 | import java.nio.file.Files; 20 | import java.nio.file.Paths; 21 | import java.util.ArrayList; 22 | import java.util.Arrays; 23 | 24 | @Slf4j 25 | @Component 26 | @RequiredArgsConstructor 27 | public class GCPStorageComponent { 28 | private static final String PROJECT_ID = "boot-sample1"; 29 | private static final String BUCKET_NAME = "photosample-storage"; 30 | 31 | private BlobInfo createBlobInfo(String bucketName, String objectName) { 32 | BlobId blobId = BlobId.of(bucketName, objectName); 33 | return BlobInfo.newBuilder(blobId).build(); 34 | } 35 | 36 | 37 | public void uploadGcpStorage(String bucketName, String objectName, String filePath) { 38 | try { 39 | Storage storage = StorageOptions.newBuilder().setProjectId(PROJECT_ID).build().getService(); 40 | storage.create(createBlobInfo(bucketName, objectName), Files.readAllBytes(Paths.get(filePath))); 41 | LOG.info("file upload: {} uploaded to bucket {} as {}", filePath, bucketName, objectName); 42 | } catch (Exception e) { 43 | LOG.debug("error", e); 44 | } 45 | } 46 | 47 | 48 | public void uploadGcpStorageStream(String objectName, InputStream fileInput) { 49 | try { 50 | Storage storage = StorageOptions.newBuilder().setProjectId(PROJECT_ID).build().getService(); 51 | storage.create(createBlobInfo(BUCKET_NAME, objectName), fileInput.readAllBytes()); 52 | LOG.info("file upload: {} uploaded to bucket {}", BUCKET_NAME, objectName); 53 | } catch (Exception e) { 54 | LOG.debug("error", e); 55 | } 56 | } 57 | 58 | public void downloadGcpStroage(String bucketName, String objectName, String destPath) { 59 | try { 60 | Storage storage = StorageOptions.newBuilder().setProjectId(PROJECT_ID).build().getService(); 61 | Blob blob = storage.get(BlobId.of(bucketName, objectName)); 62 | blob.downloadTo(Paths.get(destPath)); 63 | 64 | LOG.info("file download: {} uploaded to bucket {} as {}", destPath, bucketName, objectName); 65 | } catch (Exception e) { 66 | LOG.debug("error", e); 67 | } 68 | } 69 | 70 | public void downloadGcpStroage(String objectName, HttpServletResponse response) { 71 | try { 72 | Storage storage = StorageOptions.newBuilder().setProjectId(PROJECT_ID).build().getService(); 73 | Blob blob = storage.get(BlobId.of(BUCKET_NAME, objectName)); 74 | response.setHeader("Content-Disposition", "attachment; filename=\"" + objectName + "\";"); 75 | response.setHeader("Content-Transfer-Encoding", "binary"); 76 | blob.downloadTo(response.getOutputStream()); 77 | 78 | LOG.info("file download to bucket {} as {}", BUCKET_NAME, objectName); 79 | } catch (Exception e) { 80 | LOG.debug("error", e); 81 | } 82 | } 83 | } 84 | -------------------------------------------------------------------------------- /fastcam-photoapp/src/main/java/info/thecodinglive/photoapp/storage/gcp/GcpFileDownloadController.java: -------------------------------------------------------------------------------- 1 | package info.thecodinglive.photoapp.storage.gcp; 2 | 3 | import io.swagger.annotations.ApiOperation; 4 | import lombok.RequiredArgsConstructor; 5 | import lombok.extern.slf4j.Slf4j; 6 | import org.springframework.http.ResponseEntity; 7 | import org.springframework.web.bind.annotation.GetMapping; 8 | import org.springframework.web.bind.annotation.PostMapping; 9 | import org.springframework.web.bind.annotation.RequestPart; 10 | import org.springframework.web.bind.annotation.RestController; 11 | import org.springframework.web.multipart.MultipartFile; 12 | 13 | import javax.servlet.http.HttpServletResponse; 14 | import java.io.OutputStream; 15 | 16 | @Slf4j 17 | @RestController 18 | @RequiredArgsConstructor 19 | public class GcpFileDownloadController { 20 | private final GcpStorageService gcpStorageService; 21 | 22 | @ApiOperation("gcp 파일 다운로드") 23 | @GetMapping("/v1.0/gcp/download") 24 | public ResponseEntity fileDownload( 25 | HttpServletResponse response, 26 | String downloadFileName) { 27 | gcpStorageService.gcpFileDown(downloadFileName, response); 28 | return ResponseEntity.ok("ok"); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /fastcam-photoapp/src/main/java/info/thecodinglive/photoapp/storage/gcp/GcpFileUploadController.java: -------------------------------------------------------------------------------- 1 | package info.thecodinglive.photoapp.storage.gcp; 2 | 3 | import io.swagger.annotations.ApiOperation; 4 | import lombok.RequiredArgsConstructor; 5 | import lombok.extern.slf4j.Slf4j; 6 | import org.springframework.http.ResponseEntity; 7 | import org.springframework.web.bind.annotation.PostMapping; 8 | import org.springframework.web.bind.annotation.RequestPart; 9 | import org.springframework.web.bind.annotation.RestController; 10 | import org.springframework.web.multipart.MultipartFile; 11 | 12 | import java.util.Random; 13 | import java.util.UUID; 14 | 15 | @Slf4j 16 | @RestController 17 | @RequiredArgsConstructor 18 | public class GcpFileUploadController { 19 | private final GcpStorageService gcpStorageService; 20 | 21 | @ApiOperation("gcp 파일 업로드") 22 | @PostMapping("/v1.0/gcp/upload") 23 | public ResponseEntity fileupload(@RequestPart("imageFile") MultipartFile multipartFile) { 24 | gcpStorageService.gcpFileUpload(multipartFile.getOriginalFilename(), multipartFile); 25 | 26 | return ResponseEntity.ok("ok"); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /fastcam-photoapp/src/main/java/info/thecodinglive/photoapp/storage/gcp/GcpStorageService.java: -------------------------------------------------------------------------------- 1 | package info.thecodinglive.photoapp.storage.gcp; 2 | 3 | import lombok.RequiredArgsConstructor; 4 | import lombok.extern.slf4j.Slf4j; 5 | import org.springframework.stereotype.Service; 6 | import org.springframework.web.multipart.MultipartFile; 7 | 8 | import javax.servlet.http.HttpServletResponse; 9 | 10 | @Service 11 | @RequiredArgsConstructor 12 | @Slf4j 13 | public class GcpStorageService { 14 | private final GCPStorageComponent gcpStorageComponent; 15 | 16 | public void gcpFileUpload(String uploadedFileName, MultipartFile multipartFile) { 17 | try { 18 | gcpStorageComponent.uploadGcpStorageStream(uploadedFileName, multipartFile.getInputStream()); 19 | }catch (Exception e) { 20 | LOG.error("upload error", e); 21 | } 22 | } 23 | 24 | public void gcpFileDown(String gcpFileName, HttpServletResponse servletResponse) { 25 | gcpStorageComponent.downloadGcpStroage(gcpFileName, servletResponse); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /fastcam-photoapp/src/main/resources/admin.yml: -------------------------------------------------------------------------------- 1 | spring.boot: 2 | admin: 3 | client: 4 | instance: 5 | health-url: http://localhost:8080/swagger-ui.html 6 | #url: http://localhost:8091 7 | auto-registration: true 8 | management: 9 | endpoint: 10 | health: 11 | show-details: ALWAYS 12 | endpoints: 13 | web: 14 | exposure: 15 | include: "*" -------------------------------------------------------------------------------- /fastcam-photoapp/src/main/resources/application.yml: -------------------------------------------------------------------------------- 1 | #https://docs.spring.io/spring-boot/docs/current/reference/html/appendix-application-properties.html 2 | server.port: 8080 3 | spring: 4 | application: 5 | name: photoapp 6 | jackson: 7 | default-property-inclusion: non_null 8 | servlet: 9 | multipart.enabled: true 10 | 11 | photoapp.file: 12 | defaultPath: c:\up-dir 13 | 14 | 15 | spring.zipkin: 16 | base-url: http://localhost:9411 17 | 18 | spring.sleuth.sampler.probability: 1.0 19 | 20 | eureka: 21 | client: 22 | serviceUrl: 23 | defaultZone: http://localhost:8761/eureka/ 24 | instance: 25 | leaseRenewalIntervalInSeconds: 10 26 | metadataMap: 27 | instanceId: ${vcap.application.instance_id:${spring.application.name}:${spring.application.instance_id:${server.port}}} 28 | 29 | 30 | spring.config.import: admin.yml 31 | 32 | 33 | -------------------------------------------------------------------------------- /fastcam-photoapp/src/main/resources/test-down.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thecodinglive/fastcampus-example/8fc38f151532d7fc4168fd2cbb6e9cf42e9dd472/fastcam-photoapp/src/main/resources/test-down.jpg -------------------------------------------------------------------------------- /fastcam-photoapp/src/main/resources/test.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thecodinglive/fastcampus-example/8fc38f151532d7fc4168fd2cbb6e9cf42e9dd472/fastcam-photoapp/src/main/resources/test.jpg -------------------------------------------------------------------------------- /fastcam-photoapp/src/test/java/info/thecodinglive/photoapp/DateFormatTest.java: -------------------------------------------------------------------------------- 1 | package info.thecodinglive.photoapp; 2 | 3 | import info.thecodinglive.photoapp.storage.FileWriter; 4 | import org.assertj.core.api.Assert; 5 | import org.junit.jupiter.api.Assertions; 6 | import org.junit.jupiter.api.Test; 7 | import org.junit.jupiter.api.extension.ExtendWith; 8 | import org.springframework.boot.test.context.SpringBootTest; 9 | import org.springframework.test.context.junit.jupiter.SpringExtension; 10 | import org.springframework.test.context.junit4.SpringRunner; 11 | 12 | import java.time.LocalDateTime; 13 | 14 | //@SpringBootTest 15 | //@ExtendWith(SpringExtension.class) 16 | public class DateFormatTest { 17 | @Test 18 | void fileWriteGenerateDate() { 19 | //given 20 | String expectdDate = FileWriter.dateStr(); 21 | //then 22 | System.out.println(FileWriter.dateStr()); 23 | Assertions.assertNotNull(expectdDate); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /fastcam-photoapp/src/test/java/info/thecodinglive/photoapp/GcpStorageServiceTest.java: -------------------------------------------------------------------------------- 1 | package info.thecodinglive.photoapp; 2 | 3 | import info.thecodinglive.photoapp.storage.gcp.GCPStorageComponent; 4 | import org.junit.jupiter.api.Test; 5 | import org.junit.jupiter.api.extension.ExtendWith; 6 | import org.springframework.beans.factory.annotation.Autowired; 7 | import org.springframework.boot.test.context.SpringBootTest; 8 | import org.springframework.test.context.junit.jupiter.SpringExtension; 9 | 10 | import java.nio.file.Files; 11 | import java.nio.file.Paths; 12 | 13 | @SpringBootTest 14 | @ExtendWith(SpringExtension.class) 15 | public class GcpStorageServiceTest { 16 | @Autowired 17 | private GCPStorageComponent gcpUploadService; 18 | 19 | private String projectId = "boot-sample1"; 20 | private String bucketName = "photosample-storage"; 21 | private String filePath = "src/main/resources/test.jpg"; 22 | 23 | @Test 24 | public void gcpUpload() { 25 | gcpUploadService.uploadGcpStorage(bucketName, "ysj-test3.jpg", filePath); 26 | } 27 | 28 | @Test 29 | public void gcpDownload() { 30 | gcpUploadService.downloadGcpStroage(bucketName, "test.jpg", "src/main/resources/test-down.jpg"); 31 | } 32 | 33 | @Test 34 | public void getFiletPath() throws Exception { 35 | Files.readAllBytes(Paths.get("src/main/resources/test.jpg")); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /fastcam-resilience4j-server/build.gradle.kts: -------------------------------------------------------------------------------- 1 | import org.jetbrains.kotlin.gradle.tasks.KotlinCompile 2 | 3 | plugins { 4 | id("org.springframework.boot") version "2.4.3" 5 | id("io.spring.dependency-management") version "1.0.11.RELEASE" 6 | kotlin("jvm") version "1.4.30" 7 | kotlin("plugin.spring") version "1.4.30" 8 | } 9 | 10 | group = "info.thecodinglive.rabbitmq" 11 | version = "0.0.1-SNAPSHOT" 12 | java.sourceCompatibility = JavaVersion.VERSION_11 13 | 14 | configurations { 15 | compileOnly { 16 | extendsFrom(configurations.annotationProcessor.get()) 17 | } 18 | } 19 | 20 | repositories { 21 | jcenter() 22 | } 23 | 24 | dependencies { 25 | implementation("org.springframework.boot:spring-boot-starter-web") 26 | compileOnly("org.projectlombok:lombok") 27 | annotationProcessor("org.projectlombok:lombok") 28 | } 29 | 30 | dependencyManagement { 31 | imports { 32 | mavenBom ("org.springframework.cloud:spring-cloud-dependencies:2020.0.1") 33 | } 34 | } 35 | 36 | 37 | tasks.withType { 38 | kotlinOptions { 39 | freeCompilerArgs = listOf("-Xjsr305=strict") 40 | jvmTarget = "11" 41 | } 42 | } 43 | 44 | tasks.withType { 45 | useJUnitPlatform() 46 | } 47 | -------------------------------------------------------------------------------- /fastcam-resilience4j-server/gradlew.bat: -------------------------------------------------------------------------------- 1 | @rem 2 | @rem Copyright 2015 the original author or authors. 3 | @rem 4 | @rem Licensed under the Apache License, Version 2.0 (the "License"); 5 | @rem you may not use this file except in compliance with the License. 6 | @rem You may obtain a copy of the License at 7 | @rem 8 | @rem https://www.apache.org/licenses/LICENSE-2.0 9 | @rem 10 | @rem Unless required by applicable law or agreed to in writing, software 11 | @rem distributed under the License is distributed on an "AS IS" BASIS, 12 | @rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | @rem See the License for the specific language governing permissions and 14 | @rem limitations under the License. 15 | @rem 16 | 17 | @if "%DEBUG%" == "" @echo off 18 | @rem ########################################################################## 19 | @rem 20 | @rem Gradle startup script for Windows 21 | @rem 22 | @rem ########################################################################## 23 | 24 | @rem Set local scope for the variables with windows NT shell 25 | if "%OS%"=="Windows_NT" setlocal 26 | 27 | set DIRNAME=%~dp0 28 | if "%DIRNAME%" == "" set DIRNAME=. 29 | set APP_BASE_NAME=%~n0 30 | set APP_HOME=%DIRNAME% 31 | 32 | @rem Resolve any "." and ".." in APP_HOME to make it shorter. 33 | for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi 34 | 35 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 36 | set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" 37 | 38 | @rem Find java.exe 39 | if defined JAVA_HOME goto findJavaFromJavaHome 40 | 41 | set JAVA_EXE=java.exe 42 | %JAVA_EXE% -version >NUL 2>&1 43 | if "%ERRORLEVEL%" == "0" goto execute 44 | 45 | echo. 46 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 47 | echo. 48 | echo Please set the JAVA_HOME variable in your environment to match the 49 | echo location of your Java installation. 50 | 51 | goto fail 52 | 53 | :findJavaFromJavaHome 54 | set JAVA_HOME=%JAVA_HOME:"=% 55 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe 56 | 57 | if exist "%JAVA_EXE%" goto execute 58 | 59 | echo. 60 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 61 | echo. 62 | echo Please set the JAVA_HOME variable in your environment to match the 63 | echo location of your Java installation. 64 | 65 | goto fail 66 | 67 | :execute 68 | @rem Setup the command line 69 | 70 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar 71 | 72 | 73 | @rem Execute Gradle 74 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* 75 | 76 | :end 77 | @rem End local scope for the variables with windows NT shell 78 | if "%ERRORLEVEL%"=="0" goto mainEnd 79 | 80 | :fail 81 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of 82 | rem the _cmd.exe /c_ return code! 83 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 84 | exit /b 1 85 | 86 | :mainEnd 87 | if "%OS%"=="Windows_NT" endlocal 88 | 89 | :omega 90 | -------------------------------------------------------------------------------- /fastcam-resilience4j-server/src/main/java/info/thecodinglive/resilience4j/provide/ProvideApp.java: -------------------------------------------------------------------------------- 1 | package info.thecodinglive.resilience4j.provide; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | 6 | @SpringBootApplication 7 | public class ProvideApp { 8 | public static void main(String ar[]) { 9 | SpringApplication.run(ProvideApp.class, ar); 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /fastcam-resilience4j-server/src/main/java/info/thecodinglive/resilience4j/provide/service/BulkHeadController.java: -------------------------------------------------------------------------------- 1 | package info.thecodinglive.resilience4j.provide.service; 2 | 3 | import lombok.extern.slf4j.Slf4j; 4 | import org.springframework.web.bind.annotation.GetMapping; 5 | import org.springframework.web.bind.annotation.RestController; 6 | 7 | import java.util.concurrent.ThreadLocalRandom; 8 | 9 | @Slf4j 10 | @RestController 11 | public class BulkHeadController { 12 | private static final int DELAY = 100; 13 | private int count = 0; 14 | 15 | @GetMapping("/") 16 | public String okay() { 17 | return "I'm fine."; 18 | } 19 | 20 | @GetMapping("/slow") 21 | public String slow() throws InterruptedException { 22 | Thread.sleep(DELAY); 23 | return "I'm fine, just slow"; 24 | } 25 | 26 | @GetMapping("/error") 27 | public String error() { 28 | throw new InternalServerErrorException("I'm absolutely not fine!"); 29 | } 30 | 31 | @GetMapping("/erratic") 32 | public String erratic() throws InterruptedException { 33 | log.info(Integer.toString(count++)); 34 | 35 | if(ThreadLocalRandom.current().nextInt(0 , 5) == 0) { 36 | log.error("erratic"); 37 | throw new InterruptedException("erratic occured"); 38 | } 39 | log.info("sucess"); 40 | return "ok"; 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /fastcam-resilience4j-server/src/main/java/info/thecodinglive/resilience4j/provide/service/CircuitController.java: -------------------------------------------------------------------------------- 1 | package info.thecodinglive.resilience4j.provide.service; 2 | 3 | import lombok.extern.slf4j.Slf4j; 4 | import org.springframework.web.bind.annotation.GetMapping; 5 | import org.springframework.web.bind.annotation.RequestMapping; 6 | import org.springframework.web.bind.annotation.RestController; 7 | 8 | import java.util.concurrent.ThreadLocalRandom; 9 | 10 | @Slf4j 11 | @RestController 12 | @RequestMapping("/circuit") 13 | public class CircuitController { 14 | private static final int DELAY = 100; 15 | private int count = 0; 16 | 17 | @GetMapping("/") 18 | public String okay() { 19 | return "I'm fine."; 20 | } 21 | 22 | @GetMapping("/slow") 23 | public String slow() throws InterruptedException { 24 | Thread.sleep(DELAY); 25 | return "I'm fine, just slow"; 26 | } 27 | 28 | @GetMapping("/error") 29 | public String error() { 30 | throw new InternalServerErrorException("I'm absolutely not fine!"); 31 | } 32 | 33 | @GetMapping("/erratic") 34 | public String erratic() throws InterruptedException { 35 | log.info(Integer.toString(count++)); 36 | 37 | if(ThreadLocalRandom.current().nextInt(0 , 5) == 0) { 38 | log.error("erratic"); 39 | throw new InterruptedException("erratic occured"); 40 | } 41 | log.info("sucess"); 42 | return "ok"; 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /fastcam-resilience4j-server/src/main/java/info/thecodinglive/resilience4j/provide/service/InternalServerErrorException.java: -------------------------------------------------------------------------------- 1 | package info.thecodinglive.resilience4j.provide.service; 2 | 3 | import org.springframework.http.HttpStatus; 4 | import org.springframework.web.bind.annotation.ResponseStatus; 5 | 6 | /** 7 | * InternalServerErrorException 8 | */ 9 | @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR) 10 | public class InternalServerErrorException extends RuntimeException { 11 | 12 | public InternalServerErrorException(String msg) { 13 | super(msg); 14 | } 15 | 16 | } -------------------------------------------------------------------------------- /fastcam-resilience4j-server/src/main/resources/application.yml: -------------------------------------------------------------------------------- 1 | server.port: 7072 2 | 3 | 4 | logging: 5 | level: 6 | root: debug -------------------------------------------------------------------------------- /fastcam-resilience4j/build.gradle.kts: -------------------------------------------------------------------------------- 1 | import org.jetbrains.kotlin.gradle.tasks.KotlinCompile 2 | 3 | plugins { 4 | id("org.springframework.boot") version "2.4.3" 5 | id("io.spring.dependency-management") version "1.0.11.RELEASE" 6 | kotlin("jvm") version "1.4.30" 7 | kotlin("plugin.spring") version "1.4.30" 8 | } 9 | 10 | group = "info.thecodinglive.rabbitmq" 11 | version = "0.0.1-SNAPSHOT" 12 | java.sourceCompatibility = JavaVersion.VERSION_11 13 | 14 | configurations { 15 | compileOnly { 16 | extendsFrom(configurations.annotationProcessor.get()) 17 | } 18 | } 19 | 20 | repositories { 21 | jcenter() 22 | } 23 | 24 | dependencies { 25 | implementation("org.springframework.boot:spring-boot-starter-web") 26 | implementation("org.springframework.boot:spring-boot-starter-aop") 27 | implementation("io.github.resilience4j:resilience4j-spring-boot2") 28 | implementation("org.springframework.cloud:spring-cloud-starter-circuitbreaker-resilience4j") 29 | implementation("org.springframework.boot:spring-boot-starter-actuator") 30 | implementation("io.micrometer:micrometer-core") 31 | implementation("io.micrometer:micrometer-registry-prometheus") 32 | implementation("io.github.resilience4j:resilience4j-micrometer") 33 | 34 | compileOnly("org.projectlombok:lombok") 35 | annotationProcessor("org.projectlombok:lombok") 36 | } 37 | 38 | dependencyManagement { 39 | imports { 40 | mavenBom ("org.springframework.cloud:spring-cloud-dependencies:2020.0.1") 41 | } 42 | } 43 | 44 | 45 | tasks.withType { 46 | kotlinOptions { 47 | freeCompilerArgs = listOf("-Xjsr305=strict") 48 | jvmTarget = "11" 49 | } 50 | } 51 | 52 | tasks.withType { 53 | useJUnitPlatform() 54 | } 55 | -------------------------------------------------------------------------------- /fastcam-resilience4j/docker/docker-compose.yml: -------------------------------------------------------------------------------- 1 | version: '3' 2 | services: 3 | prometheus: 4 | image: prom/prometheus 5 | container_name: prometheus 6 | volumes: 7 | - ./prometheus.yml:/etc/prometheus/prometheus.yml 8 | expose: 9 | - 9090 10 | ports: 11 | - "9090:9090" 12 | grafana: 13 | image: grafana/grafana 14 | container_name: grafana 15 | env_file: 16 | - ./grafana.env 17 | expose: 18 | - 3000 19 | ports: 20 | - "3000:3000" -------------------------------------------------------------------------------- /fastcam-resilience4j/docker/grafana.env: -------------------------------------------------------------------------------- 1 | # [server] 2 | # GF_SERVER_DOMAIN=localhost 3 | # GF_SERVER_HTTP_PORT=3000 4 | # GF_SERVER_PROTOCOL=http -------------------------------------------------------------------------------- /fastcam-resilience4j/docker/prometheus.yml: -------------------------------------------------------------------------------- 1 | global: 2 | scrape_interval: 15s # By default, scrape targets every 15 seconds. 3 | 4 | # Attach these labels to any time series or alerts when communicating with 5 | # external systems (federation, remote storage, Alertmanager). 6 | external_labels: 7 | monitor: 'resilience4j-monitor' 8 | 9 | # A scrape configuration containing exactly one endpoint to scrape: 10 | # Here it's Prometheus itself. 11 | scrape_configs: 12 | # The job name is added as a label `job=` to any timeseries scraped from this config. 13 | - job_name: 'prometheus' 14 | 15 | # Override the global default and scrape targets from this job every 5 seconds. 16 | scrape_interval: 5s 17 | 18 | static_configs: 19 | - targets: ['localhost:9090'] 20 | 21 | - job_name: 'resilience4j-spring-boot2-demo' 22 | 23 | # Override the global default and scrape targets from this job every 5 seconds. 24 | scrape_interval: 5s 25 | 26 | metrics_path: /actuator/prometheus 27 | 28 | static_configs: 29 | # application ip 30 | - targets: ['172.30.1.45:7075'] -------------------------------------------------------------------------------- /fastcam-resilience4j/gradlew.bat: -------------------------------------------------------------------------------- 1 | @rem 2 | @rem Copyright 2015 the original author or authors. 3 | @rem 4 | @rem Licensed under the Apache License, Version 2.0 (the "License"); 5 | @rem you may not use this file except in compliance with the License. 6 | @rem You may obtain a copy of the License at 7 | @rem 8 | @rem https://www.apache.org/licenses/LICENSE-2.0 9 | @rem 10 | @rem Unless required by applicable law or agreed to in writing, software 11 | @rem distributed under the License is distributed on an "AS IS" BASIS, 12 | @rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | @rem See the License for the specific language governing permissions and 14 | @rem limitations under the License. 15 | @rem 16 | 17 | @if "%DEBUG%" == "" @echo off 18 | @rem ########################################################################## 19 | @rem 20 | @rem Gradle startup script for Windows 21 | @rem 22 | @rem ########################################################################## 23 | 24 | @rem Set local scope for the variables with windows NT shell 25 | if "%OS%"=="Windows_NT" setlocal 26 | 27 | set DIRNAME=%~dp0 28 | if "%DIRNAME%" == "" set DIRNAME=. 29 | set APP_BASE_NAME=%~n0 30 | set APP_HOME=%DIRNAME% 31 | 32 | @rem Resolve any "." and ".." in APP_HOME to make it shorter. 33 | for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi 34 | 35 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 36 | set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" 37 | 38 | @rem Find java.exe 39 | if defined JAVA_HOME goto findJavaFromJavaHome 40 | 41 | set JAVA_EXE=java.exe 42 | %JAVA_EXE% -version >NUL 2>&1 43 | if "%ERRORLEVEL%" == "0" goto execute 44 | 45 | echo. 46 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 47 | echo. 48 | echo Please set the JAVA_HOME variable in your environment to match the 49 | echo location of your Java installation. 50 | 51 | goto fail 52 | 53 | :findJavaFromJavaHome 54 | set JAVA_HOME=%JAVA_HOME:"=% 55 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe 56 | 57 | if exist "%JAVA_EXE%" goto execute 58 | 59 | echo. 60 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 61 | echo. 62 | echo Please set the JAVA_HOME variable in your environment to match the 63 | echo location of your Java installation. 64 | 65 | goto fail 66 | 67 | :execute 68 | @rem Setup the command line 69 | 70 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar 71 | 72 | 73 | @rem Execute Gradle 74 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* 75 | 76 | :end 77 | @rem End local scope for the variables with windows NT shell 78 | if "%ERRORLEVEL%"=="0" goto mainEnd 79 | 80 | :fail 81 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of 82 | rem the _cmd.exe /c_ return code! 83 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 84 | exit /b 1 85 | 86 | :mainEnd 87 | if "%OS%"=="Windows_NT" endlocal 88 | 89 | :omega 90 | -------------------------------------------------------------------------------- /fastcam-resilience4j/src/main/java/info/thecodinglive/resilience4j/ResilienceApp.java: -------------------------------------------------------------------------------- 1 | package info.thecodinglive.resilience4j; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | 6 | @SpringBootApplication 7 | public class ResilienceApp { 8 | public static void main(String ar[]) { 9 | SpringApplication.run(ResilienceApp.class, ar); 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /fastcam-resilience4j/src/main/java/info/thecodinglive/resilience4j/config/CircuitConfig.java: -------------------------------------------------------------------------------- 1 | package info.thecodinglive.resilience4j.config; 2 | 3 | import io.github.resilience4j.circuitbreaker.CircuitBreakerConfig; 4 | import io.github.resilience4j.timelimiter.TimeLimiter; 5 | import io.github.resilience4j.timelimiter.TimeLimiterConfig; 6 | import io.github.resilience4j.timelimiter.TimeLimiterRegistry; 7 | import lombok.extern.slf4j.Slf4j; 8 | import org.springframework.beans.factory.annotation.Value; 9 | import org.springframework.cloud.circuitbreaker.resilience4j.Resilience4JCircuitBreakerFactory; 10 | import org.springframework.cloud.circuitbreaker.resilience4j.Resilience4JConfigBuilder; 11 | import org.springframework.cloud.client.circuitbreaker.Customizer; 12 | import org.springframework.context.annotation.Bean; 13 | import org.springframework.context.annotation.Configuration; 14 | 15 | 16 | import java.time.Duration; 17 | 18 | @Slf4j 19 | @Configuration 20 | public class CircuitConfig { 21 | @Value("${apiServer.maxTimeout}") 22 | private Integer maxTimeout; 23 | @Bean 24 | public Customizer defaultCustomer() { 25 | log.info("maxTimeout check: {}", maxTimeout); 26 | return factory -> factory.configureDefault(id -> new Resilience4JConfigBuilder("fastcam-timelimit") 27 | .timeLimiterConfig(TimeLimiterConfig.custom() 28 | .timeoutDuration(Duration.ofSeconds(maxTimeout)) 29 | .build()) 30 | .circuitBreakerConfig(CircuitBreakerConfig.ofDefaults()).build()); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /fastcam-resilience4j/src/main/java/info/thecodinglive/resilience4j/config/WebConfig.java: -------------------------------------------------------------------------------- 1 | package info.thecodinglive.resilience4j.config; 2 | 3 | import org.springframework.boot.web.client.RestTemplateBuilder; 4 | import org.springframework.context.annotation.Bean; 5 | import org.springframework.context.annotation.Configuration; 6 | import org.springframework.web.client.RestTemplate; 7 | 8 | @Configuration 9 | public class WebConfig { 10 | @Bean 11 | RestTemplate restTemplate() {return new RestTemplateBuilder().build(); } 12 | } 13 | -------------------------------------------------------------------------------- /fastcam-resilience4j/src/main/java/info/thecodinglive/resilience4j/service/BulkHeadController.java: -------------------------------------------------------------------------------- 1 | package info.thecodinglive.resilience4j.service; 2 | 3 | import io.github.resilience4j.bulkhead.Bulkhead; 4 | import io.github.resilience4j.bulkhead.BulkheadConfig; 5 | import io.vavr.CheckedFunction0; 6 | import io.vavr.control.Try; 7 | import lombok.extern.slf4j.Slf4j; 8 | import org.springframework.beans.factory.annotation.Value; 9 | import org.springframework.web.bind.annotation.GetMapping; 10 | import org.springframework.web.bind.annotation.RestController; 11 | import org.springframework.web.client.RestTemplate; 12 | 13 | import java.time.Duration; 14 | 15 | @RestController 16 | @Slf4j 17 | public class BulkHeadController { 18 | 19 | private final RestTemplate restTemplate; 20 | private final String provideUrl; 21 | private final Bulkhead bulkhead; 22 | 23 | public BulkHeadController(RestTemplate restTemplate, @Value("${apiServer.url}") String provideUrl, 24 | @Value("${apiServer.maxConcurrent}") int maxConcurrent) { 25 | this.restTemplate = restTemplate; 26 | this.provideUrl = provideUrl; 27 | log.info("maxCounccurent: {}", maxConcurrent); 28 | this.bulkhead = createBulkHead(maxConcurrent); 29 | } 30 | 31 | private Bulkhead createBulkHead(Integer maxConcurrent) { 32 | BulkheadConfig bulkheadConfig = BulkheadConfig.custom() 33 | .maxConcurrentCalls(maxConcurrent) 34 | .maxWaitDuration(Duration.ofMillis(500)) 35 | .build(); 36 | 37 | Bulkhead bulkhead = Bulkhead.of("resilience-provider", bulkheadConfig); 38 | 39 | bulkhead.getEventPublisher() 40 | .onCallPermitted(event -> log.info("Call permitted by bulkhead")) 41 | .onCallRejected(event -> log.info("Call rejected by bulkhead")); 42 | 43 | return bulkhead; 44 | } 45 | 46 | 47 | @GetMapping("/bulkhead") 48 | public String bulkhead() { 49 | CheckedFunction0 someServiceCall = Bulkhead.decorateCheckedSupplier(bulkhead, 50 | () -> "this message was" + restTemplate.getForObject(provideUrl + "/slow", String.class)); 51 | 52 | Try result = Try.of(someServiceCall).recover((throwable -> "this is a bulkhead fallback")); 53 | return result.get(); 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /fastcam-resilience4j/src/main/java/info/thecodinglive/resilience4j/service/circuit/CircuitAnnotationService.java: -------------------------------------------------------------------------------- 1 | package info.thecodinglive.resilience4j.service.circuit; 2 | 3 | import io.github.resilience4j.circuitbreaker.CallNotPermittedException; 4 | import io.github.resilience4j.circuitbreaker.annotation.CircuitBreaker; 5 | import lombok.RequiredArgsConstructor; 6 | import lombok.extern.slf4j.Slf4j; 7 | import org.springframework.beans.factory.annotation.Value; 8 | import org.springframework.stereotype.Service; 9 | import org.springframework.web.client.RestTemplate; 10 | 11 | @RequiredArgsConstructor 12 | @Service 13 | @Slf4j 14 | public class CircuitAnnotationService { 15 | @Value("${apiServer.url}") 16 | private String apiUrl; 17 | 18 | private RestTemplate restTemplate; 19 | 20 | @CircuitBreaker(name = "myCircuitBreaker", fallbackMethod = "defaultFallback") 21 | public String getFailRequest() { 22 | //return restTemplate.getForObject(apiUrl + "/circuit/error", String.class); 23 | throw new MyException("myException"); 24 | } 25 | 26 | @CircuitBreaker(name = "myCircuitBreaker", fallbackMethod = "defaultFallback") 27 | public String getSuccessRequest() { 28 | return "request is success"; 29 | } 30 | 31 | 32 | 33 | public String defaultFallback(MyException e) { 34 | log.error("default fallback ", e); 35 | return "fallback msg"; 36 | } 37 | 38 | public String defaultFallback(CallNotPermittedException callNotPermittedException) { 39 | log.error("default fallback ", callNotPermittedException); 40 | return "call not permit fallback msg"; 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /fastcam-resilience4j/src/main/java/info/thecodinglive/resilience4j/service/circuit/CircuitController.java: -------------------------------------------------------------------------------- 1 | package info.thecodinglive.resilience4j.service.circuit; 2 | 3 | import io.github.resilience4j.circuitbreaker.CircuitBreakerRegistry; 4 | import lombok.RequiredArgsConstructor; 5 | import lombok.extern.slf4j.Slf4j; 6 | import org.springframework.beans.factory.annotation.Value; 7 | import org.springframework.cloud.client.circuitbreaker.CircuitBreakerFactory; 8 | import org.springframework.web.bind.annotation.GetMapping; 9 | import org.springframework.web.bind.annotation.PathVariable; 10 | import org.springframework.web.bind.annotation.RestController; 11 | 12 | import java.util.HashMap; 13 | import java.util.Map; 14 | 15 | @RestController 16 | @Slf4j 17 | @RequiredArgsConstructor 18 | public class CircuitController { 19 | 20 | private final CircuitAnnotationService circuitAnnotationService; 21 | private final CircuitBreakerFactory circuitBreakerFactory; 22 | private final HttpBinService httpBin; 23 | 24 | @GetMapping("/get") 25 | public Map get() {return httpBin.get();} 26 | 27 | @GetMapping("/delay/{seconds}") 28 | public Map delay(@PathVariable int seconds) { 29 | return circuitBreakerFactory 30 | .create("delay").run(httpBin.delaySuppplier(seconds), 31 | t -> { 32 | log.warn("delay call failed error", t); 33 | Map fallback = new HashMap<>(); 34 | fallback.put("hello", "world"); 35 | return fallback; 36 | }); 37 | } 38 | 39 | @GetMapping("/circuit/fail") 40 | public String requestWithCircuitFail() { 41 | return circuitAnnotationService.getFailRequest(); 42 | } 43 | 44 | @GetMapping("/circuit/success") 45 | public String requestWithCircuitSuccess() { 46 | return circuitAnnotationService.getSuccessRequest(); 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /fastcam-resilience4j/src/main/java/info/thecodinglive/resilience4j/service/circuit/HttpBinService.java: -------------------------------------------------------------------------------- 1 | package info.thecodinglive.resilience4j.service.circuit; 2 | 3 | import lombok.RequiredArgsConstructor; 4 | import org.springframework.stereotype.Service; 5 | import org.springframework.web.client.RestTemplate; 6 | 7 | import java.util.Map; 8 | import java.util.function.Supplier; 9 | 10 | @RequiredArgsConstructor 11 | @Service 12 | public class HttpBinService { 13 | private final RestTemplate rest; 14 | 15 | public Map get() { 16 | return rest.getForObject("https://httpbin.org/get", Map.class); 17 | 18 | } 19 | 20 | public Map delay(int seconds) { 21 | return rest.getForObject("https://httpbin.org/delay/" + seconds, Map.class); 22 | } 23 | 24 | public Supplier delaySuppplier(int seconds) { 25 | return () -> this.delay(seconds); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /fastcam-resilience4j/src/main/java/info/thecodinglive/resilience4j/service/circuit/MyException.java: -------------------------------------------------------------------------------- 1 | package info.thecodinglive.resilience4j.service.circuit; 2 | 3 | public class MyException extends RuntimeException { 4 | public MyException(String message) { 5 | super(message); 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /fastcam-resilience4j/src/main/resources/application.yml: -------------------------------------------------------------------------------- 1 | server.port: 7075 2 | 3 | spring.server.name: fastcam-resilience4j 4 | spring.application.name: fastcam-resilience4j 5 | 6 | info: 7 | name: ${spring.application.name} 8 | 9 | 10 | #resilience4j 11 | apiServer: 12 | url: http://localhost:7072 13 | maxConcurrent: 1 14 | maxTimeout: 3 15 | 16 | management: 17 | endpoints: 18 | web: 19 | exposure: 20 | include: "*" 21 | health: 22 | show-details: always 23 | 24 | management.metrics: 25 | tags: 26 | server: ${spring.server.name} 27 | application: ${spring.application.name} 28 | distribution: 29 | percentiles-histogram: 30 | http.server.requests: true 31 | resilience4j.circuitbreaker.calls: true 32 | 33 | resilience4j.circuitbreaker: 34 | configs: 35 | default: 36 | registerHealthIndicator: true 37 | 38 | minimumNumberOfCalls: 3 39 | failureRateThreshold: 50 40 | waitDurationInOpenState: 10s 41 | instances: 42 | myCircuitBreaker: 43 | baseConfig: default -------------------------------------------------------------------------------- /fastcam-spring-admin/build.gradle.kts: -------------------------------------------------------------------------------- 1 | import org.jetbrains.kotlin.gradle.tasks.KotlinCompile 2 | 3 | plugins { 4 | id("org.springframework.boot") version "2.4.3" 5 | id("io.spring.dependency-management") version "1.0.11.RELEASE" 6 | kotlin("jvm") version "1.4.30" 7 | kotlin("plugin.spring") version "1.4.30" 8 | } 9 | 10 | group = "info.thecodinglive.stream" 11 | version = "0.0.1-SNAPSHOT" 12 | java.sourceCompatibility = JavaVersion.VERSION_11 13 | 14 | configurations { 15 | compileOnly { 16 | extendsFrom(configurations.annotationProcessor.get()) 17 | } 18 | } 19 | 20 | repositories { 21 | jcenter() 22 | } 23 | 24 | dependencies { 25 | implementation("org.springframework.boot:spring-boot-starter-web") 26 | implementation ("de.codecentric:spring-boot-admin-starter-server:2.4.0") 27 | implementation("org.springframework.cloud:spring-cloud-starter-netflix-eureka-client") 28 | 29 | testImplementation("org.springframework.boot:spring-boot-starter-test") 30 | } 31 | 32 | dependencyManagement { 33 | imports { 34 | mavenBom ("org.springframework.cloud:spring-cloud-dependencies:2020.0.1") 35 | } 36 | } 37 | 38 | tasks.withType { 39 | kotlinOptions { 40 | freeCompilerArgs = listOf("-Xjsr305=strict") 41 | jvmTarget = "11" 42 | } 43 | } 44 | 45 | tasks.withType { 46 | useJUnitPlatform() 47 | } 48 | -------------------------------------------------------------------------------- /fastcam-spring-admin/gradlew.bat: -------------------------------------------------------------------------------- 1 | @rem 2 | @rem Copyright 2015 the original author or authors. 3 | @rem 4 | @rem Licensed under the Apache License, Version 2.0 (the "License"); 5 | @rem you may not use this file except in compliance with the License. 6 | @rem You may obtain a copy of the License at 7 | @rem 8 | @rem https://www.apache.org/licenses/LICENSE-2.0 9 | @rem 10 | @rem Unless required by applicable law or agreed to in writing, software 11 | @rem distributed under the License is distributed on an "AS IS" BASIS, 12 | @rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | @rem See the License for the specific language governing permissions and 14 | @rem limitations under the License. 15 | @rem 16 | 17 | @if "%DEBUG%" == "" @echo off 18 | @rem ########################################################################## 19 | @rem 20 | @rem Gradle startup script for Windows 21 | @rem 22 | @rem ########################################################################## 23 | 24 | @rem Set local scope for the variables with windows NT shell 25 | if "%OS%"=="Windows_NT" setlocal 26 | 27 | set DIRNAME=%~dp0 28 | if "%DIRNAME%" == "" set DIRNAME=. 29 | set APP_BASE_NAME=%~n0 30 | set APP_HOME=%DIRNAME% 31 | 32 | @rem Resolve any "." and ".." in APP_HOME to make it shorter. 33 | for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi 34 | 35 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 36 | set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" 37 | 38 | @rem Find java.exe 39 | if defined JAVA_HOME goto findJavaFromJavaHome 40 | 41 | set JAVA_EXE=java.exe 42 | %JAVA_EXE% -version >NUL 2>&1 43 | if "%ERRORLEVEL%" == "0" goto execute 44 | 45 | echo. 46 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 47 | echo. 48 | echo Please set the JAVA_HOME variable in your environment to match the 49 | echo location of your Java installation. 50 | 51 | goto fail 52 | 53 | :findJavaFromJavaHome 54 | set JAVA_HOME=%JAVA_HOME:"=% 55 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe 56 | 57 | if exist "%JAVA_EXE%" goto execute 58 | 59 | echo. 60 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 61 | echo. 62 | echo Please set the JAVA_HOME variable in your environment to match the 63 | echo location of your Java installation. 64 | 65 | goto fail 66 | 67 | :execute 68 | @rem Setup the command line 69 | 70 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar 71 | 72 | 73 | @rem Execute Gradle 74 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* 75 | 76 | :end 77 | @rem End local scope for the variables with windows NT shell 78 | if "%ERRORLEVEL%"=="0" goto mainEnd 79 | 80 | :fail 81 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of 82 | rem the _cmd.exe /c_ return code! 83 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 84 | exit /b 1 85 | 86 | :mainEnd 87 | if "%OS%"=="Windows_NT" endlocal 88 | 89 | :omega 90 | -------------------------------------------------------------------------------- /fastcam-spring-admin/src/main/java/info/thecodinglive/admin/AdminServerApp.java: -------------------------------------------------------------------------------- 1 | package info.thecodinglive.admin; 2 | 3 | import de.codecentric.boot.admin.server.config.EnableAdminServer; 4 | import org.springframework.boot.SpringApplication; 5 | import org.springframework.boot.autoconfigure.SpringBootApplication; 6 | 7 | @SpringBootApplication 8 | @EnableAdminServer 9 | public class AdminServerApp { 10 | public static void main(String ar[]) { 11 | SpringApplication.run(AdminServerApp.class, ar); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /fastcam-spring-admin/src/main/resources/application.yml: -------------------------------------------------------------------------------- 1 | server.port: 8091 2 | spring.application.name: springAdmin 3 | spring.config.import: eureka-client.yml -------------------------------------------------------------------------------- /fastcam-spring-admin/src/main/resources/eureka-client.yml: -------------------------------------------------------------------------------- 1 | eureka: 2 | instance: 3 | leaseRenewalIntervalInSeconds: 1 4 | leaseExpirationDurationInSeconds: 2 5 | client: 6 | serviceUrl: 7 | defaultZone: http://localhost:8761/eureka/ 8 | #healthcheck: 9 | #enabled: true -------------------------------------------------------------------------------- /fastcam-spring-apigw/build.gradle.kts: -------------------------------------------------------------------------------- 1 | import org.jetbrains.kotlin.gradle.tasks.KotlinCompile 2 | 3 | plugins { 4 | id("org.springframework.boot") version "2.4.3" 5 | id("io.spring.dependency-management") version "1.0.11.RELEASE" 6 | kotlin("jvm") version "1.4.30" 7 | kotlin("plugin.spring") version "1.4.30" 8 | } 9 | 10 | group = "info.thecodinglive.spgw" 11 | version = "0.0.1-SNAPSHOT" 12 | java.sourceCompatibility = JavaVersion.VERSION_11 13 | 14 | configurations { 15 | compileOnly { 16 | extendsFrom(configurations.annotationProcessor.get()) 17 | } 18 | } 19 | 20 | repositories { 21 | jcenter() 22 | } 23 | 24 | dependencies { 25 | implementation("org.springframework.cloud:spring-cloud-starter-gateway") 26 | implementation("org.springframework.boot:spring-boot-starter-actuator") 27 | implementation("org.springframework.cloud:spring-cloud-starter-netflix-eureka-client") 28 | 29 | implementation("org.springframework.cloud:spring-cloud-starter-sleuth") 30 | implementation("org.springframework.cloud:spring-cloud-sleuth-zipkin") 31 | 32 | compileOnly("org.projectlombok:lombok") 33 | annotationProcessor("org.projectlombok:lombok") 34 | testImplementation("org.springframework.boot:spring-boot-starter-test") 35 | } 36 | 37 | dependencyManagement { 38 | imports { 39 | mavenBom ("org.springframework.cloud:spring-cloud-dependencies:2020.0.1") 40 | } 41 | } 42 | 43 | 44 | tasks.withType { 45 | kotlinOptions { 46 | freeCompilerArgs = listOf("-Xjsr305=strict") 47 | jvmTarget = "11" 48 | } 49 | } 50 | 51 | tasks.withType { 52 | useJUnitPlatform() 53 | } 54 | -------------------------------------------------------------------------------- /fastcam-spring-apigw/gradlew.bat: -------------------------------------------------------------------------------- 1 | @rem 2 | @rem Copyright 2015 the original author or authors. 3 | @rem 4 | @rem Licensed under the Apache License, Version 2.0 (the "License"); 5 | @rem you may not use this file except in compliance with the License. 6 | @rem You may obtain a copy of the License at 7 | @rem 8 | @rem https://www.apache.org/licenses/LICENSE-2.0 9 | @rem 10 | @rem Unless required by applicable law or agreed to in writing, software 11 | @rem distributed under the License is distributed on an "AS IS" BASIS, 12 | @rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | @rem See the License for the specific language governing permissions and 14 | @rem limitations under the License. 15 | @rem 16 | 17 | @if "%DEBUG%" == "" @echo off 18 | @rem ########################################################################## 19 | @rem 20 | @rem Gradle startup script for Windows 21 | @rem 22 | @rem ########################################################################## 23 | 24 | @rem Set local scope for the variables with windows NT shell 25 | if "%OS%"=="Windows_NT" setlocal 26 | 27 | set DIRNAME=%~dp0 28 | if "%DIRNAME%" == "" set DIRNAME=. 29 | set APP_BASE_NAME=%~n0 30 | set APP_HOME=%DIRNAME% 31 | 32 | @rem Resolve any "." and ".." in APP_HOME to make it shorter. 33 | for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi 34 | 35 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 36 | set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" 37 | 38 | @rem Find java.exe 39 | if defined JAVA_HOME goto findJavaFromJavaHome 40 | 41 | set JAVA_EXE=java.exe 42 | %JAVA_EXE% -version >NUL 2>&1 43 | if "%ERRORLEVEL%" == "0" goto execute 44 | 45 | echo. 46 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 47 | echo. 48 | echo Please set the JAVA_HOME variable in your environment to match the 49 | echo location of your Java installation. 50 | 51 | goto fail 52 | 53 | :findJavaFromJavaHome 54 | set JAVA_HOME=%JAVA_HOME:"=% 55 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe 56 | 57 | if exist "%JAVA_EXE%" goto execute 58 | 59 | echo. 60 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 61 | echo. 62 | echo Please set the JAVA_HOME variable in your environment to match the 63 | echo location of your Java installation. 64 | 65 | goto fail 66 | 67 | :execute 68 | @rem Setup the command line 69 | 70 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar 71 | 72 | 73 | @rem Execute Gradle 74 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* 75 | 76 | :end 77 | @rem End local scope for the variables with windows NT shell 78 | if "%ERRORLEVEL%"=="0" goto mainEnd 79 | 80 | :fail 81 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of 82 | rem the _cmd.exe /c_ return code! 83 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 84 | exit /b 1 85 | 86 | :mainEnd 87 | if "%OS%"=="Windows_NT" endlocal 88 | 89 | :omega 90 | -------------------------------------------------------------------------------- /fastcam-spring-apigw/out/production/resources/api-gw.yml: -------------------------------------------------------------------------------- 1 | spring.cloud: 2 | gateway: 3 | httpclient: 4 | connect-timeout: 500 5 | response-timeout: 1000 6 | routes: 7 | - id: post-service 8 | #dest 9 | uri: http://localhost:8080 10 | predicates: 11 | - Path=/v1.0/contents/** 12 | - id: time-service 13 | uri: http://localhost:8080 14 | predicates: 15 | - Path=/v1.0/newservice 16 | - After=2021-03-21T23:35:01.126+09:00[Asia/Seoul] 17 | - id: header-service 18 | uri: http://localhost:8080 19 | predicates: 20 | - Path=/v1.0/headservice 21 | - Header=X-PHOTO-API-VERSION, 1.0.0 22 | -------------------------------------------------------------------------------- /fastcam-spring-apigw/out/production/resources/application.yml: -------------------------------------------------------------------------------- 1 | server.port: 7090 2 | spring.application: 3 | name: hanbit-api-gw 4 | 5 | spring.config.import: api-gw.yml #,eureka-client.yml -------------------------------------------------------------------------------- /fastcam-spring-apigw/out/production/resources/eureka-client.yml: -------------------------------------------------------------------------------- 1 | eureka: 2 | instance: 3 | leaseRenewalIntervalInSeconds: 1 4 | leaseExpirationDurationInSeconds: 2 5 | client: 6 | serviceUrl: 7 | defaultZone: http://localhost:8761/eureka/ 8 | #healthcheck: 9 | #enabled: true -------------------------------------------------------------------------------- /fastcam-spring-apigw/src/main/java/info/thecodinglive/spgw/SpGwApp.java: -------------------------------------------------------------------------------- 1 | package info.thecodinglive.spgw; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | import org.springframework.cloud.client.discovery.EnableDiscoveryClient; 6 | 7 | 8 | @EnableDiscoveryClient 9 | @SpringBootApplication 10 | public class SpGwApp { 11 | public static void main(String ar[]) { 12 | SpringApplication.run(SpGwApp.class); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /fastcam-spring-apigw/src/main/java/info/thecodinglive/spgw/filters/errors/GWErrorResponse.java: -------------------------------------------------------------------------------- 1 | package info.thecodinglive.spgw.filters.errors; 2 | 3 | import lombok.Getter; 4 | 5 | import java.time.LocalDateTime; 6 | import java.util.HashMap; 7 | import java.util.Map; 8 | 9 | @Getter 10 | public class GWErrorResponse { 11 | private String errorMessage; 12 | private LocalDateTime localDateTime; 13 | private Map addtionInfos = new HashMap<>(); 14 | 15 | public GWErrorResponse(String errorMessage, LocalDateTime localDateTime) { 16 | this.errorMessage = errorMessage; 17 | this.localDateTime = localDateTime; 18 | } 19 | 20 | public static GWErrorResponse defaultBuild(String errorMessage) { 21 | return new GWErrorResponse(errorMessage, LocalDateTime.now()); 22 | } 23 | 24 | } 25 | -------------------------------------------------------------------------------- /fastcam-spring-apigw/src/main/java/info/thecodinglive/spgw/filters/errors/GlobalExceptionHandler.java: -------------------------------------------------------------------------------- 1 | package info.thecodinglive.spgw.filters.errors; 2 | 3 | import com.fasterxml.jackson.databind.ObjectMapper; 4 | import lombok.RequiredArgsConstructor; 5 | import lombok.extern.slf4j.Slf4j; 6 | import org.springframework.boot.web.reactive.error.ErrorWebExceptionHandler; 7 | import org.springframework.core.annotation.Order; 8 | import org.springframework.core.io.buffer.DataBufferFactory; 9 | import org.springframework.http.MediaType; 10 | import org.springframework.http.server.reactive.ServerHttpResponse; 11 | import org.springframework.stereotype.Component; 12 | import org.springframework.web.server.ResponseStatusException; 13 | import org.springframework.web.server.ServerWebExchange; 14 | import reactor.core.publisher.Mono; 15 | import org.springframework.web.bind.annotation.RestControllerAdvice; 16 | 17 | import java.util.stream.Stream; 18 | 19 | @Slf4j 20 | @Order(-1) 21 | @RequiredArgsConstructor 22 | //@Component 23 | public class GlobalExceptionHandler implements ErrorWebExceptionHandler { 24 | private final ObjectMapper objectMapper; 25 | 26 | @Override 27 | public Mono handle(ServerWebExchange exchange, Throwable ex) { 28 | ServerHttpResponse response = exchange.getResponse(); 29 | 30 | if (response.isCommitted()) { 31 | return Mono.error(ex); 32 | } 33 | 34 | //header 35 | response.getHeaders().setContentType(MediaType.APPLICATION_JSON); 36 | 37 | if (ex instanceof ResponseStatusException) { 38 | response.setStatusCode(((ResponseStatusException) ex).getStatus()); 39 | } 40 | 41 | return response 42 | .writeWith(Mono.fromSupplier(() -> { 43 | DataBufferFactory bufferFactory = response.bufferFactory(); 44 | try { 45 | GWErrorResponse gwErrorResponse = GWErrorResponse.defaultBuild(ex.getMessage()); 46 | byte[] errorResponse = objectMapper.writeValueAsBytes(gwErrorResponse); 47 | return bufferFactory.wrap(errorResponse); 48 | } catch (Exception e) { 49 | log.error("error", e); 50 | return bufferFactory.wrap(new byte[0]); 51 | } 52 | })); 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /fastcam-spring-apigw/src/main/resources/api-gw.yml: -------------------------------------------------------------------------------- 1 | spring.cloud: 2 | gateway: 3 | httpclient: 4 | connect-timeout: 500 5 | response-timeout: 1000 6 | routes: 7 | - id: post-service 8 | #dest 9 | uri: http://localhost:8080 10 | predicates: 11 | - Path=/v1.0/contents/** 12 | - id: time-service 13 | uri: http://localhost:8080 14 | predicates: 15 | - Path=/v1.0/newservice 16 | - After=2021-03-21T23:35:01.126+09:00[Asia/Seoul] 17 | - id: header-service 18 | uri: http://localhost:8080 19 | predicates: 20 | - Path=/v1.0/headservice 21 | - Header=X-PHOTO-API-VERSION, 1.0.0 22 | -------------------------------------------------------------------------------- /fastcam-spring-apigw/src/main/resources/application.yml: -------------------------------------------------------------------------------- 1 | server.port: 7090 2 | spring.application: 3 | name: hanbit-api-gw 4 | 5 | 6 | spring.config.import: api-gw.yml,eureka-client.yml 7 | 8 | 9 | spring.zipkin: 10 | base-url: http://localhost:9411 11 | 12 | spring.sleuth.sampler.probability: 1.0 13 | 14 | 15 | -------------------------------------------------------------------------------- /fastcam-spring-apigw/src/main/resources/eureka-client.yml: -------------------------------------------------------------------------------- 1 | eureka: 2 | instance: 3 | leaseRenewalIntervalInSeconds: 1 4 | leaseExpirationDurationInSeconds: 2 5 | client: 6 | serviceUrl: 7 | defaultZone: http://localhost:8761/eureka/ 8 | 9 | management: 10 | endpoints: 11 | web: 12 | exposure: 13 | include: "*" -------------------------------------------------------------------------------- /fastcam-spring-config-consumer/build.gradle.kts: -------------------------------------------------------------------------------- 1 | import org.jetbrains.kotlin.gradle.tasks.KotlinCompile 2 | 3 | plugins { 4 | id("org.springframework.boot") version "2.4.3" 5 | id("io.spring.dependency-management") version "1.0.11.RELEASE" 6 | kotlin("jvm") version "1.4.30" 7 | kotlin("plugin.spring") version "1.4.30" 8 | } 9 | 10 | group = "info.thecodinglive.config" 11 | version = "0.0.1-SNAPSHOT" 12 | java.sourceCompatibility = JavaVersion.VERSION_11 13 | 14 | configurations { 15 | compileOnly { 16 | extendsFrom(configurations.annotationProcessor.get()) 17 | } 18 | } 19 | 20 | repositories { 21 | jcenter() 22 | } 23 | 24 | dependencies { 25 | implementation("org.springframework.cloud:spring-cloud-config-client") 26 | implementation("org.springframework.cloud:spring-cloud-starter-bootstrap") 27 | implementation("org.springframework.boot:spring-boot-starter-actuator") 28 | implementation("org.springframework.boot:spring-boot-starter-web") 29 | 30 | 31 | compileOnly("org.projectlombok:lombok") 32 | annotationProcessor("org.projectlombok:lombok") 33 | } 34 | 35 | dependencyManagement { 36 | imports { 37 | mavenBom ("org.springframework.cloud:spring-cloud-dependencies:2020.0.1") 38 | } 39 | } 40 | 41 | 42 | tasks.withType { 43 | kotlinOptions { 44 | freeCompilerArgs = listOf("-Xjsr305=strict") 45 | jvmTarget = "11" 46 | } 47 | } 48 | 49 | tasks.withType { 50 | useJUnitPlatform() 51 | } 52 | -------------------------------------------------------------------------------- /fastcam-spring-config-consumer/gradlew.bat: -------------------------------------------------------------------------------- 1 | @rem 2 | @rem Copyright 2015 the original author or authors. 3 | @rem 4 | @rem Licensed under the Apache License, Version 2.0 (the "License"); 5 | @rem you may not use this file except in compliance with the License. 6 | @rem You may obtain a copy of the License at 7 | @rem 8 | @rem https://www.apache.org/licenses/LICENSE-2.0 9 | @rem 10 | @rem Unless required by applicable law or agreed to in writing, software 11 | @rem distributed under the License is distributed on an "AS IS" BASIS, 12 | @rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | @rem See the License for the specific language governing permissions and 14 | @rem limitations under the License. 15 | @rem 16 | 17 | @if "%DEBUG%" == "" @echo off 18 | @rem ########################################################################## 19 | @rem 20 | @rem Gradle startup script for Windows 21 | @rem 22 | @rem ########################################################################## 23 | 24 | @rem Set local scope for the variables with windows NT shell 25 | if "%OS%"=="Windows_NT" setlocal 26 | 27 | set DIRNAME=%~dp0 28 | if "%DIRNAME%" == "" set DIRNAME=. 29 | set APP_BASE_NAME=%~n0 30 | set APP_HOME=%DIRNAME% 31 | 32 | @rem Resolve any "." and ".." in APP_HOME to make it shorter. 33 | for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi 34 | 35 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 36 | set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" 37 | 38 | @rem Find java.exe 39 | if defined JAVA_HOME goto findJavaFromJavaHome 40 | 41 | set JAVA_EXE=java.exe 42 | %JAVA_EXE% -version >NUL 2>&1 43 | if "%ERRORLEVEL%" == "0" goto execute 44 | 45 | echo. 46 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 47 | echo. 48 | echo Please set the JAVA_HOME variable in your environment to match the 49 | echo location of your Java installation. 50 | 51 | goto fail 52 | 53 | :findJavaFromJavaHome 54 | set JAVA_HOME=%JAVA_HOME:"=% 55 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe 56 | 57 | if exist "%JAVA_EXE%" goto execute 58 | 59 | echo. 60 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 61 | echo. 62 | echo Please set the JAVA_HOME variable in your environment to match the 63 | echo location of your Java installation. 64 | 65 | goto fail 66 | 67 | :execute 68 | @rem Setup the command line 69 | 70 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar 71 | 72 | 73 | @rem Execute Gradle 74 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* 75 | 76 | :end 77 | @rem End local scope for the variables with windows NT shell 78 | if "%ERRORLEVEL%"=="0" goto mainEnd 79 | 80 | :fail 81 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of 82 | rem the _cmd.exe /c_ return code! 83 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 84 | exit /b 1 85 | 86 | :mainEnd 87 | if "%OS%"=="Windows_NT" endlocal 88 | 89 | :omega 90 | -------------------------------------------------------------------------------- /fastcam-spring-config-consumer/src/main/java/info/thecodinglive/cloud/ConfigConsumerApp.java: -------------------------------------------------------------------------------- 1 | package info.thecodinglive.cloud; 2 | 3 | import info.thecodinglive.cloud.config.ConfigProp; 4 | import lombok.extern.slf4j.Slf4j; 5 | import org.springframework.boot.CommandLineRunner; 6 | import org.springframework.boot.SpringApplication; 7 | import org.springframework.boot.autoconfigure.SpringBootApplication; 8 | import org.springframework.boot.context.properties.EnableConfigurationProperties; 9 | import org.springframework.cloud.context.config.annotation.RefreshScope; 10 | import org.springframework.scheduling.annotation.EnableScheduling; 11 | import org.springframework.scheduling.annotation.Scheduled; 12 | 13 | @Slf4j 14 | @RefreshScope 15 | @EnableScheduling 16 | @EnableConfigurationProperties(ConfigProp.class) 17 | @SpringBootApplication 18 | public class ConfigConsumerApp implements CommandLineRunner { 19 | private final ConfigProp configProp; 20 | 21 | @Override 22 | public void run(String... args) throws Exception { 23 | log.info("load configserver property : {}", configProp.toString()); 24 | } 25 | 26 | public ConfigConsumerApp(ConfigProp configProp) { 27 | this.configProp = configProp; 28 | } 29 | 30 | public static void main(String ar[]) { 31 | SpringApplication.run(ConfigConsumerApp.class, ar); 32 | } 33 | 34 | private void recheckProp() { 35 | log.info("property: {}", configProp.toString()); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /fastcam-spring-config-consumer/src/main/java/info/thecodinglive/cloud/config/ConfigChangeListener.java: -------------------------------------------------------------------------------- 1 | package info.thecodinglive.cloud.config; 2 | 3 | import lombok.extern.slf4j.Slf4j; 4 | import org.springframework.beans.factory.annotation.Autowired; 5 | import org.springframework.cloud.context.environment.EnvironmentChangeEvent; 6 | import org.springframework.context.ApplicationListener; 7 | import org.springframework.stereotype.Component; 8 | 9 | @Slf4j 10 | @Component 11 | public class ConfigChangeListener implements ApplicationListener { 12 | @Autowired ConfigProp configProp; 13 | 14 | @Override 15 | public void onApplicationEvent(EnvironmentChangeEvent event) { 16 | //if(event.getKeys().contains("username")) 17 | log.info("event key: {}", event.getKeys().toString()); 18 | //configProp.ref 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /fastcam-spring-config-consumer/src/main/java/info/thecodinglive/cloud/config/ConfigController.java: -------------------------------------------------------------------------------- 1 | package info.thecodinglive.cloud.config; 2 | 3 | import lombok.RequiredArgsConstructor; 4 | import org.springframework.beans.factory.annotation.Autowired; 5 | import org.springframework.cloud.context.config.annotation.RefreshScope; 6 | import org.springframework.context.annotation.Scope; 7 | import org.springframework.web.bind.annotation.GetMapping; 8 | import org.springframework.web.bind.annotation.RestController; 9 | import org.springframework.web.context.annotation.RequestScope; 10 | 11 | 12 | @RequiredArgsConstructor 13 | @RestController 14 | public class ConfigController { 15 | private final ConfigMgmt configMgmt; 16 | 17 | @GetMapping("/v1/check/prop") 18 | public String findPropMessage() { 19 | return configMgmt.getConfigProperty().toString(); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /fastcam-spring-config-consumer/src/main/java/info/thecodinglive/cloud/config/ConfigMgmt.java: -------------------------------------------------------------------------------- 1 | package info.thecodinglive.cloud.config; 2 | 3 | import lombok.RequiredArgsConstructor; 4 | import org.springframework.beans.factory.ObjectProvider; 5 | import org.springframework.cloud.context.config.annotation.RefreshScope; 6 | import org.springframework.stereotype.Component; 7 | import org.springframework.stereotype.Service; 8 | 9 | @Component 10 | @RequiredArgsConstructor 11 | public class ConfigMgmt { 12 | private final ObjectProvider configProps; 13 | 14 | public ConfigProp getConfigProperty() { 15 | return configProps.getIfAvailable(); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /fastcam-spring-config-consumer/src/main/java/info/thecodinglive/cloud/config/ConfigProp.java: -------------------------------------------------------------------------------- 1 | package info.thecodinglive.cloud.config; 2 | 3 | import lombok.Data; 4 | import org.springframework.boot.context.properties.ConfigurationProperties; 5 | import org.springframework.cloud.context.config.annotation.RefreshScope; 6 | import org.springframework.stereotype.Component; 7 | 8 | 9 | @RefreshScope 10 | @Data 11 | @ConfigurationProperties("mongodbserver") 12 | public class ConfigProp { 13 | private String url; 14 | private String username; 15 | private String password; 16 | } 17 | -------------------------------------------------------------------------------- /fastcam-spring-config-consumer/src/main/java/info/thecodinglive/cloud/config/TestController.java: -------------------------------------------------------------------------------- 1 | package info.thecodinglive.cloud.config; 2 | 3 | import org.springframework.web.bind.annotation.GetMapping; 4 | import org.springframework.web.bind.annotation.RestController; 5 | 6 | @RestController 7 | public class TestController { 8 | 9 | @GetMapping("/v1.1/test") 10 | public String hello() { 11 | return "hello"; 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /fastcam-spring-config-consumer/src/main/resources/application.yml: -------------------------------------------------------------------------------- 1 | server.port: 9093 2 | 3 | # config server property yml file name 4 | 5 | management: 6 | endpoints: 7 | web: 8 | exposure: 9 | include: ['refresh','beans','env'] 10 | 11 | logging: 12 | level: 13 | org.springframework: TRACE 14 | -------------------------------------------------------------------------------- /fastcam-spring-config-consumer/src/main/resources/bootstrap.yml: -------------------------------------------------------------------------------- 1 | spring: 2 | application: 3 | name: mongo 4 | -------------------------------------------------------------------------------- /fastcam-spring-config/build.gradle.kts: -------------------------------------------------------------------------------- 1 | import org.jetbrains.kotlin.gradle.tasks.KotlinCompile 2 | 3 | plugins { 4 | id("org.springframework.boot") version "2.4.3" 5 | id("io.spring.dependency-management") version "1.0.11.RELEASE" 6 | kotlin("jvm") version "1.4.30" 7 | kotlin("plugin.spring") version "1.4.30" 8 | } 9 | 10 | group = "info.thecodinglive.config" 11 | version = "0.0.1-SNAPSHOT" 12 | java.sourceCompatibility = JavaVersion.VERSION_11 13 | 14 | configurations { 15 | compileOnly { 16 | extendsFrom(configurations.annotationProcessor.get()) 17 | } 18 | } 19 | 20 | repositories { 21 | jcenter() 22 | } 23 | 24 | dependencies { 25 | implementation("org.springframework.cloud:spring-cloud-config-server") 26 | } 27 | 28 | dependencyManagement { 29 | imports { 30 | mavenBom ("org.springframework.cloud:spring-cloud-dependencies:2020.0.1") 31 | } 32 | } 33 | 34 | 35 | tasks.withType { 36 | kotlinOptions { 37 | freeCompilerArgs = listOf("-Xjsr305=strict") 38 | jvmTarget = "11" 39 | } 40 | } 41 | 42 | tasks.withType { 43 | useJUnitPlatform() 44 | } 45 | -------------------------------------------------------------------------------- /fastcam-spring-config/gradlew.bat: -------------------------------------------------------------------------------- 1 | @rem 2 | @rem Copyright 2015 the original author or authors. 3 | @rem 4 | @rem Licensed under the Apache License, Version 2.0 (the "License"); 5 | @rem you may not use this file except in compliance with the License. 6 | @rem You may obtain a copy of the License at 7 | @rem 8 | @rem https://www.apache.org/licenses/LICENSE-2.0 9 | @rem 10 | @rem Unless required by applicable law or agreed to in writing, software 11 | @rem distributed under the License is distributed on an "AS IS" BASIS, 12 | @rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | @rem See the License for the specific language governing permissions and 14 | @rem limitations under the License. 15 | @rem 16 | 17 | @if "%DEBUG%" == "" @echo off 18 | @rem ########################################################################## 19 | @rem 20 | @rem Gradle startup script for Windows 21 | @rem 22 | @rem ########################################################################## 23 | 24 | @rem Set local scope for the variables with windows NT shell 25 | if "%OS%"=="Windows_NT" setlocal 26 | 27 | set DIRNAME=%~dp0 28 | if "%DIRNAME%" == "" set DIRNAME=. 29 | set APP_BASE_NAME=%~n0 30 | set APP_HOME=%DIRNAME% 31 | 32 | @rem Resolve any "." and ".." in APP_HOME to make it shorter. 33 | for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi 34 | 35 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 36 | set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" 37 | 38 | @rem Find java.exe 39 | if defined JAVA_HOME goto findJavaFromJavaHome 40 | 41 | set JAVA_EXE=java.exe 42 | %JAVA_EXE% -version >NUL 2>&1 43 | if "%ERRORLEVEL%" == "0" goto execute 44 | 45 | echo. 46 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 47 | echo. 48 | echo Please set the JAVA_HOME variable in your environment to match the 49 | echo location of your Java installation. 50 | 51 | goto fail 52 | 53 | :findJavaFromJavaHome 54 | set JAVA_HOME=%JAVA_HOME:"=% 55 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe 56 | 57 | if exist "%JAVA_EXE%" goto execute 58 | 59 | echo. 60 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 61 | echo. 62 | echo Please set the JAVA_HOME variable in your environment to match the 63 | echo location of your Java installation. 64 | 65 | goto fail 66 | 67 | :execute 68 | @rem Setup the command line 69 | 70 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar 71 | 72 | 73 | @rem Execute Gradle 74 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* 75 | 76 | :end 77 | @rem End local scope for the variables with windows NT shell 78 | if "%ERRORLEVEL%"=="0" goto mainEnd 79 | 80 | :fail 81 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of 82 | rem the _cmd.exe /c_ return code! 83 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 84 | exit /b 1 85 | 86 | :mainEnd 87 | if "%OS%"=="Windows_NT" endlocal 88 | 89 | :omega 90 | -------------------------------------------------------------------------------- /fastcam-spring-config/out/production/resources/app12.yml: -------------------------------------------------------------------------------- 1 | spring.cloud.stream.function.definition=supplier;receiveAndForward;receive 2 | 3 | spring.cloud.stream.kafka.binder.configuration.schema.registry.url=http://localhost:8081 4 | 5 | spring.cloud.stream.bindings.supplier-out-0.destination=sensor-1 6 | spring.cloud.stream.bindings.supplier-out-0.producer.use-native-encoding=true 7 | spring.cloud.stream.kafka.bindings.supplier-out-0.producer.configuration.value.serializer=io.confluent.kafka.serializers.KafkaAvroSerializer 8 | spring.cloud.stream.kafka.bindings.supplier-out-0.producer.configuration.schema.registry.url=http://localhost:8081 9 | 10 | spring.cloud.stream.bindings.receiveAndForward-in-0.destination=sensor-1 11 | spring.cloud.stream.bindings.receiveAndForward-in-0.consumer.use-native-decoding=true 12 | spring.cloud.stream.kafka.bindings.receiveAndForward-in-0.consumer.configuration.value.deserializer=io.confluent.kafka.serializers.KafkaAvroDeserializer 13 | spring.cloud.stream.kafka.bindings.receiveAndForward-in-0.consumer.configuration.schema.registry.url=http://localhost:8081 14 | spring.cloud.stream.kafka.bindings.receiveAndForward-in-0.consumer.configuration.specific.avro.reader: true 15 | 16 | #streambridge 17 | spring.cloud.stream.source=sensor 18 | spring.cloud.stream.bindings.sensor-out-0.destination=sensor-2 19 | spring.cloud.stream.bindings.sensor-out-0.producer.use-native-encoding=true 20 | spring.cloud.stream.kafka.bindings.sensor-out-0.producer.configuration.value.serializer=io.confluent.kafka.serializers.KafkaAvroSerializer 21 | spring.cloud.stream.kafka.bindings.sensor-out-0.producer.configuration.schema.registry.url=http://localhost:8081 22 | 23 | spring.cloud.stream.bindings.receive-in-0.destination=sensor-2 24 | spring.cloud.stream.bindings.receive-in-0.consumer.use-native-decoding=true 25 | spring.cloud.stream.kafka.bindings.receive-in-0.consumer.configuration.value.deserializer=io.confluent.kafka.serializers.KafkaAvroDeserializer 26 | spring.cloud.stream.kafka.bindings.receive-in-0.consumer.configuration.schema.registry.url=http://localhost:8081 27 | spring.cloud.stream.kafka.bindings.receive-in-0.consumer.configuration.specific.avro.reader: true 28 | 29 | spring.cloud.stream.poller.fixed-delay=10000 -------------------------------------------------------------------------------- /fastcam-spring-config/out/production/resources/application.properties: -------------------------------------------------------------------------------- 1 | spring.cloud.stream.function.definition=supplier;receiveAndForward;receive 2 | 3 | spring.cloud.stream.bindings.supplier-out-0.destination=sensor-1 4 | spring.cloud.stream.bindings.supplier-out-0.producer.use-native-encoding=true 5 | 6 | spring.cloud.stream.bindings.receiveAndForward-in-0.destination=sensor-1 7 | spring.cloud.stream.bindings.receiveAndForward-in-0.consumer.use-native-decoding=true 8 | 9 | 10 | #streambridge 11 | spring.cloud.stream.source=sensor 12 | spring.cloud.stream.bindings.sensor-out-0.destination=sensor-2 13 | spring.cloud.stream.bindings.sensor-out-0.producer.use-native-encoding=true 14 | 15 | spring.cloud.stream.bindings.receive-in-0.destination=sensor-2 16 | spring.cloud.stream.bindings.receive-in-0.consumer.use-native-decoding=true 17 | spring.cloud.stream.poller.fixed-delay=10000 18 | 19 | spring.kafka.producer.key-serializer: org.apache.kafka.common.serialization.StringSerializer 20 | spring.kafka.producer.value-serializer: org.springframework.kafka.support.serializer.JsonSerializer 21 | 22 | spring.kafka.consumer.key-deserializer: org.apache.kafka.common.serialization.StringDeserializer 23 | spring.kafka.consumer.value-deserializer: org.springframework.kafka.support.serializer.JsonDeserializer 24 | spring.kafka.consumer.properties.spring.json.trusted.packages=* -------------------------------------------------------------------------------- /fastcam-spring-config/out/production/resources/application.yml: -------------------------------------------------------------------------------- 1 | server.port: 8888 2 | 3 | spring: 4 | application: 5 | name: config-server 6 | profiles: 7 | active: native 8 | cloud: 9 | config.server.native: 10 | search-locations: classpath:/config 11 | 12 | management: 13 | endpoints: 14 | web: 15 | exposure: 16 | include: "*" 17 | endpoint: 18 | shutdown: 19 | enabled: true 20 | -------------------------------------------------------------------------------- /fastcam-spring-config/out/production/resources/config/mongo-dev.yml: -------------------------------------------------------------------------------- 1 | mongodbserver: 2 | url: 168.126.63.1 3 | username: testUser 4 | password: pass -------------------------------------------------------------------------------- /fastcam-spring-config/out/production/resources/config/mongo-real.yml: -------------------------------------------------------------------------------- 1 | mongodbserver: 2 | url: 168.126.63.1 3 | username: testUser 4 | password: pass -------------------------------------------------------------------------------- /fastcam-spring-config/src/main/java/info/thecodinglive/cloud/ConfigServer.java: -------------------------------------------------------------------------------- 1 | package info.thecodinglive.cloud; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | import org.springframework.cloud.config.server.EnableConfigServer; 6 | 7 | @SpringBootApplication 8 | @EnableConfigServer 9 | public class ConfigServer { 10 | public static void main(String ar[]) { 11 | SpringApplication.run(ConfigServer.class, ar); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /fastcam-spring-config/src/main/resources/application.yml: -------------------------------------------------------------------------------- 1 | server.port: 8888 2 | 3 | spring: 4 | application: 5 | name: config-server 6 | profiles: 7 | active: native 8 | cloud: 9 | config.server.native: 10 | search-locations: classpath:/config 11 | 12 | management: 13 | endpoints: 14 | web: 15 | exposure: 16 | include: ['refresh','beans','env'] -------------------------------------------------------------------------------- /fastcam-spring-config/src/main/resources/config/mongo-default.yml: -------------------------------------------------------------------------------- 1 | mongodbserver: 2 | url: 168.126.63.1 3 | username: tesBBBB 4 | password: passFAIL -------------------------------------------------------------------------------- /fastcam-spring-config/src/main/resources/config/mongo-dev.yml: -------------------------------------------------------------------------------- 1 | mongodbserver: 2 | url: 168.126.63.1 3 | username: testUser 4 | password: pass -------------------------------------------------------------------------------- /fastcam-spring-config/src/main/resources/config/mongo-real.yml: -------------------------------------------------------------------------------- 1 | mongodbserver: 2 | url: 168.126.63.1 3 | username: testUser 4 | password: pass -------------------------------------------------------------------------------- /fastcam-spring-eureka/build.gradle.kts: -------------------------------------------------------------------------------- 1 | import org.jetbrains.kotlin.gradle.tasks.KotlinCompile 2 | 3 | plugins { 4 | id("org.springframework.boot") version "2.4.3" 5 | id("io.spring.dependency-management") version "1.0.11.RELEASE" 6 | kotlin("jvm") version "1.4.30" 7 | kotlin("plugin.spring") version "1.4.30" 8 | } 9 | 10 | group = "info.thecodinglive.springCloud" 11 | version = "0.0.1-SNAPSHOT" 12 | java.sourceCompatibility = JavaVersion.VERSION_11 13 | 14 | configurations { 15 | compileOnly { 16 | extendsFrom(configurations.annotationProcessor.get()) 17 | } 18 | } 19 | 20 | repositories { 21 | jcenter() 22 | } 23 | 24 | dependencies { 25 | implementation("org.springframework.cloud:spring-cloud-starter-netflix-eureka-server") 26 | implementation("org.springframework.cloud:spring-cloud-starter-sleuth") 27 | implementation("org.springframework.cloud:spring-cloud-sleuth-zipkin") 28 | 29 | compileOnly("org.projectlombok:lombok") 30 | annotationProcessor("org.projectlombok:lombok") 31 | testImplementation("org.springframework.boot:spring-boot-starter-test") 32 | } 33 | 34 | dependencyManagement { 35 | imports { 36 | mavenBom ("org.springframework.cloud:spring-cloud-dependencies:2020.0.1") 37 | } 38 | } 39 | 40 | 41 | 42 | tasks.withType { 43 | kotlinOptions { 44 | freeCompilerArgs = listOf("-Xjsr305=strict") 45 | jvmTarget = "11" 46 | } 47 | } 48 | 49 | tasks.withType { 50 | useJUnitPlatform() 51 | } 52 | -------------------------------------------------------------------------------- /fastcam-spring-eureka/gradlew.bat: -------------------------------------------------------------------------------- 1 | @rem 2 | @rem Copyright 2015 the original author or authors. 3 | @rem 4 | @rem Licensed under the Apache License, Version 2.0 (the "License"); 5 | @rem you may not use this file except in compliance with the License. 6 | @rem You may obtain a copy of the License at 7 | @rem 8 | @rem https://www.apache.org/licenses/LICENSE-2.0 9 | @rem 10 | @rem Unless required by applicable law or agreed to in writing, software 11 | @rem distributed under the License is distributed on an "AS IS" BASIS, 12 | @rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | @rem See the License for the specific language governing permissions and 14 | @rem limitations under the License. 15 | @rem 16 | 17 | @if "%DEBUG%" == "" @echo off 18 | @rem ########################################################################## 19 | @rem 20 | @rem Gradle startup script for Windows 21 | @rem 22 | @rem ########################################################################## 23 | 24 | @rem Set local scope for the variables with windows NT shell 25 | if "%OS%"=="Windows_NT" setlocal 26 | 27 | set DIRNAME=%~dp0 28 | if "%DIRNAME%" == "" set DIRNAME=. 29 | set APP_BASE_NAME=%~n0 30 | set APP_HOME=%DIRNAME% 31 | 32 | @rem Resolve any "." and ".." in APP_HOME to make it shorter. 33 | for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi 34 | 35 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 36 | set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" 37 | 38 | @rem Find java.exe 39 | if defined JAVA_HOME goto findJavaFromJavaHome 40 | 41 | set JAVA_EXE=java.exe 42 | %JAVA_EXE% -version >NUL 2>&1 43 | if "%ERRORLEVEL%" == "0" goto execute 44 | 45 | echo. 46 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 47 | echo. 48 | echo Please set the JAVA_HOME variable in your environment to match the 49 | echo location of your Java installation. 50 | 51 | goto fail 52 | 53 | :findJavaFromJavaHome 54 | set JAVA_HOME=%JAVA_HOME:"=% 55 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe 56 | 57 | if exist "%JAVA_EXE%" goto execute 58 | 59 | echo. 60 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 61 | echo. 62 | echo Please set the JAVA_HOME variable in your environment to match the 63 | echo location of your Java installation. 64 | 65 | goto fail 66 | 67 | :execute 68 | @rem Setup the command line 69 | 70 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar 71 | 72 | 73 | @rem Execute Gradle 74 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* 75 | 76 | :end 77 | @rem End local scope for the variables with windows NT shell 78 | if "%ERRORLEVEL%"=="0" goto mainEnd 79 | 80 | :fail 81 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of 82 | rem the _cmd.exe /c_ return code! 83 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 84 | exit /b 1 85 | 86 | :mainEnd 87 | if "%OS%"=="Windows_NT" endlocal 88 | 89 | :omega 90 | -------------------------------------------------------------------------------- /fastcam-spring-eureka/src/main/java/info/thecodinglive/eureka/EurekaServerApp.java: -------------------------------------------------------------------------------- 1 | package info.thecodinglive.eureka; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer; 6 | 7 | @EnableEurekaServer 8 | @SpringBootApplication 9 | public class EurekaServerApp { 10 | public static void main(String ar[]) { 11 | SpringApplication.run(EurekaServerApp.class); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /fastcam-spring-eureka/src/main/resources/application.yml: -------------------------------------------------------------------------------- 1 | 2 | 3 | spring.sleuth.sampler.probability: 1.0 4 | server.port: 8761 5 | 6 | -------------------------------------------------------------------------------- /fastcam-spring-kafka/build.gradle.kts: -------------------------------------------------------------------------------- 1 | import org.jetbrains.kotlin.gradle.tasks.KotlinCompile 2 | 3 | plugins { 4 | id("org.springframework.boot") version "2.4.3" 5 | id("io.spring.dependency-management") version "1.0.11.RELEASE" 6 | kotlin("jvm") version "1.4.30" 7 | kotlin("plugin.spring") version "1.4.30" 8 | } 9 | 10 | group = "info.thecodinglive.kafka" 11 | version = "0.0.1-SNAPSHOT" 12 | java.sourceCompatibility = JavaVersion.VERSION_11 13 | 14 | configurations { 15 | compileOnly { 16 | extendsFrom(configurations.annotationProcessor.get()) 17 | } 18 | } 19 | 20 | repositories { 21 | jcenter() 22 | } 23 | 24 | dependencies { 25 | implementation("org.springframework.boot:spring-boot-starter-web") 26 | implementation("org.springframework.kafka:spring-kafka:2.6.7") 27 | 28 | testImplementation("org.springframework.boot:spring-boot-starter-test") 29 | } 30 | 31 | dependencyManagement { 32 | imports { 33 | mavenBom ("org.springframework.cloud:spring-cloud-dependencies:2020.0.1") 34 | } 35 | } 36 | 37 | 38 | tasks.withType { 39 | kotlinOptions { 40 | freeCompilerArgs = listOf("-Xjsr305=strict") 41 | jvmTarget = "11" 42 | } 43 | } 44 | 45 | tasks.withType { 46 | useJUnitPlatform() 47 | } 48 | -------------------------------------------------------------------------------- /fastcam-spring-kafka/docker/docker-compose.yml: -------------------------------------------------------------------------------- 1 | version: '2' 2 | services: 3 | zookeeper: 4 | image: wurstmeister/zookeeper 5 | container_name: zookeeper 6 | ports: 7 | - "12181:2181" 8 | kafka: 9 | image: wurstmeister/kafka:2.12-2.5.0 10 | container_name: kafka 11 | ports: 12 | - "9092:9092" 13 | environment: 14 | KAFKA_ADVERTISED_HOST_NAME: 127.0.0.1 15 | KAFKA_CREATE_TOPICS: "thecodinglive" 16 | KAFKA_ZOOKEEPER_CONNECT: zookeeper:2181 17 | volumes: 18 | - /var/run/docker.sock:/var/run/docker.sock -------------------------------------------------------------------------------- /fastcam-spring-kafka/gradlew.bat: -------------------------------------------------------------------------------- 1 | @rem 2 | @rem Copyright 2015 the original author or authors. 3 | @rem 4 | @rem Licensed under the Apache License, Version 2.0 (the "License"); 5 | @rem you may not use this file except in compliance with the License. 6 | @rem You may obtain a copy of the License at 7 | @rem 8 | @rem https://www.apache.org/licenses/LICENSE-2.0 9 | @rem 10 | @rem Unless required by applicable law or agreed to in writing, software 11 | @rem distributed under the License is distributed on an "AS IS" BASIS, 12 | @rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | @rem See the License for the specific language governing permissions and 14 | @rem limitations under the License. 15 | @rem 16 | 17 | @if "%DEBUG%" == "" @echo off 18 | @rem ########################################################################## 19 | @rem 20 | @rem Gradle startup script for Windows 21 | @rem 22 | @rem ########################################################################## 23 | 24 | @rem Set local scope for the variables with windows NT shell 25 | if "%OS%"=="Windows_NT" setlocal 26 | 27 | set DIRNAME=%~dp0 28 | if "%DIRNAME%" == "" set DIRNAME=. 29 | set APP_BASE_NAME=%~n0 30 | set APP_HOME=%DIRNAME% 31 | 32 | @rem Resolve any "." and ".." in APP_HOME to make it shorter. 33 | for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi 34 | 35 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 36 | set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" 37 | 38 | @rem Find java.exe 39 | if defined JAVA_HOME goto findJavaFromJavaHome 40 | 41 | set JAVA_EXE=java.exe 42 | %JAVA_EXE% -version >NUL 2>&1 43 | if "%ERRORLEVEL%" == "0" goto execute 44 | 45 | echo. 46 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 47 | echo. 48 | echo Please set the JAVA_HOME variable in your environment to match the 49 | echo location of your Java installation. 50 | 51 | goto fail 52 | 53 | :findJavaFromJavaHome 54 | set JAVA_HOME=%JAVA_HOME:"=% 55 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe 56 | 57 | if exist "%JAVA_EXE%" goto execute 58 | 59 | echo. 60 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 61 | echo. 62 | echo Please set the JAVA_HOME variable in your environment to match the 63 | echo location of your Java installation. 64 | 65 | goto fail 66 | 67 | :execute 68 | @rem Setup the command line 69 | 70 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar 71 | 72 | 73 | @rem Execute Gradle 74 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* 75 | 76 | :end 77 | @rem End local scope for the variables with windows NT shell 78 | if "%ERRORLEVEL%"=="0" goto mainEnd 79 | 80 | :fail 81 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of 82 | rem the _cmd.exe /c_ return code! 83 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 84 | exit /b 1 85 | 86 | :mainEnd 87 | if "%OS%"=="Windows_NT" endlocal 88 | 89 | :omega 90 | -------------------------------------------------------------------------------- /fastcam-spring-kafka/out/production/resources/application.yml: -------------------------------------------------------------------------------- 1 | #producer etc default 2 | spring.kafka: 3 | bootstrap-servers: 127.0.0.1:9092 4 | 5 | #consumer 6 | spring.kafka.consumer: 7 | bootstrap-servers: 127.0.0.1:9092 8 | group-id: thecodinglive 9 | enable-auto-commit: true 10 | auto-commit-interval: 1000ms 11 | auto-offset-reset: latest -------------------------------------------------------------------------------- /fastcam-spring-kafka/src/main/java/info/thecodinglive/kafka/KafkaApp.java: -------------------------------------------------------------------------------- 1 | package info.thecodinglive.kafka; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | 6 | @SpringBootApplication 7 | public class KafkaApp { 8 | public static void main(String ar[]) { 9 | SpringApplication.run(KafkaApp.class, ar); 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /fastcam-spring-kafka/src/main/java/info/thecodinglive/kafka/eventService/EventController.java: -------------------------------------------------------------------------------- 1 | package info.thecodinglive.kafka.eventService; 2 | 3 | import org.springframework.beans.factory.annotation.Autowired; 4 | import org.springframework.web.bind.annotation.GetMapping; 5 | import org.springframework.web.bind.annotation.RestController; 6 | 7 | @RestController 8 | public class EventController { 9 | @Autowired 10 | MyEventService myEventService; 11 | 12 | @GetMapping("/event") 13 | public String getEvent() { 14 | myEventService.sendMsg(); 15 | return "OK"; 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /fastcam-spring-kafka/src/main/java/info/thecodinglive/kafka/eventService/FastcamJacksonConverter.java: -------------------------------------------------------------------------------- 1 | package info.thecodinglive.kafka.eventService; 2 | 3 | import com.fasterxml.jackson.annotation.JsonInclude; 4 | import com.fasterxml.jackson.core.type.TypeReference; 5 | import com.fasterxml.jackson.databind.DeserializationFeature; 6 | import com.fasterxml.jackson.databind.ObjectMapper; 7 | import com.fasterxml.jackson.databind.SerializationFeature; 8 | import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule; 9 | 10 | public class FastcamJacksonConverter { 11 | private static final ObjectMapper mapper; 12 | 13 | static { 14 | mapper = new ObjectMapper() 15 | .setSerializationInclusion(JsonInclude.Include.NON_NULL) 16 | .configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false) 17 | .configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false) 18 | .configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false) 19 | .configure(DeserializationFeature.ADJUST_DATES_TO_CONTEXT_TIME_ZONE, false) 20 | .registerModule(new JavaTimeModule()); 21 | } 22 | 23 | private FastcamJacksonConverter() { 24 | throw new RuntimeException("construct not support"); 25 | } 26 | 27 | public static ObjectMapper getInstance() { 28 | return mapper; 29 | } 30 | 31 | public static String toJson(Object value) { 32 | try{ 33 | return mapper.writeValueAsString(value); 34 | } catch (Exception e) { 35 | throw new RuntimeException("convert error"); 36 | } 37 | } 38 | 39 | public static T toObject(String content, Class valueType) { 40 | try { 41 | return mapper.readValue(content, valueType); 42 | } catch (Exception e) { 43 | throw new RuntimeException("convert error"); 44 | } 45 | } 46 | 47 | public static T toObject(String content, TypeReference type) { 48 | try { 49 | return mapper.readValue(content, type); 50 | } catch (Exception e) { 51 | throw new RuntimeException("convert error"); 52 | } 53 | } 54 | 55 | public static T convert(Object obj, Class type) { 56 | try { 57 | return mapper.convertValue(obj, type); 58 | } catch (Exception e) { 59 | throw new RuntimeException("convert error"); 60 | } 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /fastcam-spring-kafka/src/main/java/info/thecodinglive/kafka/eventService/MyEvent.java: -------------------------------------------------------------------------------- 1 | package info.thecodinglive.kafka.eventService; 2 | 3 | import java.util.Map; 4 | import java.util.UUID; 5 | 6 | public class MyEvent { 7 | 8 | private String eventId; 9 | private Map myData; 10 | 11 | 12 | public MyEvent(Map myData) { 13 | this.eventId = UUID.randomUUID().toString(); 14 | this.myData = myData; 15 | } 16 | 17 | public String getEventId() { 18 | return eventId; 19 | } 20 | 21 | public Map getMyData() { 22 | return myData; 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /fastcam-spring-kafka/src/main/java/info/thecodinglive/kafka/eventService/MyEventService.java: -------------------------------------------------------------------------------- 1 | package info.thecodinglive.kafka.eventService; 2 | 3 | import info.thecodinglive.kafka.sender.KafkaProducer; 4 | import org.springframework.beans.factory.annotation.Autowired; 5 | import org.springframework.stereotype.Service; 6 | 7 | import java.util.HashMap; 8 | import java.util.Map; 9 | 10 | 11 | @Service 12 | public class MyEventService { 13 | @Autowired 14 | private KafkaProducer kafkaProducer; 15 | 16 | public void sendMsg() { 17 | Map data = new HashMap<>(); 18 | data.put("width", 1020); 19 | data.put("height", 7090); 20 | 21 | kafkaProducer.send(KafkaProducer.TOPIC_NAME, new MyEvent(data)); 22 | } 23 | 24 | } 25 | -------------------------------------------------------------------------------- /fastcam-spring-kafka/src/main/java/info/thecodinglive/kafka/receiver/KafkaReceiver.java: -------------------------------------------------------------------------------- 1 | package info.thecodinglive.kafka.receiver; 2 | 3 | import org.springframework.kafka.annotation.KafkaListener; 4 | import org.springframework.stereotype.Component; 5 | 6 | import static info.thecodinglive.kafka.sender.KafkaProducer.TOPIC_NAME; 7 | 8 | @Component 9 | public class KafkaReceiver { 10 | @KafkaListener(topics = TOPIC_NAME, autoStartup = "true") 11 | public void eventHandler(Object event) { 12 | System.out.println("get data: "+ event); 13 | } 14 | 15 | } 16 | -------------------------------------------------------------------------------- /fastcam-spring-kafka/src/main/java/info/thecodinglive/kafka/sender/KafkaProducer.java: -------------------------------------------------------------------------------- 1 | package info.thecodinglive.kafka.sender; 2 | 3 | import info.thecodinglive.utils.jackson.FastcamJacksonConverter; 4 | import org.springframework.beans.factory.annotation.Autowired; 5 | import org.springframework.kafka.core.KafkaTemplate; 6 | import org.springframework.stereotype.Component; 7 | 8 | @Component 9 | public class KafkaProducer { 10 | public static final String TOPIC_NAME = "thecodinglive"; 11 | 12 | @Autowired 13 | private KafkaTemplate kafkaTemplate; 14 | 15 | public void send(String topic, Object data) { 16 | try { 17 | kafkaTemplate.send(topic, FastcamJacksonConverter.toJson(data)); 18 | } catch (Exception e) { 19 | System.err.println("error" + e.getMessage()); 20 | } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /fastcam-spring-kafka/src/main/resources/application.yml: -------------------------------------------------------------------------------- 1 | #producer etc default 2 | spring.kafka: 3 | bootstrap-servers: 127.0.0.1:9092 4 | 5 | #consumer 6 | spring.kafka.consumer: 7 | bootstrap-servers: 127.0.0.1:9092 8 | group-id: thecodinglive 9 | enable-auto-commit: true 10 | auto-commit-interval: 1000ms 11 | auto-offset-reset: latest -------------------------------------------------------------------------------- /fastcam-spring-kafka/src/test/java/info/thecodinglive/kafka/SenderTest.java: -------------------------------------------------------------------------------- 1 | package info.thecodinglive.kafka; 2 | 3 | import info.thecodinglive.kafka.sender.KafkaProducer; 4 | import org.junit.jupiter.api.Test; 5 | import org.junit.jupiter.api.extension.ExtendWith; 6 | import org.springframework.beans.factory.annotation.Autowired; 7 | import org.springframework.boot.test.context.SpringBootTest; 8 | import org.springframework.test.context.junit.jupiter.SpringExtension; 9 | 10 | @SpringBootTest 11 | @ExtendWith(SpringExtension.class) 12 | public class SenderTest { 13 | 14 | @Autowired 15 | private KafkaProducer producer; 16 | 17 | @Test 18 | void sendMsg() { 19 | //send String 20 | producer.send("thecodinglive", "hello kafka"); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /fastcam-spring-rabbitmq/build.gradle.kts: -------------------------------------------------------------------------------- 1 | import org.jetbrains.kotlin.gradle.tasks.KotlinCompile 2 | 3 | plugins { 4 | id("org.springframework.boot") version "2.4.3" 5 | id("io.spring.dependency-management") version "1.0.11.RELEASE" 6 | kotlin("jvm") version "1.4.30" 7 | kotlin("plugin.spring") version "1.4.30" 8 | } 9 | 10 | group = "info.thecodinglive.rabbitmq" 11 | version = "0.0.1-SNAPSHOT" 12 | java.sourceCompatibility = JavaVersion.VERSION_11 13 | 14 | configurations { 15 | compileOnly { 16 | extendsFrom(configurations.annotationProcessor.get()) 17 | } 18 | } 19 | 20 | repositories { 21 | jcenter() 22 | } 23 | 24 | dependencies { 25 | implementation("org.springframework.boot:spring-boot-starter-web") 26 | implementation("org.springframework.boot:spring-boot-starter-amqp") 27 | 28 | compileOnly("org.projectlombok:lombok") 29 | annotationProcessor("org.projectlombok:lombok") 30 | 31 | implementation(project(":fastcam-spring-utils")) 32 | testImplementation("org.springframework.boot:spring-boot-starter-test") 33 | } 34 | 35 | dependencyManagement { 36 | imports { 37 | mavenBom ("org.springframework.cloud:spring-cloud-dependencies:2020.0.1") 38 | } 39 | } 40 | 41 | 42 | tasks.withType { 43 | kotlinOptions { 44 | freeCompilerArgs = listOf("-Xjsr305=strict") 45 | jvmTarget = "11" 46 | } 47 | } 48 | 49 | tasks.withType { 50 | useJUnitPlatform() 51 | } 52 | -------------------------------------------------------------------------------- /fastcam-spring-rabbitmq/docker/docker-compose.yml: -------------------------------------------------------------------------------- 1 | version: '3' 2 | services: 3 | rabbitmq: 4 | image: 'rabbitmq:3-management-alpine' 5 | container_name: rabbitmq-stream 6 | ports: 7 | - "5672:5672" 8 | - "15672:15672" 9 | environment: 10 | RABBITMQ_ERLANG_COOKIE: "RabbitMQ-My-Cookies" 11 | RABBITMQ_DEFAULT_USER: "admin" 12 | RABBITMQ_DEFAULT_PASS: "admin" -------------------------------------------------------------------------------- /fastcam-spring-rabbitmq/gradlew.bat: -------------------------------------------------------------------------------- 1 | @rem 2 | @rem Copyright 2015 the original author or authors. 3 | @rem 4 | @rem Licensed under the Apache License, Version 2.0 (the "License"); 5 | @rem you may not use this file except in compliance with the License. 6 | @rem You may obtain a copy of the License at 7 | @rem 8 | @rem https://www.apache.org/licenses/LICENSE-2.0 9 | @rem 10 | @rem Unless required by applicable law or agreed to in writing, software 11 | @rem distributed under the License is distributed on an "AS IS" BASIS, 12 | @rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | @rem See the License for the specific language governing permissions and 14 | @rem limitations under the License. 15 | @rem 16 | 17 | @if "%DEBUG%" == "" @echo off 18 | @rem ########################################################################## 19 | @rem 20 | @rem Gradle startup script for Windows 21 | @rem 22 | @rem ########################################################################## 23 | 24 | @rem Set local scope for the variables with windows NT shell 25 | if "%OS%"=="Windows_NT" setlocal 26 | 27 | set DIRNAME=%~dp0 28 | if "%DIRNAME%" == "" set DIRNAME=. 29 | set APP_BASE_NAME=%~n0 30 | set APP_HOME=%DIRNAME% 31 | 32 | @rem Resolve any "." and ".." in APP_HOME to make it shorter. 33 | for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi 34 | 35 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 36 | set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" 37 | 38 | @rem Find java.exe 39 | if defined JAVA_HOME goto findJavaFromJavaHome 40 | 41 | set JAVA_EXE=java.exe 42 | %JAVA_EXE% -version >NUL 2>&1 43 | if "%ERRORLEVEL%" == "0" goto execute 44 | 45 | echo. 46 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 47 | echo. 48 | echo Please set the JAVA_HOME variable in your environment to match the 49 | echo location of your Java installation. 50 | 51 | goto fail 52 | 53 | :findJavaFromJavaHome 54 | set JAVA_HOME=%JAVA_HOME:"=% 55 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe 56 | 57 | if exist "%JAVA_EXE%" goto execute 58 | 59 | echo. 60 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 61 | echo. 62 | echo Please set the JAVA_HOME variable in your environment to match the 63 | echo location of your Java installation. 64 | 65 | goto fail 66 | 67 | :execute 68 | @rem Setup the command line 69 | 70 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar 71 | 72 | 73 | @rem Execute Gradle 74 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* 75 | 76 | :end 77 | @rem End local scope for the variables with windows NT shell 78 | if "%ERRORLEVEL%"=="0" goto mainEnd 79 | 80 | :fail 81 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of 82 | rem the _cmd.exe /c_ return code! 83 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 84 | exit /b 1 85 | 86 | :mainEnd 87 | if "%OS%"=="Windows_NT" endlocal 88 | 89 | :omega 90 | -------------------------------------------------------------------------------- /fastcam-spring-rabbitmq/lombok.config: -------------------------------------------------------------------------------- 1 | lombok.log.fieldname = LOG -------------------------------------------------------------------------------- /fastcam-spring-rabbitmq/out/production/resources/application.yml: -------------------------------------------------------------------------------- 1 | 2 | spring: 3 | rabbitmq: 4 | addresses: 127.0.0.1 5 | port: 5672 6 | username: admin 7 | password: admin 8 | cache: 9 | channel: 10 | size: 10 11 | connection: 12 | size: 10 13 | publisher-confirms: true -------------------------------------------------------------------------------- /fastcam-spring-rabbitmq/out/production/resources/docker/docker-compose.yml: -------------------------------------------------------------------------------- 1 | version: '3' 2 | services: 3 | rabbitmq: 4 | image: 'rabbitmq:3-management-alpine' 5 | container_name: rabbitmq-stream 6 | ports: 7 | - "5672:5672" 8 | - "15672:15672" 9 | environment: 10 | RABBITMQ_ERLANG_COOKIE: "RabbitMQ-My-Cookies" 11 | RABBITMQ_DEFAULT_USER: "admin" 12 | RABBITMQ_DEFAULT_PASS: "admin" -------------------------------------------------------------------------------- /fastcam-spring-rabbitmq/src/main/java/info/thecodinglive/rabbitmq/RabbitMQApp.java: -------------------------------------------------------------------------------- 1 | package info.thecodinglive.rabbitmq; 2 | 3 | import info.thecodinglive.rabbitmq.sample.model.MyTask; 4 | import lombok.extern.slf4j.Slf4j; 5 | import org.springframework.amqp.rabbit.annotation.RabbitListener; 6 | import org.springframework.boot.SpringApplication; 7 | import org.springframework.boot.autoconfigure.SpringBootApplication; 8 | 9 | @Slf4j 10 | @SpringBootApplication 11 | public class RabbitMQApp { 12 | public static void main(String ar[]) { 13 | SpringApplication.run(RabbitMQApp.class, ar); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /fastcam-spring-rabbitmq/src/main/java/info/thecodinglive/rabbitmq/config/FastcamRabbitQueue.java: -------------------------------------------------------------------------------- 1 | package info.thecodinglive.rabbitmq.config; 2 | 3 | public enum FastcamRabbitQueue { 4 | SAMPLE_TASK("photo.sample"), 5 | READ("photo.read"), 6 | WRITE("photo.write"), 7 | EMPTY("photo.empty"); 8 | 9 | private String queueName; 10 | 11 | FastcamRabbitQueue(String queueName) { 12 | this.queueName = queueName; 13 | } 14 | 15 | public String getQueueName() { 16 | return queueName; 17 | } 18 | 19 | public static FastcamRabbitQueue find(String name) { 20 | for (FastcamRabbitQueue queue : FastcamRabbitQueue.values()) { 21 | if (queue.getQueueName().equalsIgnoreCase(name)) { 22 | return queue; 23 | } 24 | } 25 | return FastcamRabbitQueue.EMPTY; 26 | } 27 | } 28 | 29 | -------------------------------------------------------------------------------- /fastcam-spring-rabbitmq/src/main/java/info/thecodinglive/rabbitmq/config/RabbitMQConfig.java: -------------------------------------------------------------------------------- 1 | package info.thecodinglive.rabbitmq.config; 2 | 3 | import info.thecodinglive.rabbitmq.sample.model.MyTask; 4 | import info.thecodinglive.utils.jackson.FastcamJacksonConverter; 5 | import lombok.extern.slf4j.Slf4j; 6 | import org.springframework.amqp.core.BindingBuilder; 7 | import org.springframework.amqp.core.Queue; 8 | import org.springframework.amqp.core.TopicExchange; 9 | import org.springframework.amqp.rabbit.annotation.EnableRabbit; 10 | import org.springframework.amqp.rabbit.connection.CachingConnectionFactory; 11 | import org.springframework.amqp.rabbit.connection.ConnectionFactory; 12 | import org.springframework.amqp.rabbit.core.RabbitAdmin; 13 | import org.springframework.amqp.rabbit.core.RabbitTemplate; 14 | import org.springframework.amqp.support.converter.DefaultClassMapper; 15 | import org.springframework.amqp.support.converter.Jackson2JsonMessageConverter; 16 | import org.springframework.amqp.support.converter.MessageConverter; 17 | import org.springframework.boot.autoconfigure.amqp.RabbitProperties; 18 | import org.springframework.context.annotation.Bean; 19 | import org.springframework.context.annotation.Configuration; 20 | 21 | import javax.annotation.Resource; 22 | import java.util.HashMap; 23 | import java.util.Map; 24 | 25 | /** docker 사용 시 check list 26 | * - vhost / 루트 패스 27 | * - 계정 admin 권한 ( tag ) 28 | */ 29 | 30 | @Slf4j 31 | @Configuration 32 | @EnableRabbit 33 | public class RabbitMQConfig { 34 | @Resource 35 | private RabbitProperties rabbitProperties; 36 | 37 | public static final String RABBIT_EXECHAGNGE_NAME = "thecodinglive"; 38 | private static final Integer CONSUMER_COUNT = 5; 39 | 40 | @Bean 41 | public DefaultClassMapper classMapper() { 42 | DefaultClassMapper classMapper = new DefaultClassMapper(); 43 | Map> idClassMapping = new HashMap<>(); 44 | idClassMapping.put("myTask", MyTask.class); 45 | classMapper.setIdClassMapping(idClassMapping); 46 | return classMapper; 47 | } 48 | 49 | @Bean 50 | public MessageConverter rabbitMessageConverter() { 51 | Jackson2JsonMessageConverter jsonConverter = new Jackson2JsonMessageConverter(FastcamJacksonConverter.getInstance()); 52 | jsonConverter.setClassMapper(classMapper()); 53 | return jsonConverter; 54 | } 55 | 56 | @Bean 57 | public ConnectionFactory rabbitConnectionFactory() { 58 | CachingConnectionFactory connectionFactory = new CachingConnectionFactory(); 59 | LOG.info("userName:: {}", rabbitProperties.getUsername()); 60 | connectionFactory.setUsername(rabbitProperties.getUsername()); 61 | connectionFactory.setPassword(rabbitProperties.getPassword()); 62 | connectionFactory.setCacheMode(CachingConnectionFactory.CacheMode.CHANNEL); 63 | 64 | return connectionFactory; 65 | } 66 | 67 | /** 68 | * Admin 설정 관련 부분 69 | * RabbitMQ에 admin 권한이 있는 계정으로 접속한 후에 70 | * exchange와 queue를 등록하고 매핑해준다. 71 | * @param rabbitConnectionFactory 72 | * @return 73 | */ 74 | @Bean 75 | public RabbitAdmin rabbitAdmin(ConnectionFactory rabbitConnectionFactory) { 76 | final RabbitAdmin rabbitAdmin = new RabbitAdmin(rabbitConnectionFactory); 77 | 78 | // exchange 등록 79 | rabbitExchange(rabbitAdmin); 80 | ///queue 자동 등록 81 | for (FastcamRabbitQueue fastcamRabbitQueue : FastcamRabbitQueue.values()) { 82 | rabbitAdmin.declareQueue(new Queue(fastcamRabbitQueue.getQueueName(), true)); 83 | rabbitAdmin.declareBinding(BindingBuilder.bind(new Queue(fastcamRabbitQueue.getQueueName(), true)) 84 | .to(rabbitExchange(rabbitAdmin)).with(fastcamRabbitQueue.getQueueName())); 85 | } 86 | 87 | rabbitAdmin.afterPropertiesSet(); 88 | return rabbitAdmin; 89 | } 90 | 91 | @Bean 92 | TopicExchange rabbitExchange(RabbitAdmin rabbitAdmin) { 93 | TopicExchange topicExchange = new TopicExchange(RABBIT_EXECHAGNGE_NAME); 94 | topicExchange.setAdminsThatShouldDeclare(rabbitAdmin); 95 | return topicExchange; 96 | } 97 | 98 | @Bean 99 | public RabbitTemplate rabbitTemplate(ConnectionFactory rabbitConnectionFactory, 100 | MessageConverter rabbitMessageConverter) { 101 | final RabbitTemplate rabbitTemplate = new RabbitTemplate(); 102 | rabbitTemplate.setConnectionFactory(rabbitConnectionFactory); 103 | rabbitTemplate.setMessageConverter(rabbitMessageConverter); 104 | rabbitTemplate.setExchange(RABBIT_EXECHAGNGE_NAME); 105 | 106 | rabbitTemplate.setConfirmCallback(((correlationData, ack, cause) -> { 107 | if(ack) { 108 | LOG.info("success"); 109 | }else{ 110 | LOG.error("error {}", cause); 111 | } 112 | })); 113 | 114 | return rabbitTemplate; 115 | } 116 | } 117 | -------------------------------------------------------------------------------- /fastcam-spring-rabbitmq/src/main/java/info/thecodinglive/rabbitmq/receiver/RabbitMQReceiver.java: -------------------------------------------------------------------------------- 1 | package info.thecodinglive.rabbitmq.receiver; 2 | 3 | import info.thecodinglive.rabbitmq.sample.model.MyTask; 4 | import lombok.extern.slf4j.Slf4j; 5 | import org.springframework.amqp.rabbit.annotation.RabbitListener; 6 | import org.springframework.stereotype.Component; 7 | 8 | @Slf4j 9 | @Component 10 | public class RabbitMQReceiver { 11 | @RabbitListener(id = "photo.sample", queues = "photo.sample") 12 | public void handle(MyTask task) { 13 | LOG.info("mydata handle:: {}", task.toString()); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /fastcam-spring-rabbitmq/src/main/java/info/thecodinglive/rabbitmq/sample/model/MyTask.java: -------------------------------------------------------------------------------- 1 | package info.thecodinglive.rabbitmq.sample.model; 2 | 3 | import com.fasterxml.jackson.annotation.JsonIgnore; 4 | import lombok.NoArgsConstructor; 5 | import lombok.ToString; 6 | import org.springframework.util.StringUtils; 7 | 8 | import java.util.UUID; 9 | 10 | @NoArgsConstructor 11 | @ToString(exclude = "DEFAULT_MSG") 12 | public class MyTask { 13 | private String taskId; 14 | private String msg; 15 | 16 | @JsonIgnore 17 | private String DEFAULT_MSG = "you guys do something"; 18 | 19 | public MyTask(String msg) { 20 | this.taskId = UUID.randomUUID().toString(); 21 | this.msg = StringUtils.hasLength(msg) ? msg : DEFAULT_MSG; 22 | } 23 | 24 | public String getTaskId() { 25 | return taskId; 26 | } 27 | 28 | public void setTaskId(String taskId) { 29 | this.taskId = taskId; 30 | } 31 | 32 | public String getMsg() { 33 | return msg; 34 | } 35 | 36 | public void setMsg(String msg) { 37 | this.msg = msg; 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /fastcam-spring-rabbitmq/src/main/java/info/thecodinglive/rabbitmq/sender/MessageController.java: -------------------------------------------------------------------------------- 1 | package info.thecodinglive.rabbitmq.sender; 2 | 3 | import info.thecodinglive.rabbitmq.config.RabbitMQConfig; 4 | import info.thecodinglive.rabbitmq.sample.model.MyTask; 5 | import org.springframework.beans.factory.annotation.Autowired; 6 | import org.springframework.web.bind.annotation.GetMapping; 7 | import org.springframework.web.bind.annotation.RequestParam; 8 | import org.springframework.web.bind.annotation.RestController; 9 | 10 | @RestController 11 | public class MessageController { 12 | @Autowired 13 | RabbitMessagePublisher rabbitMessagePublisher; 14 | 15 | @GetMapping("/send") 16 | public String sendData(@RequestParam(defaultValue = "") String msg) { 17 | rabbitMessagePublisher.publish(RabbitMQConfig.RABBIT_EXECHAGNGE_NAME, new MyTask(msg)); 18 | 19 | return "send Data"; 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /fastcam-spring-rabbitmq/src/main/java/info/thecodinglive/rabbitmq/sender/RabbitMessagePublisher.java: -------------------------------------------------------------------------------- 1 | package info.thecodinglive.rabbitmq.sender; 2 | 3 | import info.thecodinglive.rabbitmq.sample.model.MyTask; 4 | import lombok.extern.slf4j.Slf4j; 5 | import org.springframework.amqp.core.MessageBuilder; 6 | import org.springframework.amqp.rabbit.core.RabbitTemplate; 7 | import org.springframework.beans.factory.annotation.Autowired; 8 | import org.springframework.stereotype.Component; 9 | 10 | import java.nio.charset.StandardCharsets; 11 | 12 | @Slf4j 13 | @Component 14 | public class RabbitMessagePublisher { 15 | @Autowired 16 | private RabbitTemplate rabbitTemplate; 17 | 18 | public void publish(String routingKey, MyTask myTask) { 19 | try { 20 | rabbitTemplate.convertAndSend("thecodinglive", "photo.sample", myTask); 21 | } catch (Exception e) { 22 | LOG.error("error", e); 23 | } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /fastcam-spring-rabbitmq/src/main/resources/application.yml: -------------------------------------------------------------------------------- 1 | 2 | spring: 3 | rabbitmq: 4 | addresses: 127.0.0.1 5 | port: 5672 6 | username: admin 7 | password: admin 8 | cache: 9 | channel: 10 | size: 10 11 | connection: 12 | size: 10 13 | publisher-confirms: true -------------------------------------------------------------------------------- /fastcam-spring-rabbitmq/src/main/resources/docker/docker-compose.yml: -------------------------------------------------------------------------------- 1 | version: '3' 2 | services: 3 | rabbitmq: 4 | image: 'rabbitmq:3-management-alpine' 5 | container_name: rabbitmq-stream 6 | ports: 7 | - "5672:5672" 8 | - "15672:15672" 9 | environment: 10 | RABBITMQ_ERLANG_COOKIE: "RabbitMQ-My-Cookies" 11 | RABBITMQ_DEFAULT_USER: "admin" 12 | RABBITMQ_DEFAULT_PASS: "admin" -------------------------------------------------------------------------------- /fastcam-spring-rabbitmq/src/test/java/info/thecodinglive/rabbitmq/sender/RabbitMQSenderTest.java: -------------------------------------------------------------------------------- 1 | package info.thecodinglive.rabbitmq.sender; 2 | 3 | import info.thecodinglive.rabbitmq.config.FastcamRabbitQueue; 4 | import info.thecodinglive.rabbitmq.sample.model.MyTask; 5 | import org.junit.jupiter.api.Test; 6 | import org.junit.jupiter.api.extension.ExtendWith; 7 | import org.springframework.beans.factory.annotation.Autowired; 8 | import org.springframework.boot.test.context.SpringBootTest; 9 | import org.springframework.test.context.junit.jupiter.SpringExtension; 10 | 11 | @SpringBootTest 12 | @ExtendWith(SpringExtension.class) 13 | public class RabbitMQSenderTest { 14 | @Autowired 15 | private RabbitMessagePublisher publisher; 16 | 17 | @Test 18 | public void sendMsg() { 19 | String msg = "you guys do something!!!"; 20 | publisher.publish(FastcamRabbitQueue.SAMPLE_TASK.getQueueName(), new MyTask(msg)); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /fastcam-spring-sleuth/build.gradle.kts: -------------------------------------------------------------------------------- 1 | import org.jetbrains.kotlin.gradle.tasks.KotlinCompile 2 | 3 | plugins { 4 | id("org.springframework.boot") version "2.4.3" 5 | id("io.spring.dependency-management") version "1.0.11.RELEASE" 6 | kotlin("jvm") version "1.4.30" 7 | kotlin("plugin.spring") version "1.4.30" 8 | } 9 | 10 | group = "info.thecodinglive.stream" 11 | version = "0.0.1-SNAPSHOT" 12 | java.sourceCompatibility = JavaVersion.VERSION_11 13 | 14 | configurations { 15 | compileOnly { 16 | extendsFrom(configurations.annotationProcessor.get()) 17 | } 18 | } 19 | 20 | repositories { 21 | jcenter() 22 | } 23 | 24 | dependencies { 25 | implementation("org.springframework.boot:spring-boot-starter-web") 26 | implementation("org.springframework.cloud:spring-cloud-starter-sleuth") 27 | implementation("org.springframework.cloud:spring-cloud-sleuth-zipkin") 28 | implementation("org.springframework.cloud:spring-cloud-starter-bootstrap") 29 | compileOnly("org.projectlombok:lombok") 30 | annotationProcessor("org.projectlombok:lombok") 31 | } 32 | 33 | dependencyManagement { 34 | imports { 35 | mavenBom ("org.springframework.cloud:spring-cloud-dependencies:2020.0.1") 36 | } 37 | } 38 | 39 | 40 | tasks.withType { 41 | kotlinOptions { 42 | freeCompilerArgs = listOf("-Xjsr305=strict") 43 | jvmTarget = "11" 44 | } 45 | } 46 | 47 | tasks.withType { 48 | useJUnitPlatform() 49 | } 50 | -------------------------------------------------------------------------------- /fastcam-spring-sleuth/gradlew.bat: -------------------------------------------------------------------------------- 1 | @rem 2 | @rem Copyright 2015 the original author or authors. 3 | @rem 4 | @rem Licensed under the Apache License, Version 2.0 (the "License"); 5 | @rem you may not use this file except in compliance with the License. 6 | @rem You may obtain a copy of the License at 7 | @rem 8 | @rem https://www.apache.org/licenses/LICENSE-2.0 9 | @rem 10 | @rem Unless required by applicable law or agreed to in writing, software 11 | @rem distributed under the License is distributed on an "AS IS" BASIS, 12 | @rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | @rem See the License for the specific language governing permissions and 14 | @rem limitations under the License. 15 | @rem 16 | 17 | @if "%DEBUG%" == "" @echo off 18 | @rem ########################################################################## 19 | @rem 20 | @rem Gradle startup script for Windows 21 | @rem 22 | @rem ########################################################################## 23 | 24 | @rem Set local scope for the variables with windows NT shell 25 | if "%OS%"=="Windows_NT" setlocal 26 | 27 | set DIRNAME=%~dp0 28 | if "%DIRNAME%" == "" set DIRNAME=. 29 | set APP_BASE_NAME=%~n0 30 | set APP_HOME=%DIRNAME% 31 | 32 | @rem Resolve any "." and ".." in APP_HOME to make it shorter. 33 | for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi 34 | 35 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 36 | set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" 37 | 38 | @rem Find java.exe 39 | if defined JAVA_HOME goto findJavaFromJavaHome 40 | 41 | set JAVA_EXE=java.exe 42 | %JAVA_EXE% -version >NUL 2>&1 43 | if "%ERRORLEVEL%" == "0" goto execute 44 | 45 | echo. 46 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 47 | echo. 48 | echo Please set the JAVA_HOME variable in your environment to match the 49 | echo location of your Java installation. 50 | 51 | goto fail 52 | 53 | :findJavaFromJavaHome 54 | set JAVA_HOME=%JAVA_HOME:"=% 55 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe 56 | 57 | if exist "%JAVA_EXE%" goto execute 58 | 59 | echo. 60 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 61 | echo. 62 | echo Please set the JAVA_HOME variable in your environment to match the 63 | echo location of your Java installation. 64 | 65 | goto fail 66 | 67 | :execute 68 | @rem Setup the command line 69 | 70 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar 71 | 72 | 73 | @rem Execute Gradle 74 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* 75 | 76 | :end 77 | @rem End local scope for the variables with windows NT shell 78 | if "%ERRORLEVEL%"=="0" goto mainEnd 79 | 80 | :fail 81 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of 82 | rem the _cmd.exe /c_ return code! 83 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 84 | exit /b 1 85 | 86 | :mainEnd 87 | if "%OS%"=="Windows_NT" endlocal 88 | 89 | :omega 90 | -------------------------------------------------------------------------------- /fastcam-spring-sleuth/src/main/java/info/thecodinglive/monitoring/SpringSleuth.java: -------------------------------------------------------------------------------- 1 | package info.thecodinglive.monitoring; 2 | 3 | import brave.sampler.Sampler; 4 | import org.springframework.boot.SpringApplication; 5 | import org.springframework.boot.autoconfigure.SpringBootApplication; 6 | import org.springframework.context.annotation.Bean; 7 | 8 | @SpringBootApplication 9 | public class SpringSleuth { 10 | public static void main(String ar[]) { 11 | SpringApplication.run(SpringSleuth.class, ar); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /fastcam-spring-sleuth/src/main/java/info/thecodinglive/monitoring/config/SleuthConfig.java: -------------------------------------------------------------------------------- 1 | package info.thecodinglive.monitoring.config; 2 | 3 | import brave.sampler.Sampler; 4 | import org.springframework.context.annotation.Bean; 5 | import org.springframework.context.annotation.Configuration; 6 | 7 | @Configuration 8 | public class SleuthConfig { 9 | 10 | @Bean 11 | public Sampler alwaysSampler() { 12 | return Sampler.ALWAYS_SAMPLE; 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /fastcam-spring-sleuth/src/main/java/info/thecodinglive/monitoring/sleuth/TestController.java: -------------------------------------------------------------------------------- 1 | package info.thecodinglive.monitoring.sleuth; 2 | 3 | import brave.sampler.Sampler; 4 | import lombok.extern.slf4j.Slf4j; 5 | import org.springframework.beans.factory.annotation.Autowired; 6 | import org.springframework.context.annotation.Bean; 7 | import org.springframework.web.bind.annotation.GetMapping; 8 | import org.springframework.web.bind.annotation.RestController; 9 | import org.springframework.web.client.RestTemplate; 10 | 11 | @Slf4j 12 | @RestController 13 | public class TestController { 14 | @GetMapping("/") 15 | public String helloSleuth() { 16 | log.info("Hello Sleuth"); 17 | return "success"; 18 | } 19 | 20 | } 21 | -------------------------------------------------------------------------------- /fastcam-spring-sleuth/src/main/resources/application.yml: -------------------------------------------------------------------------------- 1 | server.port: 8081 2 | 3 | spring.application: 4 | name: SleuthApp 5 | 6 | spring.zipkin: 7 | base-url: http://localhost:9411 8 | 9 | spring.sleuth.sampler.probability: 1.0 -------------------------------------------------------------------------------- /fastcam-spring-utils/build.gradle.kts: -------------------------------------------------------------------------------- 1 | import org.jetbrains.kotlin.gradle.tasks.KotlinCompile 2 | 3 | plugins { 4 | id("org.springframework.boot") version "2.4.3" 5 | id("io.spring.dependency-management") version "1.0.11.RELEASE" 6 | kotlin("jvm") version "1.4.30" 7 | kotlin("plugin.spring") version "1.4.30" 8 | } 9 | 10 | group = "info.thecodinglive.stream" 11 | version = "0.0.1-SNAPSHOT" 12 | java.sourceCompatibility = JavaVersion.VERSION_11 13 | 14 | configurations { 15 | compileOnly { 16 | extendsFrom(configurations.annotationProcessor.get()) 17 | } 18 | } 19 | 20 | repositories { 21 | jcenter() 22 | } 23 | 24 | dependencies { 25 | implementation("org.springframework.boot:spring-boot-starter-web") 26 | testImplementation("org.springframework.boot:spring-boot-starter-test") 27 | } 28 | 29 | dependencyManagement { 30 | imports { 31 | mavenBom ("org.springframework.cloud:spring-cloud-dependencies:2020.0.1") 32 | } 33 | } 34 | 35 | tasks.withType { 36 | kotlinOptions { 37 | freeCompilerArgs = listOf("-Xjsr305=strict") 38 | jvmTarget = "11" 39 | } 40 | } 41 | 42 | tasks.withType { 43 | useJUnitPlatform() 44 | } 45 | -------------------------------------------------------------------------------- /fastcam-spring-utils/gradlew.bat: -------------------------------------------------------------------------------- 1 | @rem 2 | @rem Copyright 2015 the original author or authors. 3 | @rem 4 | @rem Licensed under the Apache License, Version 2.0 (the "License"); 5 | @rem you may not use this file except in compliance with the License. 6 | @rem You may obtain a copy of the License at 7 | @rem 8 | @rem https://www.apache.org/licenses/LICENSE-2.0 9 | @rem 10 | @rem Unless required by applicable law or agreed to in writing, software 11 | @rem distributed under the License is distributed on an "AS IS" BASIS, 12 | @rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | @rem See the License for the specific language governing permissions and 14 | @rem limitations under the License. 15 | @rem 16 | 17 | @if "%DEBUG%" == "" @echo off 18 | @rem ########################################################################## 19 | @rem 20 | @rem Gradle startup script for Windows 21 | @rem 22 | @rem ########################################################################## 23 | 24 | @rem Set local scope for the variables with windows NT shell 25 | if "%OS%"=="Windows_NT" setlocal 26 | 27 | set DIRNAME=%~dp0 28 | if "%DIRNAME%" == "" set DIRNAME=. 29 | set APP_BASE_NAME=%~n0 30 | set APP_HOME=%DIRNAME% 31 | 32 | @rem Resolve any "." and ".." in APP_HOME to make it shorter. 33 | for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi 34 | 35 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 36 | set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" 37 | 38 | @rem Find java.exe 39 | if defined JAVA_HOME goto findJavaFromJavaHome 40 | 41 | set JAVA_EXE=java.exe 42 | %JAVA_EXE% -version >NUL 2>&1 43 | if "%ERRORLEVEL%" == "0" goto execute 44 | 45 | echo. 46 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 47 | echo. 48 | echo Please set the JAVA_HOME variable in your environment to match the 49 | echo location of your Java installation. 50 | 51 | goto fail 52 | 53 | :findJavaFromJavaHome 54 | set JAVA_HOME=%JAVA_HOME:"=% 55 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe 56 | 57 | if exist "%JAVA_EXE%" goto execute 58 | 59 | echo. 60 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 61 | echo. 62 | echo Please set the JAVA_HOME variable in your environment to match the 63 | echo location of your Java installation. 64 | 65 | goto fail 66 | 67 | :execute 68 | @rem Setup the command line 69 | 70 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar 71 | 72 | 73 | @rem Execute Gradle 74 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* 75 | 76 | :end 77 | @rem End local scope for the variables with windows NT shell 78 | if "%ERRORLEVEL%"=="0" goto mainEnd 79 | 80 | :fail 81 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of 82 | rem the _cmd.exe /c_ return code! 83 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 84 | exit /b 1 85 | 86 | :mainEnd 87 | if "%OS%"=="Windows_NT" endlocal 88 | 89 | :omega 90 | -------------------------------------------------------------------------------- /fastcam-spring-utils/src/main/java/info/thecodinglive/utils/jackson/FastcamJacksonConverter.java: -------------------------------------------------------------------------------- 1 | package info.thecodinglive.utils.jackson; 2 | 3 | import com.fasterxml.jackson.annotation.JsonInclude; 4 | import com.fasterxml.jackson.core.type.TypeReference; 5 | import com.fasterxml.jackson.databind.DeserializationFeature; 6 | import com.fasterxml.jackson.databind.ObjectMapper; 7 | import com.fasterxml.jackson.databind.SerializationFeature; 8 | import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule; 9 | 10 | public class FastcamJacksonConverter { 11 | private static final ObjectMapper mapper; 12 | 13 | static { 14 | mapper = new ObjectMapper() 15 | .setSerializationInclusion(JsonInclude.Include.NON_NULL) 16 | .configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false) 17 | .configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false) 18 | .configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false) 19 | .configure(DeserializationFeature.ADJUST_DATES_TO_CONTEXT_TIME_ZONE, false) 20 | .registerModule(new JavaTimeModule()); 21 | } 22 | 23 | private FastcamJacksonConverter() { 24 | throw new RuntimeException("construct not support"); 25 | } 26 | 27 | public static ObjectMapper getInstance() { 28 | return mapper; 29 | } 30 | 31 | public static String toJson(Object value) { 32 | try{ 33 | return mapper.writeValueAsString(value); 34 | } catch (Exception e) { 35 | throw new RuntimeException("convert error"); 36 | } 37 | } 38 | 39 | public static T toObject(String content, Class valueType) { 40 | try { 41 | return mapper.readValue(content, valueType); 42 | } catch (Exception e) { 43 | throw new RuntimeException("convert error"); 44 | } 45 | } 46 | 47 | public static T toObject(String content, TypeReference type) { 48 | try { 49 | return mapper.readValue(content, type); 50 | } catch (Exception e) { 51 | throw new RuntimeException("convert error"); 52 | } 53 | } 54 | 55 | public static T convert(Object obj, Class type) { 56 | try { 57 | return mapper.convertValue(obj, type); 58 | } catch (Exception e) { 59 | throw new RuntimeException("convert error"); 60 | } 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /fastcam-spring-vault/build.gradle.kts: -------------------------------------------------------------------------------- 1 | import org.jetbrains.kotlin.gradle.tasks.KotlinCompile 2 | 3 | plugins { 4 | id("org.springframework.boot") version "2.4.3" 5 | id("io.spring.dependency-management") version "1.0.11.RELEASE" 6 | kotlin("jvm") version "1.4.30" 7 | kotlin("plugin.spring") version "1.4.30" 8 | } 9 | 10 | group = "info.thecodinglive.vault" 11 | version = "0.0.1-SNAPSHOT" 12 | java.sourceCompatibility = JavaVersion.VERSION_11 13 | 14 | configurations { 15 | compileOnly { 16 | extendsFrom(configurations.annotationProcessor.get()) 17 | } 18 | } 19 | 20 | repositories { 21 | jcenter() 22 | } 23 | 24 | dependencies { 25 | implementation("org.springframework.cloud:spring-cloud-starter-vault-config") 26 | implementation("org.springframework.cloud:spring-cloud-starter-bootstrap") 27 | implementation("org.springframework.boot:spring-boot-starter-test") 28 | } 29 | 30 | dependencyManagement { 31 | imports { 32 | mavenBom ("org.springframework.cloud:spring-cloud-dependencies:2020.0.1") 33 | } 34 | } 35 | 36 | 37 | tasks.withType { 38 | kotlinOptions { 39 | freeCompilerArgs = listOf("-Xjsr305=strict") 40 | jvmTarget = "11" 41 | } 42 | } 43 | 44 | tasks.withType { 45 | useJUnitPlatform() 46 | } 47 | -------------------------------------------------------------------------------- /fastcam-spring-vault/gradlew.bat: -------------------------------------------------------------------------------- 1 | @rem 2 | @rem Copyright 2015 the original author or authors. 3 | @rem 4 | @rem Licensed under the Apache License, Version 2.0 (the "License"); 5 | @rem you may not use this file except in compliance with the License. 6 | @rem You may obtain a copy of the License at 7 | @rem 8 | @rem https://www.apache.org/licenses/LICENSE-2.0 9 | @rem 10 | @rem Unless required by applicable law or agreed to in writing, software 11 | @rem distributed under the License is distributed on an "AS IS" BASIS, 12 | @rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | @rem See the License for the specific language governing permissions and 14 | @rem limitations under the License. 15 | @rem 16 | 17 | @if "%DEBUG%" == "" @echo off 18 | @rem ########################################################################## 19 | @rem 20 | @rem Gradle startup script for Windows 21 | @rem 22 | @rem ########################################################################## 23 | 24 | @rem Set local scope for the variables with windows NT shell 25 | if "%OS%"=="Windows_NT" setlocal 26 | 27 | set DIRNAME=%~dp0 28 | if "%DIRNAME%" == "" set DIRNAME=. 29 | set APP_BASE_NAME=%~n0 30 | set APP_HOME=%DIRNAME% 31 | 32 | @rem Resolve any "." and ".." in APP_HOME to make it shorter. 33 | for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi 34 | 35 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 36 | set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" 37 | 38 | @rem Find java.exe 39 | if defined JAVA_HOME goto findJavaFromJavaHome 40 | 41 | set JAVA_EXE=java.exe 42 | %JAVA_EXE% -version >NUL 2>&1 43 | if "%ERRORLEVEL%" == "0" goto execute 44 | 45 | echo. 46 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 47 | echo. 48 | echo Please set the JAVA_HOME variable in your environment to match the 49 | echo location of your Java installation. 50 | 51 | goto fail 52 | 53 | :findJavaFromJavaHome 54 | set JAVA_HOME=%JAVA_HOME:"=% 55 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe 56 | 57 | if exist "%JAVA_EXE%" goto execute 58 | 59 | echo. 60 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 61 | echo. 62 | echo Please set the JAVA_HOME variable in your environment to match the 63 | echo location of your Java installation. 64 | 65 | goto fail 66 | 67 | :execute 68 | @rem Setup the command line 69 | 70 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar 71 | 72 | 73 | @rem Execute Gradle 74 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* 75 | 76 | :end 77 | @rem End local scope for the variables with windows NT shell 78 | if "%ERRORLEVEL%"=="0" goto mainEnd 79 | 80 | :fail 81 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of 82 | rem the _cmd.exe /c_ return code! 83 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 84 | exit /b 1 85 | 86 | :mainEnd 87 | if "%OS%"=="Windows_NT" endlocal 88 | 89 | :omega 90 | -------------------------------------------------------------------------------- /fastcam-spring-vault/src/main/java/info/thecodinglive/cloud/app/SpringVaultApp.java: -------------------------------------------------------------------------------- 1 | package info.thecodinglive.cloud.app; 2 | 3 | import info.thecodinglive.cloud.config.MySqlConfig; 4 | import org.slf4j.Logger; 5 | import org.slf4j.LoggerFactory; 6 | import org.springframework.boot.CommandLineRunner; 7 | import org.springframework.boot.SpringApplication; 8 | import org.springframework.boot.autoconfigure.SpringBootApplication; 9 | import org.springframework.boot.context.properties.EnableConfigurationProperties; 10 | 11 | @SpringBootApplication 12 | @EnableConfigurationProperties(MySqlConfig.class) 13 | public class SpringVaultApp implements CommandLineRunner { 14 | private static Logger LOG = LoggerFactory.getLogger(SpringVaultApp.class); 15 | 16 | private final MySqlConfig mySqlConfig; 17 | 18 | public SpringVaultApp(MySqlConfig mySqlConfig) { 19 | this.mySqlConfig = mySqlConfig; 20 | } 21 | 22 | public static void main(String ar[]) { 23 | SpringApplication.run(SpringVaultApp.class, ar); 24 | } 25 | 26 | @Override 27 | public void run(String... args) throws Exception { 28 | LOG.info("proerties: {} , {}", mySqlConfig.getUserName(), mySqlConfig.getPassword()); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /fastcam-spring-vault/src/main/java/info/thecodinglive/cloud/config/MySqlConfig.java: -------------------------------------------------------------------------------- 1 | package info.thecodinglive.cloud.config; 2 | 3 | import org.springframework.boot.context.properties.ConfigurationProperties; 4 | import org.springframework.context.annotation.Configuration; 5 | 6 | 7 | @ConfigurationProperties("mysql") 8 | public class MySqlConfig { 9 | private String userName; 10 | private String password; 11 | 12 | public String getUserName() { 13 | return userName; 14 | } 15 | 16 | public void setUserName(String userName) { 17 | this.userName = userName; 18 | } 19 | 20 | public String getPassword() { 21 | return password; 22 | } 23 | 24 | public void setPassword(String password) { 25 | this.password = password; 26 | } 27 | 28 | @Override 29 | public String toString() { 30 | return "MySqlConfig{" + 31 | "userName='" + userName + '\'' + 32 | ", password='" + password + '\'' + 33 | '}'; 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /fastcam-spring-vault/src/main/resources/application.yml: -------------------------------------------------------------------------------- 1 | server.port: 9061 2 | 3 | -------------------------------------------------------------------------------- /fastcam-spring-vault/src/main/resources/bootstrap.yml: -------------------------------------------------------------------------------- 1 | spring: 2 | application: 3 | name: mysql 4 | 5 | spring.cloud.vault: 6 | host: localhost 7 | port: 8200 8 | token: 67a57b2d-5741-496e-a8d6-eba59cfd25a8 9 | scheme: http 10 | kv.enabled: true 11 | 12 | -------------------------------------------------------------------------------- /fastcam-spring-vault/src/main/resources/config/mongo-default.yml: -------------------------------------------------------------------------------- 1 | mongodbserver: 2 | url: 168.126.63.1 3 | username: testUser 4 | password: pass -------------------------------------------------------------------------------- /fastcam-spring-vault/src/main/resources/config/mongo-dev.yml: -------------------------------------------------------------------------------- 1 | mongodbserver: 2 | url: 168.126.63.1 3 | username: testUser 4 | password: pass -------------------------------------------------------------------------------- /fastcam-spring-vault/src/main/resources/config/mongo-real.yml: -------------------------------------------------------------------------------- 1 | mongodbserver: 2 | url: 168.126.63.1 3 | username: testUser 4 | password: pass -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thecodinglive/fastcampus-example/8fc38f151532d7fc4168fd2cbb6e9cf42e9dd472/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionBase=GRADLE_USER_HOME 2 | distributionPath=wrapper/dists 3 | distributionUrl=https\://services.gradle.org/distributions/gradle-6.7.1-bin.zip 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | -------------------------------------------------------------------------------- /gradlew: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env sh 2 | 3 | # 4 | # Copyright 2015 the original author or authors. 5 | # 6 | # Licensed under the Apache License, Version 2.0 (the "License"); 7 | # you may not use this file except in compliance with the License. 8 | # You may obtain a copy of the License at 9 | # 10 | # https://www.apache.org/licenses/LICENSE-2.0 11 | # 12 | # Unless required by applicable law or agreed to in writing, software 13 | # distributed under the License is distributed on an "AS IS" BASIS, 14 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | # See the License for the specific language governing permissions and 16 | # limitations under the License. 17 | # 18 | 19 | ############################################################################## 20 | ## 21 | ## Gradle start up script for UN*X 22 | ## 23 | ############################################################################## 24 | 25 | # Attempt to set APP_HOME 26 | # Resolve links: $0 may be a link 27 | PRG="$0" 28 | # Need this for relative symlinks. 29 | while [ -h "$PRG" ] ; do 30 | ls=`ls -ld "$PRG"` 31 | link=`expr "$ls" : '.*-> \(.*\)$'` 32 | if expr "$link" : '/.*' > /dev/null; then 33 | PRG="$link" 34 | else 35 | PRG=`dirname "$PRG"`"/$link" 36 | fi 37 | done 38 | SAVED="`pwd`" 39 | cd "`dirname \"$PRG\"`/" >/dev/null 40 | APP_HOME="`pwd -P`" 41 | cd "$SAVED" >/dev/null 42 | 43 | APP_NAME="Gradle" 44 | APP_BASE_NAME=`basename "$0"` 45 | 46 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 47 | DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' 48 | 49 | # Use the maximum available, or set MAX_FD != -1 to use that value. 50 | MAX_FD="maximum" 51 | 52 | warn () { 53 | echo "$*" 54 | } 55 | 56 | die () { 57 | echo 58 | echo "$*" 59 | echo 60 | exit 1 61 | } 62 | 63 | # OS specific support (must be 'true' or 'false'). 64 | cygwin=false 65 | msys=false 66 | darwin=false 67 | nonstop=false 68 | case "`uname`" in 69 | CYGWIN* ) 70 | cygwin=true 71 | ;; 72 | Darwin* ) 73 | darwin=true 74 | ;; 75 | MINGW* ) 76 | msys=true 77 | ;; 78 | NONSTOP* ) 79 | nonstop=true 80 | ;; 81 | esac 82 | 83 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar 84 | 85 | 86 | # Determine the Java command to use to start the JVM. 87 | if [ -n "$JAVA_HOME" ] ; then 88 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then 89 | # IBM's JDK on AIX uses strange locations for the executables 90 | JAVACMD="$JAVA_HOME/jre/sh/java" 91 | else 92 | JAVACMD="$JAVA_HOME/bin/java" 93 | fi 94 | if [ ! -x "$JAVACMD" ] ; then 95 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME 96 | 97 | Please set the JAVA_HOME variable in your environment to match the 98 | location of your Java installation." 99 | fi 100 | else 101 | JAVACMD="java" 102 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 103 | 104 | Please set the JAVA_HOME variable in your environment to match the 105 | location of your Java installation." 106 | fi 107 | 108 | # Increase the maximum file descriptors if we can. 109 | if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then 110 | MAX_FD_LIMIT=`ulimit -H -n` 111 | if [ $? -eq 0 ] ; then 112 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then 113 | MAX_FD="$MAX_FD_LIMIT" 114 | fi 115 | ulimit -n $MAX_FD 116 | if [ $? -ne 0 ] ; then 117 | warn "Could not set maximum file descriptor limit: $MAX_FD" 118 | fi 119 | else 120 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" 121 | fi 122 | fi 123 | 124 | # For Darwin, add options to specify how the application appears in the dock 125 | if $darwin; then 126 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" 127 | fi 128 | 129 | # For Cygwin or MSYS, switch paths to Windows format before running java 130 | if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then 131 | APP_HOME=`cygpath --path --mixed "$APP_HOME"` 132 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` 133 | 134 | JAVACMD=`cygpath --unix "$JAVACMD"` 135 | 136 | # We build the pattern for arguments to be converted via cygpath 137 | ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` 138 | SEP="" 139 | for dir in $ROOTDIRSRAW ; do 140 | ROOTDIRS="$ROOTDIRS$SEP$dir" 141 | SEP="|" 142 | done 143 | OURCYGPATTERN="(^($ROOTDIRS))" 144 | # Add a user-defined pattern to the cygpath arguments 145 | if [ "$GRADLE_CYGPATTERN" != "" ] ; then 146 | OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" 147 | fi 148 | # Now convert the arguments - kludge to limit ourselves to /bin/sh 149 | i=0 150 | for arg in "$@" ; do 151 | CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` 152 | CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option 153 | 154 | if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition 155 | eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` 156 | else 157 | eval `echo args$i`="\"$arg\"" 158 | fi 159 | i=`expr $i + 1` 160 | done 161 | case $i in 162 | 0) set -- ;; 163 | 1) set -- "$args0" ;; 164 | 2) set -- "$args0" "$args1" ;; 165 | 3) set -- "$args0" "$args1" "$args2" ;; 166 | 4) set -- "$args0" "$args1" "$args2" "$args3" ;; 167 | 5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; 168 | 6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; 169 | 7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; 170 | 8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; 171 | 9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; 172 | esac 173 | fi 174 | 175 | # Escape application args 176 | save () { 177 | for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done 178 | echo " " 179 | } 180 | APP_ARGS=`save "$@"` 181 | 182 | # Collect all arguments for the java command, following the shell quoting and substitution rules 183 | eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS" 184 | 185 | exec "$JAVACMD" "$@" 186 | -------------------------------------------------------------------------------- /gradlew.bat: -------------------------------------------------------------------------------- 1 | @rem 2 | @rem Copyright 2015 the original author or authors. 3 | @rem 4 | @rem Licensed under the Apache License, Version 2.0 (the "License"); 5 | @rem you may not use this file except in compliance with the License. 6 | @rem You may obtain a copy of the License at 7 | @rem 8 | @rem https://www.apache.org/licenses/LICENSE-2.0 9 | @rem 10 | @rem Unless required by applicable law or agreed to in writing, software 11 | @rem distributed under the License is distributed on an "AS IS" BASIS, 12 | @rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | @rem See the License for the specific language governing permissions and 14 | @rem limitations under the License. 15 | @rem 16 | 17 | @if "%DEBUG%" == "" @echo off 18 | @rem ########################################################################## 19 | @rem 20 | @rem Gradle startup script for Windows 21 | @rem 22 | @rem ########################################################################## 23 | 24 | @rem Set local scope for the variables with windows NT shell 25 | if "%OS%"=="Windows_NT" setlocal 26 | 27 | set DIRNAME=%~dp0 28 | if "%DIRNAME%" == "" set DIRNAME=. 29 | set APP_BASE_NAME=%~n0 30 | set APP_HOME=%DIRNAME% 31 | 32 | @rem Resolve any "." and ".." in APP_HOME to make it shorter. 33 | for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi 34 | 35 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 36 | set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" 37 | 38 | @rem Find java.exe 39 | if defined JAVA_HOME goto findJavaFromJavaHome 40 | 41 | set JAVA_EXE=java.exe 42 | %JAVA_EXE% -version >NUL 2>&1 43 | if "%ERRORLEVEL%" == "0" goto execute 44 | 45 | echo. 46 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 47 | echo. 48 | echo Please set the JAVA_HOME variable in your environment to match the 49 | echo location of your Java installation. 50 | 51 | goto fail 52 | 53 | :findJavaFromJavaHome 54 | set JAVA_HOME=%JAVA_HOME:"=% 55 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe 56 | 57 | if exist "%JAVA_EXE%" goto execute 58 | 59 | echo. 60 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 61 | echo. 62 | echo Please set the JAVA_HOME variable in your environment to match the 63 | echo location of your Java installation. 64 | 65 | goto fail 66 | 67 | :execute 68 | @rem Setup the command line 69 | 70 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar 71 | 72 | 73 | @rem Execute Gradle 74 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* 75 | 76 | :end 77 | @rem End local scope for the variables with windows NT shell 78 | if "%ERRORLEVEL%"=="0" goto mainEnd 79 | 80 | :fail 81 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of 82 | rem the _cmd.exe /c_ return code! 83 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 84 | exit /b 1 85 | 86 | :mainEnd 87 | if "%OS%"=="Windows_NT" endlocal 88 | 89 | :omega 90 | -------------------------------------------------------------------------------- /readme.md: -------------------------------------------------------------------------------- 1 | ## fastcampus spring-cloud example 2 | 3 | ### 관련예제 소스코드 4 | * Chapter 03. 웹 API 통합을 위한 기술 - 02. spring cloud gateway 활용 5 | * Chapter 04. 분산시스템관리를 위한 Discovery pattern - 02. eurkea 활용실습 6 | * Chapter 05. 쓰기요청 분산처리를 위한 메시지 큐 활용 - 01. 분산환경에서 쓰기 요청을 분산처리 하려면 7 | * Chapter 05. 쓰기요청 분산처리를 위한 메시지 큐 활용 - 03. spring amqp를 이용한 rabbitmq 연동 8 | * Chapter 05. 쓰기요청 분산처리를 위한 메시지 큐 활용 - 04. spring kafka를 이용한 kafka 연동 9 | * Chapter 05. 쓰기요청 분산처리를 위한 메시지 큐 활용 - 05. spring cloud stream을 이용한 rabbitmq, kafka 연동 10 | * Chapter 06. 분산환경에서 API Client 개발 - 01. Ribbon과 FeignClient 11 | * Chapter 06. 분산환경에서 API Client 개발 - 02. FeignClient 를 이용한 API 연동 12 | * Chapter 06. 분산환경에서 API Client 개발 - 03. FeignClient와 eurkea 연동 13 | * Chapter 07. 장애허용시스템 구축 - 04. resilience4j 를 활용한 circuit breaker 패턴 적용 14 | * Chapter 08. 구글 GCP 활용 - 02. 구글 GCP에 예제 컴포넌트 배포 15 | * Chapter 08. 구글 GCP 활용 - 03. 구글 GCP에 spring Cloud 관련 기능 활용 16 | * Chapter 09. 분산환경에서 서버설정 통합관리 - 01. 스프링 클라우드 컨피그 소개 17 | * Chapter 09. 분산환경에서 서버설정 통합관리 - 02. 스프링클라우드에서 컨피그를 연동하여 설정 정보 업데이트 관리 18 | * Chapter 09. 분산환경에서 서버설정 통합관리 - 03. 스프링클라우드 볼트를 이용한 설정정보 보안 19 | * Chapter 10. 분산환경에서 모니터링 - 01. 스프링클라우드 어드민을 이용한 모듈별 상태 관리 20 | * Chapter 10. 분산환경에서 모니터링 - 02. 분산환경에서 로깅을 위한 MDC 21 | * Chapter 10. 분산환경에서 모니터링 - 03. 스프링클라우드의 슬루스와 집킨을 이용한 모니터링 -------------------------------------------------------------------------------- /settings.gradle.kts: -------------------------------------------------------------------------------- 1 | /* 2 | * This file was generated by the Gradle 'init' task. 3 | * 4 | * The settings file is used to specify which projects to include in your build. 5 | * 6 | * Detailed information about configuring a multi-project build in Gradle can be found 7 | * in the user manual at https://docs.gradle.org/6.7.1/userguide/multi_project_builds.html 8 | */ 9 | 10 | rootProject.name = "fastcampus-spring-cloud" 11 | 12 | include( 13 | "fastcam-spring-utils", 14 | "fastcam-spring-eureka", 15 | "fastcam-spring-apigw", 16 | "fastcam-photoapp", 17 | "fastcam-spring-rabbitmq", 18 | "fastcam-spring-kafka", 19 | "fastcam-resilience4j", 20 | "fastcam-resilience4j-server", 21 | "fastcam-feignclient", 22 | "fastcam-spring-config", 23 | "fastcam-spring-config-consumer", 24 | "fastcam-spring-admin", 25 | "fastcam-spring-sleuth", 26 | "fastcam-spring-vault") 27 | 28 | --------------------------------------------------------------------------------