Spaces:
Sleeping
Sleeping
adding file
Browse filesThis view is limited to 50 files because it contains too many changes.
See raw diff
- .classpath +29 -0
- .dockerignore +10 -0
- .idea/Task ManagementSystem.iml +9 -0
- .idea/gradle.xml +7 -0
- .idea/misc.xml +6 -0
- .idea/modules.xml +8 -0
- .idea/vcs.xml +6 -0
- .idea/workspace.xml +159 -0
- .project +28 -0
- .vscode/settings.json +10 -0
- APIGateWay/.gitignore +37 -0
- APIGateWay/Dockerfile +13 -0
- APIGateWay/build.gradle +59 -0
- APIGateWay/gradle/wrapper/gradle-wrapper.jar +0 -0
- APIGateWay/gradle/wrapper/gradle-wrapper.properties +7 -0
- APIGateWay/gradlew +249 -0
- APIGateWay/gradlew.bat +92 -0
- APIGateWay/settings.gradle +1 -0
- APIGateWay/src/main/java/in/garvit/tasks/ApiGateWayApplication.java +14 -0
- APIGateWay/src/main/java/in/garvit/tasks/controller/FallbackController.java +38 -0
- APIGateWay/src/main/resources/application-docker.yml +109 -0
- APIGateWay/src/main/resources/application.yml +113 -0
- APIGateWay/src/test/java/in/garvit/tasks/ApiGateWayApplicationTests.java +13 -0
- Dockerfile +49 -0
- EurekaServerConfiguration/.gitignore +50 -0
- EurekaServerConfiguration/Dockerfile +26 -0
- EurekaServerConfiguration/README.md +188 -0
- EurekaServerConfiguration/build.gradle +75 -0
- EurekaServerConfiguration/gradle/wrapper/gradle-wrapper.jar +0 -0
- EurekaServerConfiguration/gradle/wrapper/gradle-wrapper.properties +7 -0
- EurekaServerConfiguration/gradlew +249 -0
- EurekaServerConfiguration/gradlew.bat +92 -0
- EurekaServerConfiguration/settings.gradle +1 -0
- EurekaServerConfiguration/src/main/java/in/garvit/tasks/EurekaServerConfigurationApplication.java +51 -0
- EurekaServerConfiguration/src/main/java/in/garvit/tasks/config/EurekaServerConfig.java +40 -0
- EurekaServerConfiguration/src/main/java/in/garvit/tasks/controller/EurekaHealthIndicator.java +55 -0
- EurekaServerConfiguration/src/main/java/in/garvit/tasks/controller/EurekaInfoController.java +45 -0
- EurekaServerConfiguration/src/main/resources/META-INF/additional-spring-configuration-metadata.json +34 -0
- EurekaServerConfiguration/src/main/resources/application-docker.properties +38 -0
- EurekaServerConfiguration/src/main/resources/application.properties +40 -0
- EurekaServerConfiguration/src/main/resources/logback-spring.xml +49 -0
- EurekaServerConfiguration/src/test/java/in/garvit/tasks/EurekaServerConfigurationApplicationTests.java +28 -0
- EurekaServerConfiguration/src/test/resources/application-test.properties +25 -0
- FRONTEND_INTEGRATION_ISSUES.md +200 -0
- QUICKSTART.md +297 -0
- README.md +216 -7
- TaskService/.gitignore +37 -0
- TaskService/API_REFERENCE.md +425 -0
- TaskService/CHANGELOG.md +94 -0
- TaskService/Dockerfile +16 -0
.classpath
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
<?xml version="1.0" encoding="UTF-8"?>
|
| 2 |
+
<classpath>
|
| 3 |
+
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
|
| 4 |
+
<classpathentry kind="src" path="APIGateWay/src/main/java"/>
|
| 5 |
+
<classpathentry kind="src" path="APIGateWay/src/test/java"/>
|
| 6 |
+
<classpathentry kind="src" path="EurekaServerConfiguration/src/main/java"/>
|
| 7 |
+
<classpathentry kind="src" path="EurekaServerConfiguration/src/test/java"/>
|
| 8 |
+
<classpathentry kind="src" path="TaskService/src/main/java"/>
|
| 9 |
+
<classpathentry kind="src" path="TaskService/src/test/java"/>
|
| 10 |
+
<classpathentry kind="src" path="TaskSubmissionService/src/main/java"/>
|
| 11 |
+
<classpathentry kind="src" path="TaskSubmissionService/src/test/java"/>
|
| 12 |
+
<classpathentry kind="src" path="TaskUserService/src/main/java"/>
|
| 13 |
+
<classpathentry kind="src" path="TaskUserService/src/test/java"/>
|
| 14 |
+
<classpathentry kind="src" path="UserService/src/main/java"/>
|
| 15 |
+
<classpathentry kind="src" path="UserService/src/test/java"/>
|
| 16 |
+
<classpathentry kind="src" path="ZipkinDemoProject/src/main/java"/>
|
| 17 |
+
<classpathentry kind="src" path="ZipkinDemoProject/src/test/java"/>
|
| 18 |
+
<classpathentry kind="src" path="ZipkinProject/src/main/java"/>
|
| 19 |
+
<classpathentry kind="src" path="ZipkinProject/src/test/java"/>
|
| 20 |
+
<classpathentry kind="lib" path="APIGateWay/gradle/wrapper/gradle-wrapper.jar"/>
|
| 21 |
+
<classpathentry kind="lib" path="EurekaServerConfiguration/gradle/wrapper/gradle-wrapper.jar"/>
|
| 22 |
+
<classpathentry kind="lib" path="TaskService/gradle/wrapper/gradle-wrapper.jar"/>
|
| 23 |
+
<classpathentry kind="lib" path="TaskSubmissionService/gradle/wrapper/gradle-wrapper.jar"/>
|
| 24 |
+
<classpathentry kind="lib" path="TaskUserService/gradle/wrapper/gradle-wrapper.jar"/>
|
| 25 |
+
<classpathentry kind="lib" path="UserService/.mvn/wrapper/maven-wrapper.jar"/>
|
| 26 |
+
<classpathentry kind="lib" path="ZipkinDemoProject/.mvn/wrapper/maven-wrapper.jar"/>
|
| 27 |
+
<classpathentry kind="lib" path="ZipkinProject/gradle/wrapper/gradle-wrapper.jar"/>
|
| 28 |
+
<classpathentry kind="output" path="APIGateWay/bin/main"/>
|
| 29 |
+
</classpath>
|
.dockerignore
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
.git
|
| 2 |
+
.gitignore
|
| 3 |
+
**/build/
|
| 4 |
+
**/node_modules/
|
| 5 |
+
**/.gradle/
|
| 6 |
+
**/out/
|
| 7 |
+
**/*.log
|
| 8 |
+
.DS_Store
|
| 9 |
+
.idea/
|
| 10 |
+
.vscode/
|
.idea/Task ManagementSystem.iml
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
<?xml version="1.0" encoding="UTF-8"?>
|
| 2 |
+
<module type="JAVA_MODULE" version="4">
|
| 3 |
+
<component name="NewModuleRootManager" inherit-compiler-output="true">
|
| 4 |
+
<exclude-output />
|
| 5 |
+
<content url="file://$MODULE_DIR$" />
|
| 6 |
+
<orderEntry type="inheritedJdk" />
|
| 7 |
+
<orderEntry type="sourceFolder" forTests="false" />
|
| 8 |
+
</component>
|
| 9 |
+
</module>
|
.idea/gradle.xml
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
<?xml version="1.0" encoding="UTF-8"?>
|
| 2 |
+
<project version="4">
|
| 3 |
+
<component name="GradleMigrationSettings" migrationVersion="1" />
|
| 4 |
+
<component name="GradleSettings">
|
| 5 |
+
<option name="parallelModelFetch" value="true" />
|
| 6 |
+
</component>
|
| 7 |
+
</project>
|
.idea/misc.xml
ADDED
|
@@ -0,0 +1,6 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
<?xml version="1.0" encoding="UTF-8"?>
|
| 2 |
+
<project version="4">
|
| 3 |
+
<component name="ProjectRootManager" version="2" project-jdk-name="21" project-jdk-type="JavaSDK">
|
| 4 |
+
<output url="file://$PROJECT_DIR$/out" />
|
| 5 |
+
</component>
|
| 6 |
+
</project>
|
.idea/modules.xml
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
<?xml version="1.0" encoding="UTF-8"?>
|
| 2 |
+
<project version="4">
|
| 3 |
+
<component name="ProjectModuleManager">
|
| 4 |
+
<modules>
|
| 5 |
+
<module fileurl="file://$PROJECT_DIR$/.idea/Task ManagementSystem.iml" filepath="$PROJECT_DIR$/.idea/Task ManagementSystem.iml" />
|
| 6 |
+
</modules>
|
| 7 |
+
</component>
|
| 8 |
+
</project>
|
.idea/vcs.xml
ADDED
|
@@ -0,0 +1,6 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
<?xml version="1.0" encoding="UTF-8"?>
|
| 2 |
+
<project version="4">
|
| 3 |
+
<component name="VcsDirectoryMappings">
|
| 4 |
+
<mapping directory="" vcs="Git" />
|
| 5 |
+
</component>
|
| 6 |
+
</project>
|
.idea/workspace.xml
ADDED
|
@@ -0,0 +1,159 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
<?xml version="1.0" encoding="UTF-8"?>
|
| 2 |
+
<project version="4">
|
| 3 |
+
<component name="AutoImportSettings">
|
| 4 |
+
<option name="autoReloadType" value="SELECTIVE" />
|
| 5 |
+
</component>
|
| 6 |
+
<component name="ChangeListManager">
|
| 7 |
+
<list default="true" id="c67da803-df2c-4e52-b76f-66886ddeae27" name="Changes" comment="">
|
| 8 |
+
<change beforePath="$PROJECT_DIR$/.idea/workspace.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/workspace.xml" afterDir="false" />
|
| 9 |
+
<change beforePath="$PROJECT_DIR$/APIGateWay/Dockerfile" beforeDir="false" afterPath="$PROJECT_DIR$/APIGateWay/Dockerfile" afterDir="false" />
|
| 10 |
+
<change beforePath="$PROJECT_DIR$/APIGateWay/src/main/resources/application-docker.yml" beforeDir="false" afterPath="$PROJECT_DIR$/APIGateWay/src/main/resources/application-docker.yml" afterDir="false" />
|
| 11 |
+
<change beforePath="$PROJECT_DIR$/APIGateWay/src/main/resources/application.yml" beforeDir="false" afterPath="$PROJECT_DIR$/APIGateWay/src/main/resources/application.yml" afterDir="false" />
|
| 12 |
+
<change beforePath="$PROJECT_DIR$/EurekaServerConfiguration/.gitignore" beforeDir="false" afterPath="$PROJECT_DIR$/EurekaServerConfiguration/.gitignore" afterDir="false" />
|
| 13 |
+
<change beforePath="$PROJECT_DIR$/EurekaServerConfiguration/Dockerfile" beforeDir="false" afterPath="$PROJECT_DIR$/EurekaServerConfiguration/Dockerfile" afterDir="false" />
|
| 14 |
+
<change beforePath="$PROJECT_DIR$/EurekaServerConfiguration/build.gradle" beforeDir="false" afterPath="$PROJECT_DIR$/EurekaServerConfiguration/build.gradle" afterDir="false" />
|
| 15 |
+
<change beforePath="$PROJECT_DIR$/EurekaServerConfiguration/src/main/java/in/garvit/tasks/EurekaServerConfigurationApplication.java" beforeDir="false" afterPath="$PROJECT_DIR$/EurekaServerConfiguration/src/main/java/in/garvit/tasks/EurekaServerConfigurationApplication.java" afterDir="false" />
|
| 16 |
+
<change beforePath="$PROJECT_DIR$/EurekaServerConfiguration/src/main/resources/META-INF/additional-spring-configuration-metadata.json" beforeDir="false" afterPath="$PROJECT_DIR$/EurekaServerConfiguration/src/main/resources/META-INF/additional-spring-configuration-metadata.json" afterDir="false" />
|
| 17 |
+
<change beforePath="$PROJECT_DIR$/EurekaServerConfiguration/src/main/resources/application-docker.properties" beforeDir="false" afterPath="$PROJECT_DIR$/EurekaServerConfiguration/src/main/resources/application-docker.properties" afterDir="false" />
|
| 18 |
+
<change beforePath="$PROJECT_DIR$/EurekaServerConfiguration/src/main/resources/application.properties" beforeDir="false" afterPath="$PROJECT_DIR$/EurekaServerConfiguration/src/main/resources/application.properties" afterDir="false" />
|
| 19 |
+
<change beforePath="$PROJECT_DIR$/EurekaServerConfiguration/src/test/java/in/garvit/tasks/EurekaServerConfigurationApplicationTests.java" beforeDir="false" afterPath="$PROJECT_DIR$/EurekaServerConfiguration/src/test/java/in/garvit/tasks/EurekaServerConfigurationApplicationTests.java" afterDir="false" />
|
| 20 |
+
<change beforePath="$PROJECT_DIR$/TaskService/Dockerfile" beforeDir="false" afterPath="$PROJECT_DIR$/TaskService/Dockerfile" afterDir="false" />
|
| 21 |
+
<change beforePath="$PROJECT_DIR$/TaskService/build.gradle" beforeDir="false" afterPath="$PROJECT_DIR$/TaskService/build.gradle" afterDir="false" />
|
| 22 |
+
<change beforePath="$PROJECT_DIR$/TaskService/src/main/java/in/garvit/tasks/controller/HomeController.java" beforeDir="false" afterPath="$PROJECT_DIR$/TaskService/src/main/java/in/garvit/tasks/controller/HomeController.java" afterDir="false" />
|
| 23 |
+
<change beforePath="$PROJECT_DIR$/TaskService/src/main/java/in/garvit/tasks/controller/TaskController.java" beforeDir="false" afterPath="$PROJECT_DIR$/TaskService/src/main/java/in/garvit/tasks/controller/TaskController.java" afterDir="false" />
|
| 24 |
+
<change beforePath="$PROJECT_DIR$/TaskService/src/main/java/in/garvit/tasks/enums/TaskStatus.java" beforeDir="false" afterPath="$PROJECT_DIR$/TaskService/src/main/java/in/garvit/tasks/enums/TaskStatus.java" afterDir="false" />
|
| 25 |
+
<change beforePath="$PROJECT_DIR$/TaskService/src/main/java/in/garvit/tasks/repository/TaskRepository.java" beforeDir="false" afterPath="$PROJECT_DIR$/TaskService/src/main/java/in/garvit/tasks/repository/TaskRepository.java" afterDir="false" />
|
| 26 |
+
<change beforePath="$PROJECT_DIR$/TaskService/src/main/java/in/garvit/tasks/service/TaskService.java" beforeDir="false" afterPath="$PROJECT_DIR$/TaskService/src/main/java/in/garvit/tasks/service/TaskService.java" afterDir="false" />
|
| 27 |
+
<change beforePath="$PROJECT_DIR$/TaskService/src/main/java/in/garvit/tasks/service/TaskServiceImplementation.java" beforeDir="false" afterPath="$PROJECT_DIR$/TaskService/src/main/java/in/garvit/tasks/service/TaskServiceImplementation.java" afterDir="false" />
|
| 28 |
+
<change beforePath="$PROJECT_DIR$/TaskService/src/main/java/in/garvit/tasks/service/UserService.java" beforeDir="false" afterPath="$PROJECT_DIR$/TaskService/src/main/java/in/garvit/tasks/service/UserService.java" afterDir="false" />
|
| 29 |
+
<change beforePath="$PROJECT_DIR$/TaskService/src/main/java/in/garvit/tasks/taskModel/Task.java" beforeDir="false" afterPath="$PROJECT_DIR$/TaskService/src/main/java/in/garvit/tasks/taskModel/Task.java" afterDir="false" />
|
| 30 |
+
<change beforePath="$PROJECT_DIR$/TaskService/src/main/java/in/garvit/tasks/taskModel/UserDTO.java" beforeDir="false" afterPath="$PROJECT_DIR$/TaskService/src/main/java/in/garvit/tasks/taskModel/UserDTO.java" afterDir="false" />
|
| 31 |
+
<change beforePath="$PROJECT_DIR$/TaskService/src/test/java/in/garvit/tasks/TaskServiceApplicationTests.java" beforeDir="false" afterPath="$PROJECT_DIR$/TaskService/src/test/java/in/garvit/tasks/TaskServiceApplicationTests.java" afterDir="false" />
|
| 32 |
+
<change beforePath="$PROJECT_DIR$/TaskSubmissionService/src/main/java/in/garvit/tasks/submissionModel/TaskSubmission.java" beforeDir="false" afterPath="$PROJECT_DIR$/TaskSubmissionService/src/main/java/in/garvit/tasks/submissionModel/TaskSubmission.java" afterDir="false" />
|
| 33 |
+
</list>
|
| 34 |
+
<option name="SHOW_DIALOG" value="false" />
|
| 35 |
+
<option name="HIGHLIGHT_CONFLICTS" value="true" />
|
| 36 |
+
<option name="HIGHLIGHT_NON_ACTIVE_CHANGELIST" value="false" />
|
| 37 |
+
<option name="LAST_RESOLUTION" value="IGNORE" />
|
| 38 |
+
</component>
|
| 39 |
+
<component name="ExternalProjectsManager">
|
| 40 |
+
<system id="GRADLE">
|
| 41 |
+
<state>
|
| 42 |
+
<task path="$PROJECT_DIR$/EurekaServerConfiguration">
|
| 43 |
+
<activation />
|
| 44 |
+
</task>
|
| 45 |
+
<projects_view />
|
| 46 |
+
</state>
|
| 47 |
+
</system>
|
| 48 |
+
</component>
|
| 49 |
+
<component name="FileTemplateManagerImpl">
|
| 50 |
+
<option name="RECENT_TEMPLATES">
|
| 51 |
+
<list>
|
| 52 |
+
<option value="Dockerfile" />
|
| 53 |
+
</list>
|
| 54 |
+
</option>
|
| 55 |
+
</component>
|
| 56 |
+
<component name="Git.Settings">
|
| 57 |
+
<option name="RECENT_GIT_ROOT_PATH" value="$PROJECT_DIR$" />
|
| 58 |
+
</component>
|
| 59 |
+
<component name="GitHubPullRequestSearchHistory">{
|
| 60 |
+
"lastFilter": {
|
| 61 |
+
"state": "OPEN",
|
| 62 |
+
"assignee": "garvitpathak27"
|
| 63 |
+
}
|
| 64 |
+
}</component>
|
| 65 |
+
<component name="GithubPullRequestsUISettings">{
|
| 66 |
+
"selectedUrlAndAccountId": {
|
| 67 |
+
"url": "https://github.com/garvitpathak27/Task-Management-System-using-microservices.git",
|
| 68 |
+
"accountId": "48ce2745-8d73-42b2-bbce-9c06be004cf4"
|
| 69 |
+
}
|
| 70 |
+
}</component>
|
| 71 |
+
<component name="MarkdownSettingsMigration">
|
| 72 |
+
<option name="stateVersion" value="1" />
|
| 73 |
+
</component>
|
| 74 |
+
<component name="ProjectColorInfo">{
|
| 75 |
+
"associatedIndex": 0
|
| 76 |
+
}</component>
|
| 77 |
+
<component name="ProjectId" id="2cMQfo36h3efNXGKSYcbJDFQpZy" />
|
| 78 |
+
<component name="ProjectLevelVcsManager">
|
| 79 |
+
<ConfirmationsSetting value="2" id="Add" />
|
| 80 |
+
</component>
|
| 81 |
+
<component name="ProjectViewState">
|
| 82 |
+
<option name="hideEmptyMiddlePackages" value="true" />
|
| 83 |
+
<option name="showLibraryContents" value="true" />
|
| 84 |
+
</component>
|
| 85 |
+
<component name="PropertiesComponent"><![CDATA[{
|
| 86 |
+
"keyToString": {
|
| 87 |
+
"Gradle.C:/Users/garvit/Documents/workspace-spring-tool-suite-4-4.21.0.RELEASE/Task ManagementSystem/EurekaServerConfiguration.executor": "Run",
|
| 88 |
+
"Gradle.Gradle.executor": "Run",
|
| 89 |
+
"RunOnceActivity.OpenProjectViewOnStart": "true",
|
| 90 |
+
"RunOnceActivity.ShowReadmeOnStart": "true",
|
| 91 |
+
"RunOnceActivity.TerminalTabsStorage.copyFrom.TerminalArrangementManager.252": "true",
|
| 92 |
+
"RunOnceActivity.git.unshallow": "true",
|
| 93 |
+
"git-widget-placeholder": "master",
|
| 94 |
+
"ignore.virus.scanning.warn.message": "true",
|
| 95 |
+
"kotlin-language-version-configured": "true",
|
| 96 |
+
"last_opened_file_path": "/home/garvitpathak27/cloud_computing/Task-Management-System-using-microservices",
|
| 97 |
+
"node.js.detected.package.eslint": "true",
|
| 98 |
+
"node.js.detected.package.tslint": "true",
|
| 99 |
+
"node.js.selected.package.eslint": "(autodetect)",
|
| 100 |
+
"node.js.selected.package.tslint": "(autodetect)",
|
| 101 |
+
"nodejs_package_manager_path": "npm",
|
| 102 |
+
"project.structure.last.edited": "Project",
|
| 103 |
+
"project.structure.proportion": "0.0",
|
| 104 |
+
"project.structure.side.proportion": "0.0",
|
| 105 |
+
"settings.editor.selected.configurable": "settings.sync",
|
| 106 |
+
"vue.rearranger.settings.migration": "true"
|
| 107 |
+
}
|
| 108 |
+
}]]></component>
|
| 109 |
+
<component name="RecentsManager">
|
| 110 |
+
<key name="CopyFile.RECENT_KEYS">
|
| 111 |
+
<recent name="$PROJECT_DIR$/TaskService/src/main/java/in" />
|
| 112 |
+
</key>
|
| 113 |
+
</component>
|
| 114 |
+
<component name="RunManager">
|
| 115 |
+
<configuration name="C:/Users/garvit/Documents/workspace-spring-tool-suite-4-4.21.0.RELEASE/Task ManagementSystem/EurekaServerConfiguration" type="GradleRunConfiguration" factoryName="Gradle" nameIsGenerated="true">
|
| 116 |
+
<ExternalSystemSettings>
|
| 117 |
+
<option name="executionName" />
|
| 118 |
+
<option name="externalProjectPath" value="$PROJECT_DIR$/EurekaServerConfiguration" />
|
| 119 |
+
<option name="externalSystemIdString" value="GRADLE" />
|
| 120 |
+
<option name="scriptParameters" value="" />
|
| 121 |
+
<option name="taskDescriptions">
|
| 122 |
+
<list />
|
| 123 |
+
</option>
|
| 124 |
+
<option name="taskNames">
|
| 125 |
+
<list />
|
| 126 |
+
</option>
|
| 127 |
+
<option name="vmOptions" />
|
| 128 |
+
</ExternalSystemSettings>
|
| 129 |
+
<ExternalSystemDebugServerProcess>true</ExternalSystemDebugServerProcess>
|
| 130 |
+
<ExternalSystemReattachDebugProcess>true</ExternalSystemReattachDebugProcess>
|
| 131 |
+
<DebugAllEnabled>false</DebugAllEnabled>
|
| 132 |
+
<RunAsTest>false</RunAsTest>
|
| 133 |
+
<method v="2" />
|
| 134 |
+
</configuration>
|
| 135 |
+
</component>
|
| 136 |
+
<component name="SpellCheckerSettings" RuntimeDictionaries="0" Folders="0" CustomDictionaries="0" DefaultDictionary="application-level" UseSingleDictionary="true" transferred="true" />
|
| 137 |
+
<component name="TaskManager">
|
| 138 |
+
<task active="true" id="Default" summary="Default task">
|
| 139 |
+
<changelist id="c67da803-df2c-4e52-b76f-66886ddeae27" name="Changes" comment="" />
|
| 140 |
+
<created>1707919077382</created>
|
| 141 |
+
<option name="number" value="Default" />
|
| 142 |
+
<option name="presentableId" value="Default" />
|
| 143 |
+
<updated>1707919077382</updated>
|
| 144 |
+
<workItem from="1707919078192" duration="1548000" />
|
| 145 |
+
<workItem from="1707920639016" duration="14000" />
|
| 146 |
+
<workItem from="1707920675885" duration="12000" />
|
| 147 |
+
<workItem from="1707924022325" duration="42000" />
|
| 148 |
+
<workItem from="1708164783782" duration="156000" />
|
| 149 |
+
</task>
|
| 150 |
+
<servers />
|
| 151 |
+
</component>
|
| 152 |
+
<component name="TypeScriptGeneratedFilesManager">
|
| 153 |
+
<option name="version" value="3" />
|
| 154 |
+
</component>
|
| 155 |
+
<component name="XSLT-Support.FileAssociations.UIState">
|
| 156 |
+
<expand />
|
| 157 |
+
<select />
|
| 158 |
+
</component>
|
| 159 |
+
</project>
|
.project
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
<?xml version="1.0" encoding="UTF-8"?>
|
| 2 |
+
<projectDescription>
|
| 3 |
+
<name>Task ManagementSystem</name>
|
| 4 |
+
<comment></comment>
|
| 5 |
+
<projects>
|
| 6 |
+
</projects>
|
| 7 |
+
<buildSpec>
|
| 8 |
+
<buildCommand>
|
| 9 |
+
<name>org.eclipse.jdt.core.javabuilder</name>
|
| 10 |
+
<arguments>
|
| 11 |
+
</arguments>
|
| 12 |
+
</buildCommand>
|
| 13 |
+
</buildSpec>
|
| 14 |
+
<natures>
|
| 15 |
+
<nature>org.eclipse.jdt.core.javanature</nature>
|
| 16 |
+
</natures>
|
| 17 |
+
<filteredResources>
|
| 18 |
+
<filter>
|
| 19 |
+
<id>1759173395110</id>
|
| 20 |
+
<name></name>
|
| 21 |
+
<type>30</type>
|
| 22 |
+
<matcher>
|
| 23 |
+
<id>org.eclipse.core.resources.regexFilterMatcher</id>
|
| 24 |
+
<arguments>node_modules|\.git|__CREATED_BY_JAVA_LANGUAGE_SERVER__</arguments>
|
| 25 |
+
</matcher>
|
| 26 |
+
</filter>
|
| 27 |
+
</filteredResources>
|
| 28 |
+
</projectDescription>
|
.vscode/settings.json
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"java.compile.nullAnalysis.mode": "automatic",
|
| 3 |
+
"cSpell.words": [
|
| 4 |
+
"openfeign",
|
| 5 |
+
"projectlombok",
|
| 6 |
+
"springframework",
|
| 7 |
+
"zipkin"
|
| 8 |
+
],
|
| 9 |
+
"java.configuration.updateBuildConfiguration": "interactive"
|
| 10 |
+
}
|
APIGateWay/.gitignore
ADDED
|
@@ -0,0 +1,37 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 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/
|
APIGateWay/Dockerfile
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
FROM eclipse-temurin:17-jre-alpine
|
| 2 |
+
|
| 3 |
+
LABEL authors="garvitpathak27"
|
| 4 |
+
|
| 5 |
+
WORKDIR /app
|
| 6 |
+
|
| 7 |
+
RUN apk add --no-cache curl
|
| 8 |
+
|
| 9 |
+
COPY build/libs/api-gateway.jar app.jar
|
| 10 |
+
|
| 11 |
+
EXPOSE 8090
|
| 12 |
+
|
| 13 |
+
ENTRYPOINT ["java","-jar","/app/app.jar"]
|
APIGateWay/build.gradle
ADDED
|
@@ -0,0 +1,59 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
plugins {
|
| 2 |
+
id 'java'
|
| 3 |
+
id 'org.springframework.boot' version '3.2.2'
|
| 4 |
+
id 'io.spring.dependency-management' version '1.1.4'
|
| 5 |
+
}
|
| 6 |
+
|
| 7 |
+
group = 'com.example'
|
| 8 |
+
version = '0.0.1-SNAPSHOT'
|
| 9 |
+
|
| 10 |
+
java {
|
| 11 |
+
sourceCompatibility = '17'
|
| 12 |
+
}
|
| 13 |
+
|
| 14 |
+
repositories {
|
| 15 |
+
mavenCentral()
|
| 16 |
+
}
|
| 17 |
+
|
| 18 |
+
ext {
|
| 19 |
+
set('springCloudVersion', "2023.0.0")
|
| 20 |
+
}
|
| 21 |
+
|
| 22 |
+
dependencies {
|
| 23 |
+
implementation 'org.springframework.cloud:spring-cloud-starter-netflix-eureka-client'
|
| 24 |
+
testImplementation 'org.springframework.boot:spring-boot-starter-test'
|
| 25 |
+
implementation 'org.springframework.cloud:spring-cloud-starter-gateway'
|
| 26 |
+
implementation 'org.springframework.cloud:spring-cloud-starter-circuitbreaker-reactor-resilience4j'
|
| 27 |
+
implementation 'org.springframework.retry:spring-retry'
|
| 28 |
+
implementation 'org.springframework.boot:spring-boot-starter-actuator'
|
| 29 |
+
//zipkin tracing
|
| 30 |
+
implementation 'io.micrometer:micrometer-tracing-bridge-brave'
|
| 31 |
+
implementation 'io.zipkin.reporter2:zipkin-reporter-brave'
|
| 32 |
+
// https://mvnrepository.com/artifact/org.springframework.cloud/spring-cloud-starter-sleuth
|
| 33 |
+
//implementation group: 'org.springframework.cloud', name: 'spring-cloud-starter-sleuth', version: '3.1.11'
|
| 34 |
+
|
| 35 |
+
// Zipkin server dependency
|
| 36 |
+
//implementation 'io.zipkin.java:zipkin-server:2.12.9'
|
| 37 |
+
|
| 38 |
+
// Zipkin autoconfigure UI dependency (runtime scope)
|
| 39 |
+
//runtimeOnly 'io.zipkin.java:zipkin-autoconfigure-ui:2.12.9'
|
| 40 |
+
|
| 41 |
+
}
|
| 42 |
+
|
| 43 |
+
dependencyManagement {
|
| 44 |
+
imports {
|
| 45 |
+
mavenBom "org.springframework.cloud:spring-cloud-dependencies:${springCloudVersion}"
|
| 46 |
+
}
|
| 47 |
+
}
|
| 48 |
+
|
| 49 |
+
tasks.named('test') {
|
| 50 |
+
useJUnitPlatform()
|
| 51 |
+
}
|
| 52 |
+
|
| 53 |
+
tasks.named('bootJar') {
|
| 54 |
+
archiveFileName = 'api-gateway.jar'
|
| 55 |
+
}
|
| 56 |
+
|
| 57 |
+
tasks.named('jar') {
|
| 58 |
+
enabled = false
|
| 59 |
+
}
|
APIGateWay/gradle/wrapper/gradle-wrapper.jar
ADDED
|
Binary file (43.5 kB). View file
|
|
|
APIGateWay/gradle/wrapper/gradle-wrapper.properties
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
distributionBase=GRADLE_USER_HOME
|
| 2 |
+
distributionPath=wrapper/dists
|
| 3 |
+
distributionUrl=https\://services.gradle.org/distributions/gradle-8.5-bin.zip
|
| 4 |
+
networkTimeout=10000
|
| 5 |
+
validateDistributionUrl=true
|
| 6 |
+
zipStoreBase=GRADLE_USER_HOME
|
| 7 |
+
zipStorePath=wrapper/dists
|
APIGateWay/gradlew
ADDED
|
@@ -0,0 +1,249 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#!/bin/sh
|
| 2 |
+
|
| 3 |
+
#
|
| 4 |
+
# Copyright © 2015-2021 the original 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 POSIX generated by Gradle.
|
| 22 |
+
#
|
| 23 |
+
# Important for running:
|
| 24 |
+
#
|
| 25 |
+
# (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is
|
| 26 |
+
# noncompliant, but you have some other compliant shell such as ksh or
|
| 27 |
+
# bash, then to run this script, type that shell name before the whole
|
| 28 |
+
# command line, like:
|
| 29 |
+
#
|
| 30 |
+
# ksh Gradle
|
| 31 |
+
#
|
| 32 |
+
# Busybox and similar reduced shells will NOT work, because this script
|
| 33 |
+
# requires all of these POSIX shell features:
|
| 34 |
+
# * functions;
|
| 35 |
+
# * expansions «$var», «${var}», «${var:-default}», «${var+SET}»,
|
| 36 |
+
# «${var#prefix}», «${var%suffix}», and «$( cmd )»;
|
| 37 |
+
# * compound commands having a testable exit status, especially «case»;
|
| 38 |
+
# * various built-in commands including «command», «set», and «ulimit».
|
| 39 |
+
#
|
| 40 |
+
# Important for patching:
|
| 41 |
+
#
|
| 42 |
+
# (2) This script targets any POSIX shell, so it avoids extensions provided
|
| 43 |
+
# by Bash, Ksh, etc; in particular arrays are avoided.
|
| 44 |
+
#
|
| 45 |
+
# The "traditional" practice of packing multiple parameters into a
|
| 46 |
+
# space-separated string is a well documented source of bugs and security
|
| 47 |
+
# problems, so this is (mostly) avoided, by progressively accumulating
|
| 48 |
+
# options in "$@", and eventually passing that to Java.
|
| 49 |
+
#
|
| 50 |
+
# Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS,
|
| 51 |
+
# and GRADLE_OPTS) rely on word-splitting, this is performed explicitly;
|
| 52 |
+
# see the in-line comments for details.
|
| 53 |
+
#
|
| 54 |
+
# There are tweaks for specific operating systems such as AIX, CygWin,
|
| 55 |
+
# Darwin, MinGW, and NonStop.
|
| 56 |
+
#
|
| 57 |
+
# (3) This script is generated from the Groovy template
|
| 58 |
+
# https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
|
| 59 |
+
# within the Gradle project.
|
| 60 |
+
#
|
| 61 |
+
# You can find Gradle at https://github.com/gradle/gradle/.
|
| 62 |
+
#
|
| 63 |
+
##############################################################################
|
| 64 |
+
|
| 65 |
+
# Attempt to set APP_HOME
|
| 66 |
+
|
| 67 |
+
# Resolve links: $0 may be a link
|
| 68 |
+
app_path=$0
|
| 69 |
+
|
| 70 |
+
# Need this for daisy-chained symlinks.
|
| 71 |
+
while
|
| 72 |
+
APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path
|
| 73 |
+
[ -h "$app_path" ]
|
| 74 |
+
do
|
| 75 |
+
ls=$( ls -ld "$app_path" )
|
| 76 |
+
link=${ls#*' -> '}
|
| 77 |
+
case $link in #(
|
| 78 |
+
/*) app_path=$link ;; #(
|
| 79 |
+
*) app_path=$APP_HOME$link ;;
|
| 80 |
+
esac
|
| 81 |
+
done
|
| 82 |
+
|
| 83 |
+
# This is normally unused
|
| 84 |
+
# shellcheck disable=SC2034
|
| 85 |
+
APP_BASE_NAME=${0##*/}
|
| 86 |
+
# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036)
|
| 87 |
+
APP_HOME=$( cd "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit
|
| 88 |
+
|
| 89 |
+
# Use the maximum available, or set MAX_FD != -1 to use that value.
|
| 90 |
+
MAX_FD=maximum
|
| 91 |
+
|
| 92 |
+
warn () {
|
| 93 |
+
echo "$*"
|
| 94 |
+
} >&2
|
| 95 |
+
|
| 96 |
+
die () {
|
| 97 |
+
echo
|
| 98 |
+
echo "$*"
|
| 99 |
+
echo
|
| 100 |
+
exit 1
|
| 101 |
+
} >&2
|
| 102 |
+
|
| 103 |
+
# OS specific support (must be 'true' or 'false').
|
| 104 |
+
cygwin=false
|
| 105 |
+
msys=false
|
| 106 |
+
darwin=false
|
| 107 |
+
nonstop=false
|
| 108 |
+
case "$( uname )" in #(
|
| 109 |
+
CYGWIN* ) cygwin=true ;; #(
|
| 110 |
+
Darwin* ) darwin=true ;; #(
|
| 111 |
+
MSYS* | MINGW* ) msys=true ;; #(
|
| 112 |
+
NONSTOP* ) nonstop=true ;;
|
| 113 |
+
esac
|
| 114 |
+
|
| 115 |
+
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
|
| 116 |
+
|
| 117 |
+
|
| 118 |
+
# Determine the Java command to use to start the JVM.
|
| 119 |
+
if [ -n "$JAVA_HOME" ] ; then
|
| 120 |
+
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
|
| 121 |
+
# IBM's JDK on AIX uses strange locations for the executables
|
| 122 |
+
JAVACMD=$JAVA_HOME/jre/sh/java
|
| 123 |
+
else
|
| 124 |
+
JAVACMD=$JAVA_HOME/bin/java
|
| 125 |
+
fi
|
| 126 |
+
if [ ! -x "$JAVACMD" ] ; then
|
| 127 |
+
die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
|
| 128 |
+
|
| 129 |
+
Please set the JAVA_HOME variable in your environment to match the
|
| 130 |
+
location of your Java installation."
|
| 131 |
+
fi
|
| 132 |
+
else
|
| 133 |
+
JAVACMD=java
|
| 134 |
+
if ! command -v java >/dev/null 2>&1
|
| 135 |
+
then
|
| 136 |
+
die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
| 137 |
+
|
| 138 |
+
Please set the JAVA_HOME variable in your environment to match the
|
| 139 |
+
location of your Java installation."
|
| 140 |
+
fi
|
| 141 |
+
fi
|
| 142 |
+
|
| 143 |
+
# Increase the maximum file descriptors if we can.
|
| 144 |
+
if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then
|
| 145 |
+
case $MAX_FD in #(
|
| 146 |
+
max*)
|
| 147 |
+
# In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked.
|
| 148 |
+
# shellcheck disable=SC2039,SC3045
|
| 149 |
+
MAX_FD=$( ulimit -H -n ) ||
|
| 150 |
+
warn "Could not query maximum file descriptor limit"
|
| 151 |
+
esac
|
| 152 |
+
case $MAX_FD in #(
|
| 153 |
+
'' | soft) :;; #(
|
| 154 |
+
*)
|
| 155 |
+
# In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked.
|
| 156 |
+
# shellcheck disable=SC2039,SC3045
|
| 157 |
+
ulimit -n "$MAX_FD" ||
|
| 158 |
+
warn "Could not set maximum file descriptor limit to $MAX_FD"
|
| 159 |
+
esac
|
| 160 |
+
fi
|
| 161 |
+
|
| 162 |
+
# Collect all arguments for the java command, stacking in reverse order:
|
| 163 |
+
# * args from the command line
|
| 164 |
+
# * the main class name
|
| 165 |
+
# * -classpath
|
| 166 |
+
# * -D...appname settings
|
| 167 |
+
# * --module-path (only if needed)
|
| 168 |
+
# * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables.
|
| 169 |
+
|
| 170 |
+
# For Cygwin or MSYS, switch paths to Windows format before running java
|
| 171 |
+
if "$cygwin" || "$msys" ; then
|
| 172 |
+
APP_HOME=$( cygpath --path --mixed "$APP_HOME" )
|
| 173 |
+
CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" )
|
| 174 |
+
|
| 175 |
+
JAVACMD=$( cygpath --unix "$JAVACMD" )
|
| 176 |
+
|
| 177 |
+
# Now convert the arguments - kludge to limit ourselves to /bin/sh
|
| 178 |
+
for arg do
|
| 179 |
+
if
|
| 180 |
+
case $arg in #(
|
| 181 |
+
-*) false ;; # don't mess with options #(
|
| 182 |
+
/?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath
|
| 183 |
+
[ -e "$t" ] ;; #(
|
| 184 |
+
*) false ;;
|
| 185 |
+
esac
|
| 186 |
+
then
|
| 187 |
+
arg=$( cygpath --path --ignore --mixed "$arg" )
|
| 188 |
+
fi
|
| 189 |
+
# Roll the args list around exactly as many times as the number of
|
| 190 |
+
# args, so each arg winds up back in the position where it started, but
|
| 191 |
+
# possibly modified.
|
| 192 |
+
#
|
| 193 |
+
# NB: a `for` loop captures its iteration list before it begins, so
|
| 194 |
+
# changing the positional parameters here affects neither the number of
|
| 195 |
+
# iterations, nor the values presented in `arg`.
|
| 196 |
+
shift # remove old arg
|
| 197 |
+
set -- "$@" "$arg" # push replacement arg
|
| 198 |
+
done
|
| 199 |
+
fi
|
| 200 |
+
|
| 201 |
+
|
| 202 |
+
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
| 203 |
+
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
|
| 204 |
+
|
| 205 |
+
# Collect all arguments for the java command:
|
| 206 |
+
# * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments,
|
| 207 |
+
# and any embedded shellness will be escaped.
|
| 208 |
+
# * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be
|
| 209 |
+
# treated as '${Hostname}' itself on the command line.
|
| 210 |
+
|
| 211 |
+
set -- \
|
| 212 |
+
"-Dorg.gradle.appname=$APP_BASE_NAME" \
|
| 213 |
+
-classpath "$CLASSPATH" \
|
| 214 |
+
org.gradle.wrapper.GradleWrapperMain \
|
| 215 |
+
"$@"
|
| 216 |
+
|
| 217 |
+
# Stop when "xargs" is not available.
|
| 218 |
+
if ! command -v xargs >/dev/null 2>&1
|
| 219 |
+
then
|
| 220 |
+
die "xargs is not available"
|
| 221 |
+
fi
|
| 222 |
+
|
| 223 |
+
# Use "xargs" to parse quoted args.
|
| 224 |
+
#
|
| 225 |
+
# With -n1 it outputs one arg per line, with the quotes and backslashes removed.
|
| 226 |
+
#
|
| 227 |
+
# In Bash we could simply go:
|
| 228 |
+
#
|
| 229 |
+
# readarray ARGS < <( xargs -n1 <<<"$var" ) &&
|
| 230 |
+
# set -- "${ARGS[@]}" "$@"
|
| 231 |
+
#
|
| 232 |
+
# but POSIX shell has neither arrays nor command substitution, so instead we
|
| 233 |
+
# post-process each arg (as a line of input to sed) to backslash-escape any
|
| 234 |
+
# character that might be a shell metacharacter, then use eval to reverse
|
| 235 |
+
# that process (while maintaining the separation between arguments), and wrap
|
| 236 |
+
# the whole thing up as a single "set" statement.
|
| 237 |
+
#
|
| 238 |
+
# This will of course break if any of these variables contains a newline or
|
| 239 |
+
# an unmatched quote.
|
| 240 |
+
#
|
| 241 |
+
|
| 242 |
+
eval "set -- $(
|
| 243 |
+
printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" |
|
| 244 |
+
xargs -n1 |
|
| 245 |
+
sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' |
|
| 246 |
+
tr '\n' ' '
|
| 247 |
+
)" '"$@"'
|
| 248 |
+
|
| 249 |
+
exec "$JAVACMD" "$@"
|
APIGateWay/gradlew.bat
ADDED
|
@@ -0,0 +1,92 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 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 |
+
@rem This is normally unused
|
| 30 |
+
set APP_BASE_NAME=%~n0
|
| 31 |
+
set APP_HOME=%DIRNAME%
|
| 32 |
+
|
| 33 |
+
@rem Resolve any "." and ".." in APP_HOME to make it shorter.
|
| 34 |
+
for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
|
| 35 |
+
|
| 36 |
+
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
| 37 |
+
set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
|
| 38 |
+
|
| 39 |
+
@rem Find java.exe
|
| 40 |
+
if defined JAVA_HOME goto findJavaFromJavaHome
|
| 41 |
+
|
| 42 |
+
set JAVA_EXE=java.exe
|
| 43 |
+
%JAVA_EXE% -version >NUL 2>&1
|
| 44 |
+
if %ERRORLEVEL% equ 0 goto execute
|
| 45 |
+
|
| 46 |
+
echo.
|
| 47 |
+
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
| 48 |
+
echo.
|
| 49 |
+
echo Please set the JAVA_HOME variable in your environment to match the
|
| 50 |
+
echo location of your Java installation.
|
| 51 |
+
|
| 52 |
+
goto fail
|
| 53 |
+
|
| 54 |
+
:findJavaFromJavaHome
|
| 55 |
+
set JAVA_HOME=%JAVA_HOME:"=%
|
| 56 |
+
set JAVA_EXE=%JAVA_HOME%/bin/java.exe
|
| 57 |
+
|
| 58 |
+
if exist "%JAVA_EXE%" goto execute
|
| 59 |
+
|
| 60 |
+
echo.
|
| 61 |
+
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
|
| 62 |
+
echo.
|
| 63 |
+
echo Please set the JAVA_HOME variable in your environment to match the
|
| 64 |
+
echo location of your Java installation.
|
| 65 |
+
|
| 66 |
+
goto fail
|
| 67 |
+
|
| 68 |
+
:execute
|
| 69 |
+
@rem Setup the command line
|
| 70 |
+
|
| 71 |
+
set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
|
| 72 |
+
|
| 73 |
+
|
| 74 |
+
@rem Execute Gradle
|
| 75 |
+
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %*
|
| 76 |
+
|
| 77 |
+
:end
|
| 78 |
+
@rem End local scope for the variables with windows NT shell
|
| 79 |
+
if %ERRORLEVEL% equ 0 goto mainEnd
|
| 80 |
+
|
| 81 |
+
:fail
|
| 82 |
+
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
|
| 83 |
+
rem the _cmd.exe /c_ return code!
|
| 84 |
+
set EXIT_CODE=%ERRORLEVEL%
|
| 85 |
+
if %EXIT_CODE% equ 0 set EXIT_CODE=1
|
| 86 |
+
if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE%
|
| 87 |
+
exit /b %EXIT_CODE%
|
| 88 |
+
|
| 89 |
+
:mainEnd
|
| 90 |
+
if "%OS%"=="Windows_NT" endlocal
|
| 91 |
+
|
| 92 |
+
:omega
|
APIGateWay/settings.gradle
ADDED
|
@@ -0,0 +1 @@
|
|
|
|
|
|
|
| 1 |
+
rootProject.name = 'APIGateWay'
|
APIGateWay/src/main/java/in/garvit/tasks/ApiGateWayApplication.java
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
package in.garvit.tasks;
|
| 2 |
+
|
| 3 |
+
import org.springframework.boot.SpringApplication;
|
| 4 |
+
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
| 5 |
+
|
| 6 |
+
|
| 7 |
+
@SpringBootApplication
|
| 8 |
+
public class ApiGateWayApplication {
|
| 9 |
+
|
| 10 |
+
public static void main(String[] args) {
|
| 11 |
+
SpringApplication.run(ApiGateWayApplication.class, args);
|
| 12 |
+
}
|
| 13 |
+
|
| 14 |
+
}
|
APIGateWay/src/main/java/in/garvit/tasks/controller/FallbackController.java
ADDED
|
@@ -0,0 +1,38 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
package in.garvit.tasks.controller;
|
| 2 |
+
|
| 3 |
+
import java.util.Map;
|
| 4 |
+
|
| 5 |
+
import org.springframework.http.HttpStatus;
|
| 6 |
+
import org.springframework.http.ResponseEntity;
|
| 7 |
+
import org.springframework.web.bind.annotation.GetMapping;
|
| 8 |
+
import org.springframework.web.bind.annotation.RequestMapping;
|
| 9 |
+
import org.springframework.web.bind.annotation.RestController;
|
| 10 |
+
|
| 11 |
+
/** Ensures circuit breaker fallbacks return a consistent payload instead of an empty 500. */
|
| 12 |
+
@RestController
|
| 13 |
+
@RequestMapping("/fallback")
|
| 14 |
+
public class FallbackController {
|
| 15 |
+
|
| 16 |
+
@GetMapping("/users")
|
| 17 |
+
public ResponseEntity<Map<String, String>> userServiceFallback() {
|
| 18 |
+
return buildFallbackResponse("User service is temporarily unavailable. Please try again shortly.");
|
| 19 |
+
}
|
| 20 |
+
|
| 21 |
+
@GetMapping("/tasks")
|
| 22 |
+
public ResponseEntity<Map<String, String>> taskServiceFallback() {
|
| 23 |
+
return buildFallbackResponse("Task service is temporarily unavailable. Please try again shortly.");
|
| 24 |
+
}
|
| 25 |
+
|
| 26 |
+
@GetMapping("/submissions")
|
| 27 |
+
public ResponseEntity<Map<String, String>> taskSubmissionServiceFallback() {
|
| 28 |
+
return buildFallbackResponse("Task submission service is temporarily unavailable. Please try again shortly.");
|
| 29 |
+
}
|
| 30 |
+
|
| 31 |
+
private ResponseEntity<Map<String, String>> buildFallbackResponse(String message) {
|
| 32 |
+
Map<String, String> body = Map.of(
|
| 33 |
+
"status", "SERVICE_UNAVAILABLE",
|
| 34 |
+
"message", message
|
| 35 |
+
);
|
| 36 |
+
return new ResponseEntity<>(body, HttpStatus.SERVICE_UNAVAILABLE);
|
| 37 |
+
}
|
| 38 |
+
}
|
APIGateWay/src/main/resources/application-docker.yml
ADDED
|
@@ -0,0 +1,109 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
server:
|
| 2 |
+
port: ${SERVER_PORT:8090}
|
| 3 |
+
tomcat:
|
| 4 |
+
max-threads: 200
|
| 5 |
+
connection-timeout: 5s
|
| 6 |
+
|
| 7 |
+
spring:
|
| 8 |
+
application:
|
| 9 |
+
name: ${SPRING_APP_NAME:API-GATEWAY-SERVER}
|
| 10 |
+
zipkin:
|
| 11 |
+
base-url: ${ZIPKIN_BASE_URL:http://zipkin:9411}
|
| 12 |
+
sleuth:
|
| 13 |
+
sampler:
|
| 14 |
+
probability: ${ZIPKIN_SAMPLER_PROBABILITY:1.0}
|
| 15 |
+
cloud:
|
| 16 |
+
gateway:
|
| 17 |
+
routes:
|
| 18 |
+
- id: user-service
|
| 19 |
+
uri: lb://USER-SERVICE
|
| 20 |
+
predicates:
|
| 21 |
+
- Path=/auth/**,/users/**,/api/users/**,/
|
| 22 |
+
filters:
|
| 23 |
+
- name: CircuitBreaker
|
| 24 |
+
args:
|
| 25 |
+
name: userServiceCircuitBreaker
|
| 26 |
+
fallbackUri: forward:/fallback/users
|
| 27 |
+
|
| 28 |
+
- id: task-service
|
| 29 |
+
uri: lb://TASK-SERVICE
|
| 30 |
+
predicates:
|
| 31 |
+
- Path=/api/tasks/**,/tasks/**
|
| 32 |
+
filters:
|
| 33 |
+
- name: CircuitBreaker
|
| 34 |
+
args:
|
| 35 |
+
name: taskServiceCircuitBreaker
|
| 36 |
+
fallbackUri: forward:/fallback/tasks
|
| 37 |
+
|
| 38 |
+
- id: task-submission-service
|
| 39 |
+
uri: lb://TASK-SUBMISSION
|
| 40 |
+
predicates:
|
| 41 |
+
- Path=/api/submissions/**,/submissions/**
|
| 42 |
+
filters:
|
| 43 |
+
- name: CircuitBreaker
|
| 44 |
+
args:
|
| 45 |
+
name: submissionServiceCircuitBreaker
|
| 46 |
+
fallbackUri: forward:/fallback/submissions
|
| 47 |
+
|
| 48 |
+
default-filters:
|
| 49 |
+
- DedupeResponseHeader=Access-Control-Allow-Credentials Access-Control-Allow-Origin
|
| 50 |
+
globalcors:
|
| 51 |
+
cors-configurations:
|
| 52 |
+
'[/**]':
|
| 53 |
+
allowedOrigins:
|
| 54 |
+
- ${GATEWAY_ALLOWED_ORIGIN_1:http://task-management-ui:3000}
|
| 55 |
+
- ${GATEWAY_ALLOWED_ORIGIN_2:http://localhost:3000}
|
| 56 |
+
allowedOriginPatterns:
|
| 57 |
+
- ${GATEWAY_ALLOWED_ORIGIN_PATTERN:*}
|
| 58 |
+
allowedMethods:
|
| 59 |
+
- GET
|
| 60 |
+
- POST
|
| 61 |
+
- PUT
|
| 62 |
+
- PATCH
|
| 63 |
+
- DELETE
|
| 64 |
+
- OPTIONS
|
| 65 |
+
allowedHeaders:
|
| 66 |
+
- Authorization
|
| 67 |
+
- Content-Type
|
| 68 |
+
- X-Requested-With
|
| 69 |
+
allowCredentials: true
|
| 70 |
+
maxAge: 3600
|
| 71 |
+
|
| 72 |
+
eureka:
|
| 73 |
+
instance:
|
| 74 |
+
prefer-ip-address: true
|
| 75 |
+
lease-renewal-interval-in-seconds: 30
|
| 76 |
+
client:
|
| 77 |
+
fetch-registry: true
|
| 78 |
+
register-with-eureka: true
|
| 79 |
+
service-url:
|
| 80 |
+
defaultZone: ${EUREKA_SERVER_URI:http://eureka-server:8085/eureka}
|
| 81 |
+
registry-fetch-interval-seconds: 30
|
| 82 |
+
|
| 83 |
+
resilience4j:
|
| 84 |
+
circuitbreaker:
|
| 85 |
+
instances:
|
| 86 |
+
userServiceCircuitBreaker:
|
| 87 |
+
slidingWindowSize: 10
|
| 88 |
+
failureRateThreshold: 50
|
| 89 |
+
waitDurationInOpenState: 30s
|
| 90 |
+
permittedNumberOfCallsInHalfOpenState: 2
|
| 91 |
+
taskServiceCircuitBreaker:
|
| 92 |
+
slidingWindowSize: 10
|
| 93 |
+
failureRateThreshold: 50
|
| 94 |
+
waitDurationInOpenState: 30s
|
| 95 |
+
permittedNumberOfCallsInHalfOpenState: 2
|
| 96 |
+
submissionServiceCircuitBreaker:
|
| 97 |
+
slidingWindowSize: 10
|
| 98 |
+
failureRateThreshold: 50
|
| 99 |
+
waitDurationInOpenState: 30s
|
| 100 |
+
permittedNumberOfCallsInHalfOpenState: 2
|
| 101 |
+
|
| 102 |
+
management:
|
| 103 |
+
endpoints:
|
| 104 |
+
web:
|
| 105 |
+
exposure:
|
| 106 |
+
include: "*"
|
| 107 |
+
endpoint:
|
| 108 |
+
health:
|
| 109 |
+
show-details: always
|
APIGateWay/src/main/resources/application.yml
ADDED
|
@@ -0,0 +1,113 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
server:
|
| 2 |
+
port: ${SERVER_PORT:8090}
|
| 3 |
+
tomcat:
|
| 4 |
+
max-threads: 200
|
| 5 |
+
connection-timeout: 5s
|
| 6 |
+
|
| 7 |
+
spring:
|
| 8 |
+
application:
|
| 9 |
+
name: ${SPRING_APP_NAME:API-GATEWAY-SERVER}
|
| 10 |
+
zipkin:
|
| 11 |
+
base-url: ${ZIPKIN_BASE_URL:http://localhost:9411}
|
| 12 |
+
sleuth:
|
| 13 |
+
sampler:
|
| 14 |
+
probability: ${ZIPKIN_SAMPLER_PROBABILITY:1.0}
|
| 15 |
+
cloud:
|
| 16 |
+
gateway:
|
| 17 |
+
routes:
|
| 18 |
+
- id: user-service
|
| 19 |
+
uri: lb://USER-SERVICE
|
| 20 |
+
predicates:
|
| 21 |
+
- Path=/auth/**,/users/**,/api/users/**,/
|
| 22 |
+
filters:
|
| 23 |
+
- name: CircuitBreaker
|
| 24 |
+
args:
|
| 25 |
+
name: userServiceCircuitBreaker
|
| 26 |
+
fallbackUri: forward:/fallback/users
|
| 27 |
+
- name: Retry
|
| 28 |
+
args:
|
| 29 |
+
retries: 3
|
| 30 |
+
statuses: BAD_GATEWAY
|
| 31 |
+
|
| 32 |
+
- id: task-service
|
| 33 |
+
uri: lb://TASK-SERVICE
|
| 34 |
+
predicates:
|
| 35 |
+
- Path=/api/tasks/**,/tasks/**
|
| 36 |
+
filters:
|
| 37 |
+
- name: CircuitBreaker
|
| 38 |
+
args:
|
| 39 |
+
name: taskServiceCircuitBreaker
|
| 40 |
+
fallbackUri: forward:/fallback/tasks
|
| 41 |
+
|
| 42 |
+
- id: task-submission-service
|
| 43 |
+
uri: lb://TASK-SUBMISSION
|
| 44 |
+
predicates:
|
| 45 |
+
- Path=/api/submissions/**,/submissions/**
|
| 46 |
+
filters:
|
| 47 |
+
- name: CircuitBreaker
|
| 48 |
+
args:
|
| 49 |
+
name: submissionServiceCircuitBreaker
|
| 50 |
+
fallbackUri: forward:/fallback/submissions
|
| 51 |
+
|
| 52 |
+
default-filters:
|
| 53 |
+
- DedupeResponseHeader=Access-Control-Allow-Credentials Access-Control-Allow-Origin
|
| 54 |
+
globalcors:
|
| 55 |
+
cors-configurations:
|
| 56 |
+
'[/**]':
|
| 57 |
+
allowedOrigins:
|
| 58 |
+
- ${GATEWAY_ALLOWED_ORIGIN_1:http://localhost:3000}
|
| 59 |
+
- ${GATEWAY_ALLOWED_ORIGIN_2:http://localhost:8080}
|
| 60 |
+
allowedOriginPatterns:
|
| 61 |
+
- ${GATEWAY_ALLOWED_ORIGIN_PATTERN:*}
|
| 62 |
+
allowedMethods:
|
| 63 |
+
- GET
|
| 64 |
+
- POST
|
| 65 |
+
- PUT
|
| 66 |
+
- PATCH
|
| 67 |
+
- DELETE
|
| 68 |
+
- OPTIONS
|
| 69 |
+
allowedHeaders:
|
| 70 |
+
- Authorization
|
| 71 |
+
- Content-Type
|
| 72 |
+
- X-Requested-With
|
| 73 |
+
allowCredentials: true
|
| 74 |
+
maxAge: 3600
|
| 75 |
+
|
| 76 |
+
eureka:
|
| 77 |
+
instance:
|
| 78 |
+
prefer-ip-address: true
|
| 79 |
+
lease-renewal-interval-in-seconds: 30
|
| 80 |
+
client:
|
| 81 |
+
fetch-registry: true
|
| 82 |
+
register-with-eureka: true
|
| 83 |
+
service-url:
|
| 84 |
+
defaultZone: ${EUREKA_SERVER_URI:http://localhost:8085/eureka}
|
| 85 |
+
registry-fetch-interval-seconds: 30
|
| 86 |
+
|
| 87 |
+
resilience4j:
|
| 88 |
+
circuitbreaker:
|
| 89 |
+
instances:
|
| 90 |
+
userServiceCircuitBreaker:
|
| 91 |
+
slidingWindowSize: 10
|
| 92 |
+
failureRateThreshold: 50
|
| 93 |
+
waitDurationInOpenState: 30s
|
| 94 |
+
permittedNumberOfCallsInHalfOpenState: 2
|
| 95 |
+
taskServiceCircuitBreaker:
|
| 96 |
+
slidingWindowSize: 10
|
| 97 |
+
failureRateThreshold: 50
|
| 98 |
+
waitDurationInOpenState: 30s
|
| 99 |
+
permittedNumberOfCallsInHalfOpenState: 2
|
| 100 |
+
submissionServiceCircuitBreaker:
|
| 101 |
+
slidingWindowSize: 10
|
| 102 |
+
failureRateThreshold: 50
|
| 103 |
+
waitDurationInOpenState: 30s
|
| 104 |
+
permittedNumberOfCallsInHalfOpenState: 2
|
| 105 |
+
|
| 106 |
+
management:
|
| 107 |
+
endpoints:
|
| 108 |
+
web:
|
| 109 |
+
exposure:
|
| 110 |
+
include: "*"
|
| 111 |
+
endpoint:
|
| 112 |
+
health:
|
| 113 |
+
show-details: always
|
APIGateWay/src/test/java/in/garvit/tasks/ApiGateWayApplicationTests.java
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
package in.garvit.tasks;
|
| 2 |
+
|
| 3 |
+
import org.junit.jupiter.api.Test;
|
| 4 |
+
import org.springframework.boot.test.context.SpringBootTest;
|
| 5 |
+
|
| 6 |
+
@SpringBootTest
|
| 7 |
+
class ApiGateWayApplicationTests {
|
| 8 |
+
|
| 9 |
+
@Test
|
| 10 |
+
void contextLoads() {
|
| 11 |
+
}
|
| 12 |
+
|
| 13 |
+
}
|
Dockerfile
ADDED
|
@@ -0,0 +1,49 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
FROM ubuntu:22.04
|
| 2 |
+
|
| 3 |
+
ENV DEBIAN_FRONTEND=noninteractive
|
| 4 |
+
|
| 5 |
+
RUN apt-get update \
|
| 6 |
+
&& apt-get install -y --no-install-recommends \
|
| 7 |
+
curl \
|
| 8 |
+
wget \
|
| 9 |
+
gnupg \
|
| 10 |
+
ca-certificates \
|
| 11 |
+
openjdk-17-jdk-headless \
|
| 12 |
+
netcat \
|
| 13 |
+
build-essential \
|
| 14 |
+
python3 \
|
| 15 |
+
unzip \
|
| 16 |
+
libcurl4 \
|
| 17 |
+
libgssapi-krb5-2 \
|
| 18 |
+
libssl3 \
|
| 19 |
+
liblzma5 \
|
| 20 |
+
tzdata \
|
| 21 |
+
&& rm -rf /var/lib/apt/lists/*
|
| 22 |
+
|
| 23 |
+
RUN curl -fsSL https://deb.nodesource.com/setup_18.x | bash - \
|
| 24 |
+
&& apt-get update \
|
| 25 |
+
&& apt-get install -y --no-install-recommends nodejs \
|
| 26 |
+
&& rm -rf /var/lib/apt/lists/*
|
| 27 |
+
|
| 28 |
+
RUN curl -fsSL https://fastdl.mongodb.org/linux/mongodb-linux-x86_64-ubuntu2204-6.0.15.tgz -o /tmp/mongodb.tgz \
|
| 29 |
+
&& tar -xzf /tmp/mongodb.tgz -C /opt \
|
| 30 |
+
&& mv /opt/mongodb-linux-x86_64-ubuntu2204-6.0.15 /opt/mongodb \
|
| 31 |
+
&& rm /tmp/mongodb.tgz \
|
| 32 |
+
&& mkdir -p /data/db
|
| 33 |
+
|
| 34 |
+
ENV PATH="/opt/mongodb/bin:${PATH}"
|
| 35 |
+
|
| 36 |
+
WORKDIR /app
|
| 37 |
+
COPY . .
|
| 38 |
+
|
| 39 |
+
RUN find . -name gradlew -exec chmod +x {} \; \
|
| 40 |
+
&& chmod +x build-all.sh hf-entrypoint.sh
|
| 41 |
+
|
| 42 |
+
ENV REACT_APP_API_BASE_URL=/api
|
| 43 |
+
RUN ./build-all.sh
|
| 44 |
+
RUN cd task-management-ui && npm prune --omit=dev
|
| 45 |
+
|
| 46 |
+
EXPOSE 7860
|
| 47 |
+
ENV PORT=7860
|
| 48 |
+
|
| 49 |
+
CMD ["/app/hf-entrypoint.sh"]
|
EurekaServerConfiguration/.gitignore
ADDED
|
@@ -0,0 +1,50 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 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 |
+
|
| 39 |
+
### Logs ###
|
| 40 |
+
logs/
|
| 41 |
+
*.log
|
| 42 |
+
|
| 43 |
+
### OS ###
|
| 44 |
+
.DS_Store
|
| 45 |
+
Thumbs.db
|
| 46 |
+
|
| 47 |
+
### Temporary files ###
|
| 48 |
+
*.tmp
|
| 49 |
+
*.temp
|
| 50 |
+
*~
|
EurekaServerConfiguration/Dockerfile
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
FROM eclipse-temurin:17-jre-alpine
|
| 2 |
+
|
| 3 |
+
LABEL authors="garvitpathak27"
|
| 4 |
+
LABEL version="1.0.0"
|
| 5 |
+
LABEL description="Eureka Server for Task Management Microservices"
|
| 6 |
+
|
| 7 |
+
WORKDIR /app
|
| 8 |
+
|
| 9 |
+
RUN apk add --no-cache curl \
|
| 10 |
+
&& addgroup -S spring \
|
| 11 |
+
&& adduser -S spring -G spring
|
| 12 |
+
|
| 13 |
+
COPY build/libs/eureka-server.jar app.jar
|
| 14 |
+
|
| 15 |
+
RUN chown spring:spring /app/app.jar
|
| 16 |
+
|
| 17 |
+
USER spring:spring
|
| 18 |
+
|
| 19 |
+
HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \
|
| 20 |
+
CMD curl -sf http://localhost:8085/actuator/health || exit 1
|
| 21 |
+
|
| 22 |
+
EXPOSE 8085
|
| 23 |
+
|
| 24 |
+
ENV JAVA_OPTS="-Xmx512m -Xms256m -XX:+UseG1GC -XX:+UseContainerSupport -Djava.security.egd=file:/dev/./urandom"
|
| 25 |
+
|
| 26 |
+
ENTRYPOINT ["sh", "-c", "java $JAVA_OPTS -jar /app/app.jar --spring.profiles.active=docker"]
|
EurekaServerConfiguration/README.md
ADDED
|
@@ -0,0 +1,188 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Eureka Server Configuration
|
| 2 |
+
|
| 3 |
+
A Spring Boot microservice that acts as a service registry for the Task Management System. This Eureka Server provides service discovery capabilities for all microservices in the system.
|
| 4 |
+
|
| 5 |
+
## Features
|
| 6 |
+
|
| 7 |
+
- **Service Registration and Discovery**: Allows microservices to register themselves and discover other services
|
| 8 |
+
- **Health Monitoring**: Monitors the health of registered services
|
| 9 |
+
- **Load Balancing Support**: Provides client-side load balancing information
|
| 10 |
+
- **Circuit Breaker Integration**: Works with Hystrix for fault tolerance
|
| 11 |
+
- **Distributed Tracing**: Integrated with Zipkin for request tracing
|
| 12 |
+
- **Actuator Endpoints**: Comprehensive monitoring and management endpoints
|
| 13 |
+
|
| 14 |
+
## Prerequisites
|
| 15 |
+
|
| 16 |
+
- Java 17 or higher
|
| 17 |
+
- Gradle 8.5 or higher
|
| 18 |
+
- Docker (for containerized deployment)
|
| 19 |
+
|
| 20 |
+
## Configuration
|
| 21 |
+
|
| 22 |
+
### Local Development
|
| 23 |
+
The application uses `application.properties` for local development configuration:
|
| 24 |
+
- Server runs on port 8085
|
| 25 |
+
- Eureka dashboard available at http://localhost:8085
|
| 26 |
+
|
| 27 |
+
### Docker Deployment
|
| 28 |
+
The application uses `application-docker.properties` for Docker deployment:
|
| 29 |
+
- Configured for container networking
|
| 30 |
+
- Zipkin integration with container service names
|
| 31 |
+
|
| 32 |
+
## Building the Application
|
| 33 |
+
|
| 34 |
+
```bash
|
| 35 |
+
# Build with Gradle
|
| 36 |
+
./gradlew build
|
| 37 |
+
|
| 38 |
+
# Build Docker image
|
| 39 |
+
docker build -t eureka-server:1.0.0 .
|
| 40 |
+
```
|
| 41 |
+
|
| 42 |
+
## Running the Application
|
| 43 |
+
|
| 44 |
+
### Local Development
|
| 45 |
+
```bash
|
| 46 |
+
# Run with Gradle
|
| 47 |
+
./gradlew bootRun
|
| 48 |
+
|
| 49 |
+
# Run JAR file
|
| 50 |
+
java -jar build/libs/eureka-server.jar
|
| 51 |
+
```
|
| 52 |
+
|
| 53 |
+
### Docker
|
| 54 |
+
```bash
|
| 55 |
+
# Run Docker container
|
| 56 |
+
docker run -p 8085:8085 eureka-server:1.0.0
|
| 57 |
+
```
|
| 58 |
+
|
| 59 |
+
## Endpoints
|
| 60 |
+
|
| 61 |
+
### Eureka Dashboard
|
| 62 |
+
- **URL**: http://localhost:8085
|
| 63 |
+
- **Description**: Web UI for viewing registered services
|
| 64 |
+
|
| 65 |
+
### Actuator Endpoints
|
| 66 |
+
- **Health**: http://localhost:8085/actuator/health
|
| 67 |
+
- **Info**: http://localhost:8085/actuator/info
|
| 68 |
+
- **Metrics**: http://localhost:8085/actuator/metrics
|
| 69 |
+
- **All Endpoints**: http://localhost:8085/actuator
|
| 70 |
+
|
| 71 |
+
### API Endpoints
|
| 72 |
+
- **Info**: http://localhost:8085/info
|
| 73 |
+
- **Home**: http://localhost:8085/
|
| 74 |
+
|
| 75 |
+
## Health Checks
|
| 76 |
+
|
| 77 |
+
The application includes comprehensive health checks:
|
| 78 |
+
- Custom Eureka health indicator
|
| 79 |
+
- Actuator health endpoints
|
| 80 |
+
- Docker health checks
|
| 81 |
+
- Liveness and readiness probes
|
| 82 |
+
|
| 83 |
+
## Monitoring
|
| 84 |
+
|
| 85 |
+
### Metrics
|
| 86 |
+
- Micrometer metrics integration
|
| 87 |
+
- Prometheus metrics endpoint
|
| 88 |
+
- JVM and system metrics
|
| 89 |
+
|
| 90 |
+
### Logging
|
| 91 |
+
- Structured JSON logging (in Docker)
|
| 92 |
+
- Log rotation and retention
|
| 93 |
+
- Configurable log levels
|
| 94 |
+
|
| 95 |
+
### Tracing
|
| 96 |
+
- Zipkin distributed tracing
|
| 97 |
+
- Request correlation IDs
|
| 98 |
+
- Performance monitoring
|
| 99 |
+
|
| 100 |
+
## Configuration Properties
|
| 101 |
+
|
| 102 |
+
| Property | Description | Default |
|
| 103 |
+
|----------|-------------|---------|
|
| 104 |
+
| `server.port` | Server port | 8085 |
|
| 105 |
+
| `eureka.server.enable-self-preservation` | Enable self-preservation mode | true |
|
| 106 |
+
| `eureka.server.renewal-percent-threshold` | Renewal threshold percentage | 0.85 |
|
| 107 |
+
| `eureka.server.eviction-interval-timer-in-ms` | Eviction interval | 30000 |
|
| 108 |
+
|
| 109 |
+
## Security
|
| 110 |
+
|
| 111 |
+
- Runs as non-root user in Docker
|
| 112 |
+
- Health checks for container orchestration
|
| 113 |
+
- Actuator endpoints secured appropriately
|
| 114 |
+
- Network security through container networking
|
| 115 |
+
|
| 116 |
+
## Performance Tuning
|
| 117 |
+
|
| 118 |
+
- Optimized JVM settings for containers
|
| 119 |
+
- Response cache configuration
|
| 120 |
+
- Renewal and eviction timers optimized
|
| 121 |
+
- G1 garbage collector for better performance
|
| 122 |
+
|
| 123 |
+
## Troubleshooting
|
| 124 |
+
|
| 125 |
+
### Common Issues
|
| 126 |
+
|
| 127 |
+
1. **Service not registering**
|
| 128 |
+
- Check network connectivity
|
| 129 |
+
- Verify service configuration
|
| 130 |
+
- Check Eureka client configuration
|
| 131 |
+
|
| 132 |
+
2. **High CPU usage**
|
| 133 |
+
- Check eviction interval settings
|
| 134 |
+
- Monitor garbage collection
|
| 135 |
+
- Review renewal threshold
|
| 136 |
+
|
| 137 |
+
3. **Memory issues**
|
| 138 |
+
- Adjust JVM heap settings
|
| 139 |
+
- Monitor registered services count
|
| 140 |
+
- Check for memory leaks
|
| 141 |
+
|
| 142 |
+
### Logs Location
|
| 143 |
+
- Local: `logs/eureka-server.log`
|
| 144 |
+
- Docker: Container stdout/stderr
|
| 145 |
+
|
| 146 |
+
## Development
|
| 147 |
+
|
| 148 |
+
### Project Structure
|
| 149 |
+
```
|
| 150 |
+
src/
|
| 151 |
+
├── main/
|
| 152 |
+
│ ├── java/
|
| 153 |
+
│ │ └── in/garvit/tasks/
|
| 154 |
+
│ │ ├── EurekaServerConfigurationApplication.java
|
| 155 |
+
│ │ ├── config/
|
| 156 |
+
│ │ │ └── EurekaServerConfig.java
|
| 157 |
+
│ │ └── controller/
|
| 158 |
+
│ │ ├── EurekaHealthIndicator.java
|
| 159 |
+
│ │ └── EurekaInfoController.java
|
| 160 |
+
│ └── resources/
|
| 161 |
+
│ ├── application.properties
|
| 162 |
+
│ ├── application-docker.properties
|
| 163 |
+
│ ├── logback-spring.xml
|
| 164 |
+
│ └── META-INF/
|
| 165 |
+
│ └── additional-spring-configuration-metadata.json
|
| 166 |
+
└── test/
|
| 167 |
+
└── java/
|
| 168 |
+
```
|
| 169 |
+
|
| 170 |
+
### Building and Testing
|
| 171 |
+
```bash
|
| 172 |
+
# Run tests
|
| 173 |
+
./gradlew test
|
| 174 |
+
|
| 175 |
+
# Build application
|
| 176 |
+
./gradlew build
|
| 177 |
+
|
| 178 |
+
# Check dependencies
|
| 179 |
+
./gradlew dependencies
|
| 180 |
+
```
|
| 181 |
+
|
| 182 |
+
## License
|
| 183 |
+
|
| 184 |
+
This project is part of the Task Management System microservices architecture.
|
| 185 |
+
|
| 186 |
+
## Author
|
| 187 |
+
|
| 188 |
+
**garvitpathak27** - Initial work and maintenance
|
EurekaServerConfiguration/build.gradle
ADDED
|
@@ -0,0 +1,75 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
plugins {
|
| 2 |
+
id 'java'
|
| 3 |
+
id 'org.springframework.boot' version '3.2.2'
|
| 4 |
+
id 'io.spring.dependency-management' version '1.1.4'
|
| 5 |
+
}
|
| 6 |
+
|
| 7 |
+
group = 'in.garvit.tasks'
|
| 8 |
+
version = '1.0.0'
|
| 9 |
+
description = 'Eureka Server Configuration for Task Management Microservices'
|
| 10 |
+
|
| 11 |
+
java {
|
| 12 |
+
sourceCompatibility = '17'
|
| 13 |
+
targetCompatibility = '17'
|
| 14 |
+
}
|
| 15 |
+
|
| 16 |
+
configurations {
|
| 17 |
+
compileOnly {
|
| 18 |
+
extendsFrom annotationProcessor
|
| 19 |
+
}
|
| 20 |
+
}
|
| 21 |
+
|
| 22 |
+
repositories {
|
| 23 |
+
mavenCentral()
|
| 24 |
+
}
|
| 25 |
+
|
| 26 |
+
ext {
|
| 27 |
+
set('springCloudVersion', "2023.0.0")
|
| 28 |
+
}
|
| 29 |
+
|
| 30 |
+
dependencies {
|
| 31 |
+
// Core Spring Boot and Eureka dependencies
|
| 32 |
+
implementation 'org.springframework.boot:spring-boot-starter-web'
|
| 33 |
+
implementation 'org.springframework.boot:spring-boot-starter-actuator'
|
| 34 |
+
implementation 'org.springframework.cloud:spring-cloud-starter-netflix-eureka-server'
|
| 35 |
+
|
| 36 |
+
// Monitoring and Observability
|
| 37 |
+
implementation 'io.micrometer:micrometer-tracing-bridge-brave'
|
| 38 |
+
implementation 'io.zipkin.reporter2:zipkin-reporter-brave'
|
| 39 |
+
implementation 'io.micrometer:micrometer-registry-prometheus'
|
| 40 |
+
|
| 41 |
+
// Logging
|
| 42 |
+
implementation 'net.logstash.logback:logstash-logback-encoder:7.4'
|
| 43 |
+
|
| 44 |
+
// Development tools
|
| 45 |
+
developmentOnly 'org.springframework.boot:spring-boot-devtools'
|
| 46 |
+
annotationProcessor 'org.springframework.boot:spring-boot-configuration-processor'
|
| 47 |
+
|
| 48 |
+
// Testing
|
| 49 |
+
testImplementation 'org.springframework.boot:spring-boot-starter-test'
|
| 50 |
+
}
|
| 51 |
+
|
| 52 |
+
dependencyManagement {
|
| 53 |
+
imports {
|
| 54 |
+
mavenBom "org.springframework.cloud:spring-cloud-dependencies:${springCloudVersion}"
|
| 55 |
+
}
|
| 56 |
+
}
|
| 57 |
+
|
| 58 |
+
tasks.named('test') {
|
| 59 |
+
useJUnitPlatform()
|
| 60 |
+
testLogging {
|
| 61 |
+
events "passed", "skipped", "failed"
|
| 62 |
+
}
|
| 63 |
+
}
|
| 64 |
+
|
| 65 |
+
// JAR configuration
|
| 66 |
+
jar {
|
| 67 |
+
enabled = false
|
| 68 |
+
archiveClassifier = ''
|
| 69 |
+
}
|
| 70 |
+
|
| 71 |
+
bootJar {
|
| 72 |
+
enabled = true
|
| 73 |
+
archiveClassifier = ''
|
| 74 |
+
archiveFileName = 'eureka-server.jar'
|
| 75 |
+
}
|
EurekaServerConfiguration/gradle/wrapper/gradle-wrapper.jar
ADDED
|
Binary file (43.5 kB). View file
|
|
|
EurekaServerConfiguration/gradle/wrapper/gradle-wrapper.properties
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
distributionBase=GRADLE_USER_HOME
|
| 2 |
+
distributionPath=wrapper/dists
|
| 3 |
+
distributionUrl=https\://services.gradle.org/distributions/gradle-8.5-bin.zip
|
| 4 |
+
networkTimeout=10000
|
| 5 |
+
validateDistributionUrl=true
|
| 6 |
+
zipStoreBase=GRADLE_USER_HOME
|
| 7 |
+
zipStorePath=wrapper/dists
|
EurekaServerConfiguration/gradlew
ADDED
|
@@ -0,0 +1,249 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#!/bin/sh
|
| 2 |
+
|
| 3 |
+
#
|
| 4 |
+
# Copyright © 2015-2021 the original 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 POSIX generated by Gradle.
|
| 22 |
+
#
|
| 23 |
+
# Important for running:
|
| 24 |
+
#
|
| 25 |
+
# (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is
|
| 26 |
+
# noncompliant, but you have some other compliant shell such as ksh or
|
| 27 |
+
# bash, then to run this script, type that shell name before the whole
|
| 28 |
+
# command line, like:
|
| 29 |
+
#
|
| 30 |
+
# ksh Gradle
|
| 31 |
+
#
|
| 32 |
+
# Busybox and similar reduced shells will NOT work, because this script
|
| 33 |
+
# requires all of these POSIX shell features:
|
| 34 |
+
# * functions;
|
| 35 |
+
# * expansions «$var», «${var}», «${var:-default}», «${var+SET}»,
|
| 36 |
+
# «${var#prefix}», «${var%suffix}», and «$( cmd )»;
|
| 37 |
+
# * compound commands having a testable exit status, especially «case»;
|
| 38 |
+
# * various built-in commands including «command», «set», and «ulimit».
|
| 39 |
+
#
|
| 40 |
+
# Important for patching:
|
| 41 |
+
#
|
| 42 |
+
# (2) This script targets any POSIX shell, so it avoids extensions provided
|
| 43 |
+
# by Bash, Ksh, etc; in particular arrays are avoided.
|
| 44 |
+
#
|
| 45 |
+
# The "traditional" practice of packing multiple parameters into a
|
| 46 |
+
# space-separated string is a well documented source of bugs and security
|
| 47 |
+
# problems, so this is (mostly) avoided, by progressively accumulating
|
| 48 |
+
# options in "$@", and eventually passing that to Java.
|
| 49 |
+
#
|
| 50 |
+
# Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS,
|
| 51 |
+
# and GRADLE_OPTS) rely on word-splitting, this is performed explicitly;
|
| 52 |
+
# see the in-line comments for details.
|
| 53 |
+
#
|
| 54 |
+
# There are tweaks for specific operating systems such as AIX, CygWin,
|
| 55 |
+
# Darwin, MinGW, and NonStop.
|
| 56 |
+
#
|
| 57 |
+
# (3) This script is generated from the Groovy template
|
| 58 |
+
# https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
|
| 59 |
+
# within the Gradle project.
|
| 60 |
+
#
|
| 61 |
+
# You can find Gradle at https://github.com/gradle/gradle/.
|
| 62 |
+
#
|
| 63 |
+
##############################################################################
|
| 64 |
+
|
| 65 |
+
# Attempt to set APP_HOME
|
| 66 |
+
|
| 67 |
+
# Resolve links: $0 may be a link
|
| 68 |
+
app_path=$0
|
| 69 |
+
|
| 70 |
+
# Need this for daisy-chained symlinks.
|
| 71 |
+
while
|
| 72 |
+
APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path
|
| 73 |
+
[ -h "$app_path" ]
|
| 74 |
+
do
|
| 75 |
+
ls=$( ls -ld "$app_path" )
|
| 76 |
+
link=${ls#*' -> '}
|
| 77 |
+
case $link in #(
|
| 78 |
+
/*) app_path=$link ;; #(
|
| 79 |
+
*) app_path=$APP_HOME$link ;;
|
| 80 |
+
esac
|
| 81 |
+
done
|
| 82 |
+
|
| 83 |
+
# This is normally unused
|
| 84 |
+
# shellcheck disable=SC2034
|
| 85 |
+
APP_BASE_NAME=${0##*/}
|
| 86 |
+
# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036)
|
| 87 |
+
APP_HOME=$( cd "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit
|
| 88 |
+
|
| 89 |
+
# Use the maximum available, or set MAX_FD != -1 to use that value.
|
| 90 |
+
MAX_FD=maximum
|
| 91 |
+
|
| 92 |
+
warn () {
|
| 93 |
+
echo "$*"
|
| 94 |
+
} >&2
|
| 95 |
+
|
| 96 |
+
die () {
|
| 97 |
+
echo
|
| 98 |
+
echo "$*"
|
| 99 |
+
echo
|
| 100 |
+
exit 1
|
| 101 |
+
} >&2
|
| 102 |
+
|
| 103 |
+
# OS specific support (must be 'true' or 'false').
|
| 104 |
+
cygwin=false
|
| 105 |
+
msys=false
|
| 106 |
+
darwin=false
|
| 107 |
+
nonstop=false
|
| 108 |
+
case "$( uname )" in #(
|
| 109 |
+
CYGWIN* ) cygwin=true ;; #(
|
| 110 |
+
Darwin* ) darwin=true ;; #(
|
| 111 |
+
MSYS* | MINGW* ) msys=true ;; #(
|
| 112 |
+
NONSTOP* ) nonstop=true ;;
|
| 113 |
+
esac
|
| 114 |
+
|
| 115 |
+
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
|
| 116 |
+
|
| 117 |
+
|
| 118 |
+
# Determine the Java command to use to start the JVM.
|
| 119 |
+
if [ -n "$JAVA_HOME" ] ; then
|
| 120 |
+
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
|
| 121 |
+
# IBM's JDK on AIX uses strange locations for the executables
|
| 122 |
+
JAVACMD=$JAVA_HOME/jre/sh/java
|
| 123 |
+
else
|
| 124 |
+
JAVACMD=$JAVA_HOME/bin/java
|
| 125 |
+
fi
|
| 126 |
+
if [ ! -x "$JAVACMD" ] ; then
|
| 127 |
+
die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
|
| 128 |
+
|
| 129 |
+
Please set the JAVA_HOME variable in your environment to match the
|
| 130 |
+
location of your Java installation."
|
| 131 |
+
fi
|
| 132 |
+
else
|
| 133 |
+
JAVACMD=java
|
| 134 |
+
if ! command -v java >/dev/null 2>&1
|
| 135 |
+
then
|
| 136 |
+
die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
| 137 |
+
|
| 138 |
+
Please set the JAVA_HOME variable in your environment to match the
|
| 139 |
+
location of your Java installation."
|
| 140 |
+
fi
|
| 141 |
+
fi
|
| 142 |
+
|
| 143 |
+
# Increase the maximum file descriptors if we can.
|
| 144 |
+
if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then
|
| 145 |
+
case $MAX_FD in #(
|
| 146 |
+
max*)
|
| 147 |
+
# In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked.
|
| 148 |
+
# shellcheck disable=SC2039,SC3045
|
| 149 |
+
MAX_FD=$( ulimit -H -n ) ||
|
| 150 |
+
warn "Could not query maximum file descriptor limit"
|
| 151 |
+
esac
|
| 152 |
+
case $MAX_FD in #(
|
| 153 |
+
'' | soft) :;; #(
|
| 154 |
+
*)
|
| 155 |
+
# In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked.
|
| 156 |
+
# shellcheck disable=SC2039,SC3045
|
| 157 |
+
ulimit -n "$MAX_FD" ||
|
| 158 |
+
warn "Could not set maximum file descriptor limit to $MAX_FD"
|
| 159 |
+
esac
|
| 160 |
+
fi
|
| 161 |
+
|
| 162 |
+
# Collect all arguments for the java command, stacking in reverse order:
|
| 163 |
+
# * args from the command line
|
| 164 |
+
# * the main class name
|
| 165 |
+
# * -classpath
|
| 166 |
+
# * -D...appname settings
|
| 167 |
+
# * --module-path (only if needed)
|
| 168 |
+
# * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables.
|
| 169 |
+
|
| 170 |
+
# For Cygwin or MSYS, switch paths to Windows format before running java
|
| 171 |
+
if "$cygwin" || "$msys" ; then
|
| 172 |
+
APP_HOME=$( cygpath --path --mixed "$APP_HOME" )
|
| 173 |
+
CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" )
|
| 174 |
+
|
| 175 |
+
JAVACMD=$( cygpath --unix "$JAVACMD" )
|
| 176 |
+
|
| 177 |
+
# Now convert the arguments - kludge to limit ourselves to /bin/sh
|
| 178 |
+
for arg do
|
| 179 |
+
if
|
| 180 |
+
case $arg in #(
|
| 181 |
+
-*) false ;; # don't mess with options #(
|
| 182 |
+
/?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath
|
| 183 |
+
[ -e "$t" ] ;; #(
|
| 184 |
+
*) false ;;
|
| 185 |
+
esac
|
| 186 |
+
then
|
| 187 |
+
arg=$( cygpath --path --ignore --mixed "$arg" )
|
| 188 |
+
fi
|
| 189 |
+
# Roll the args list around exactly as many times as the number of
|
| 190 |
+
# args, so each arg winds up back in the position where it started, but
|
| 191 |
+
# possibly modified.
|
| 192 |
+
#
|
| 193 |
+
# NB: a `for` loop captures its iteration list before it begins, so
|
| 194 |
+
# changing the positional parameters here affects neither the number of
|
| 195 |
+
# iterations, nor the values presented in `arg`.
|
| 196 |
+
shift # remove old arg
|
| 197 |
+
set -- "$@" "$arg" # push replacement arg
|
| 198 |
+
done
|
| 199 |
+
fi
|
| 200 |
+
|
| 201 |
+
|
| 202 |
+
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
| 203 |
+
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
|
| 204 |
+
|
| 205 |
+
# Collect all arguments for the java command:
|
| 206 |
+
# * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments,
|
| 207 |
+
# and any embedded shellness will be escaped.
|
| 208 |
+
# * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be
|
| 209 |
+
# treated as '${Hostname}' itself on the command line.
|
| 210 |
+
|
| 211 |
+
set -- \
|
| 212 |
+
"-Dorg.gradle.appname=$APP_BASE_NAME" \
|
| 213 |
+
-classpath "$CLASSPATH" \
|
| 214 |
+
org.gradle.wrapper.GradleWrapperMain \
|
| 215 |
+
"$@"
|
| 216 |
+
|
| 217 |
+
# Stop when "xargs" is not available.
|
| 218 |
+
if ! command -v xargs >/dev/null 2>&1
|
| 219 |
+
then
|
| 220 |
+
die "xargs is not available"
|
| 221 |
+
fi
|
| 222 |
+
|
| 223 |
+
# Use "xargs" to parse quoted args.
|
| 224 |
+
#
|
| 225 |
+
# With -n1 it outputs one arg per line, with the quotes and backslashes removed.
|
| 226 |
+
#
|
| 227 |
+
# In Bash we could simply go:
|
| 228 |
+
#
|
| 229 |
+
# readarray ARGS < <( xargs -n1 <<<"$var" ) &&
|
| 230 |
+
# set -- "${ARGS[@]}" "$@"
|
| 231 |
+
#
|
| 232 |
+
# but POSIX shell has neither arrays nor command substitution, so instead we
|
| 233 |
+
# post-process each arg (as a line of input to sed) to backslash-escape any
|
| 234 |
+
# character that might be a shell metacharacter, then use eval to reverse
|
| 235 |
+
# that process (while maintaining the separation between arguments), and wrap
|
| 236 |
+
# the whole thing up as a single "set" statement.
|
| 237 |
+
#
|
| 238 |
+
# This will of course break if any of these variables contains a newline or
|
| 239 |
+
# an unmatched quote.
|
| 240 |
+
#
|
| 241 |
+
|
| 242 |
+
eval "set -- $(
|
| 243 |
+
printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" |
|
| 244 |
+
xargs -n1 |
|
| 245 |
+
sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' |
|
| 246 |
+
tr '\n' ' '
|
| 247 |
+
)" '"$@"'
|
| 248 |
+
|
| 249 |
+
exec "$JAVACMD" "$@"
|
EurekaServerConfiguration/gradlew.bat
ADDED
|
@@ -0,0 +1,92 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 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 |
+
@rem This is normally unused
|
| 30 |
+
set APP_BASE_NAME=%~n0
|
| 31 |
+
set APP_HOME=%DIRNAME%
|
| 32 |
+
|
| 33 |
+
@rem Resolve any "." and ".." in APP_HOME to make it shorter.
|
| 34 |
+
for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
|
| 35 |
+
|
| 36 |
+
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
| 37 |
+
set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
|
| 38 |
+
|
| 39 |
+
@rem Find java.exe
|
| 40 |
+
if defined JAVA_HOME goto findJavaFromJavaHome
|
| 41 |
+
|
| 42 |
+
set JAVA_EXE=java.exe
|
| 43 |
+
%JAVA_EXE% -version >NUL 2>&1
|
| 44 |
+
if %ERRORLEVEL% equ 0 goto execute
|
| 45 |
+
|
| 46 |
+
echo.
|
| 47 |
+
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
| 48 |
+
echo.
|
| 49 |
+
echo Please set the JAVA_HOME variable in your environment to match the
|
| 50 |
+
echo location of your Java installation.
|
| 51 |
+
|
| 52 |
+
goto fail
|
| 53 |
+
|
| 54 |
+
:findJavaFromJavaHome
|
| 55 |
+
set JAVA_HOME=%JAVA_HOME:"=%
|
| 56 |
+
set JAVA_EXE=%JAVA_HOME%/bin/java.exe
|
| 57 |
+
|
| 58 |
+
if exist "%JAVA_EXE%" goto execute
|
| 59 |
+
|
| 60 |
+
echo.
|
| 61 |
+
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
|
| 62 |
+
echo.
|
| 63 |
+
echo Please set the JAVA_HOME variable in your environment to match the
|
| 64 |
+
echo location of your Java installation.
|
| 65 |
+
|
| 66 |
+
goto fail
|
| 67 |
+
|
| 68 |
+
:execute
|
| 69 |
+
@rem Setup the command line
|
| 70 |
+
|
| 71 |
+
set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
|
| 72 |
+
|
| 73 |
+
|
| 74 |
+
@rem Execute Gradle
|
| 75 |
+
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %*
|
| 76 |
+
|
| 77 |
+
:end
|
| 78 |
+
@rem End local scope for the variables with windows NT shell
|
| 79 |
+
if %ERRORLEVEL% equ 0 goto mainEnd
|
| 80 |
+
|
| 81 |
+
:fail
|
| 82 |
+
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
|
| 83 |
+
rem the _cmd.exe /c_ return code!
|
| 84 |
+
set EXIT_CODE=%ERRORLEVEL%
|
| 85 |
+
if %EXIT_CODE% equ 0 set EXIT_CODE=1
|
| 86 |
+
if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE%
|
| 87 |
+
exit /b %EXIT_CODE%
|
| 88 |
+
|
| 89 |
+
:mainEnd
|
| 90 |
+
if "%OS%"=="Windows_NT" endlocal
|
| 91 |
+
|
| 92 |
+
:omega
|
EurekaServerConfiguration/settings.gradle
ADDED
|
@@ -0,0 +1 @@
|
|
|
|
|
|
|
| 1 |
+
rootProject.name = 'EurekaServerConfiguration'
|
EurekaServerConfiguration/src/main/java/in/garvit/tasks/EurekaServerConfigurationApplication.java
ADDED
|
@@ -0,0 +1,51 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
package in.garvit.tasks;
|
| 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 |
+
import jakarta.annotation.PostConstruct;
|
| 8 |
+
import java.util.TimeZone;
|
| 9 |
+
|
| 10 |
+
/**
|
| 11 |
+
* Eureka Server Configuration Application
|
| 12 |
+
*
|
| 13 |
+
* This microservice acts as the service registry for the Task Management System.
|
| 14 |
+
* It provides service discovery capabilities for all microservices in the system.
|
| 15 |
+
*
|
| 16 |
+
* Features:
|
| 17 |
+
* - Service Registration and Discovery
|
| 18 |
+
* - Health Monitoring
|
| 19 |
+
* - Load Balancing Support
|
| 20 |
+
* - Circuit Breaker Integration
|
| 21 |
+
* - Distributed Tracing with Zipkin
|
| 22 |
+
*
|
| 23 |
+
* @author garvitpathak27
|
| 24 |
+
* @version 1.0.0
|
| 25 |
+
*/
|
| 26 |
+
@SpringBootApplication
|
| 27 |
+
@EnableEurekaServer
|
| 28 |
+
public class EurekaServerConfigurationApplication {
|
| 29 |
+
|
| 30 |
+
@PostConstruct
|
| 31 |
+
public void init() {
|
| 32 |
+
// Set default timezone to UTC for consistency across all microservices
|
| 33 |
+
TimeZone.setDefault(TimeZone.getTimeZone("UTC"));
|
| 34 |
+
System.out.println("Eureka Server starting with UTC timezone...");
|
| 35 |
+
}
|
| 36 |
+
|
| 37 |
+
public static void main(String[] args) {
|
| 38 |
+
SpringApplication application = new SpringApplication(EurekaServerConfigurationApplication.class);
|
| 39 |
+
|
| 40 |
+
// Set system properties for better performance
|
| 41 |
+
System.setProperty("spring.output.ansi.enabled", "always");
|
| 42 |
+
System.setProperty("logging.pattern.console", "%clr(%d{yyyy-MM-dd HH:mm:ss.SSS}){faint} %clr(${LOG_LEVEL_PATTERN:-%5p}) %clr([%15.15t]){faint} %clr(%-40.40logger{39}){cyan} %clr(:){faint} %m%n${LOG_EXCEPTION_CONVERSION_WORD:-%wEx}");
|
| 43 |
+
|
| 44 |
+
// Add shutdown hook for graceful shutdown
|
| 45 |
+
Runtime.getRuntime().addShutdownHook(new Thread(() -> {
|
| 46 |
+
System.out.println("Eureka Server is shutting down gracefully...");
|
| 47 |
+
}));
|
| 48 |
+
|
| 49 |
+
application.run(args);
|
| 50 |
+
}
|
| 51 |
+
}
|
EurekaServerConfiguration/src/main/java/in/garvit/tasks/config/EurekaServerConfig.java
ADDED
|
@@ -0,0 +1,40 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
package in.garvit.tasks.config;
|
| 2 |
+
|
| 3 |
+
import org.springframework.boot.actuate.info.Info;
|
| 4 |
+
import org.springframework.boot.actuate.info.InfoContributor;
|
| 5 |
+
import org.springframework.context.annotation.Bean;
|
| 6 |
+
import org.springframework.context.annotation.Configuration;
|
| 7 |
+
|
| 8 |
+
import java.time.LocalDateTime;
|
| 9 |
+
import java.util.HashMap;
|
| 10 |
+
import java.util.Map;
|
| 11 |
+
|
| 12 |
+
/**
|
| 13 |
+
* Configuration class for Eureka Server
|
| 14 |
+
* Contains beans and configurations for the Eureka server
|
| 15 |
+
*
|
| 16 |
+
* @author garvitpathak27
|
| 17 |
+
*/
|
| 18 |
+
@Configuration("customEurekaServerConfig")
|
| 19 |
+
public class EurekaServerConfig {
|
| 20 |
+
|
| 21 |
+
/**
|
| 22 |
+
* Custom info contributor for actuator info endpoint
|
| 23 |
+
*/
|
| 24 |
+
@Bean
|
| 25 |
+
public InfoContributor customInfoContributor() {
|
| 26 |
+
return new InfoContributor() {
|
| 27 |
+
@Override
|
| 28 |
+
public void contribute(Info.Builder builder) {
|
| 29 |
+
Map<String, Object> details = new HashMap<>();
|
| 30 |
+
details.put("service", "Eureka Service Discovery Server");
|
| 31 |
+
details.put("version", "1.0.0");
|
| 32 |
+
details.put("author", "garvitpathak27");
|
| 33 |
+
details.put("startup-time", LocalDateTime.now());
|
| 34 |
+
details.put("description", "Service registry for Task Management Microservices");
|
| 35 |
+
|
| 36 |
+
builder.withDetail("application", details);
|
| 37 |
+
}
|
| 38 |
+
};
|
| 39 |
+
}
|
| 40 |
+
}
|
EurekaServerConfiguration/src/main/java/in/garvit/tasks/controller/EurekaHealthIndicator.java
ADDED
|
@@ -0,0 +1,55 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
package in.garvit.tasks.controller;
|
| 2 |
+
|
| 3 |
+
import org.springframework.boot.actuate.health.Health;
|
| 4 |
+
import org.springframework.boot.actuate.health.HealthIndicator;
|
| 5 |
+
import org.springframework.stereotype.Component;
|
| 6 |
+
|
| 7 |
+
import com.netflix.eureka.EurekaServerContextHolder;
|
| 8 |
+
import com.netflix.eureka.registry.PeerAwareInstanceRegistry;
|
| 9 |
+
|
| 10 |
+
/**
|
| 11 |
+
* Custom health indicator for Eureka Server
|
| 12 |
+
* Provides detailed health information about the Eureka server status
|
| 13 |
+
*
|
| 14 |
+
* @author garvitpathak27
|
| 15 |
+
*/
|
| 16 |
+
@Component("customEurekaHealthIndicator")
|
| 17 |
+
public class EurekaHealthIndicator implements HealthIndicator {
|
| 18 |
+
|
| 19 |
+
@Override
|
| 20 |
+
public Health health() {
|
| 21 |
+
Health.Builder builder = new Health.Builder();
|
| 22 |
+
|
| 23 |
+
try {
|
| 24 |
+
// Check if Eureka server context is available
|
| 25 |
+
if (EurekaServerContextHolder.getInstance() != null &&
|
| 26 |
+
EurekaServerContextHolder.getInstance().getServerContext() != null) {
|
| 27 |
+
|
| 28 |
+
PeerAwareInstanceRegistry registry = EurekaServerContextHolder.getInstance()
|
| 29 |
+
.getServerContext().getRegistry();
|
| 30 |
+
|
| 31 |
+
if (registry != null) {
|
| 32 |
+
// Get registry information
|
| 33 |
+
long numberOfRegisteredInstances = registry.getNumOfRenewsInLastMin();
|
| 34 |
+
int numOfKnownApps = registry.getApplications().size();
|
| 35 |
+
|
| 36 |
+
builder.up()
|
| 37 |
+
.withDetail("status", "Eureka Server is running")
|
| 38 |
+
.withDetail("renewsInLastMin", numberOfRegisteredInstances)
|
| 39 |
+
.withDetail("numOfKnownApps", numOfKnownApps)
|
| 40 |
+
.withDetail("selfPreservationMode", registry.isSelfPreservationModeEnabled());
|
| 41 |
+
} else {
|
| 42 |
+
builder.down().withDetail("reason", "Registry not available");
|
| 43 |
+
}
|
| 44 |
+
} else {
|
| 45 |
+
builder.down().withDetail("reason", "Eureka server context not available");
|
| 46 |
+
}
|
| 47 |
+
} catch (Exception e) {
|
| 48 |
+
builder.down()
|
| 49 |
+
.withDetail("reason", "Health check failed")
|
| 50 |
+
.withDetail("exception", e.getMessage());
|
| 51 |
+
}
|
| 52 |
+
|
| 53 |
+
return builder.build();
|
| 54 |
+
}
|
| 55 |
+
}
|
EurekaServerConfiguration/src/main/java/in/garvit/tasks/controller/EurekaInfoController.java
ADDED
|
@@ -0,0 +1,45 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
package in.garvit.tasks.controller;
|
| 2 |
+
|
| 3 |
+
import org.springframework.beans.factory.annotation.Value;
|
| 4 |
+
import org.springframework.web.bind.annotation.GetMapping;
|
| 5 |
+
import org.springframework.web.bind.annotation.RestController;
|
| 6 |
+
|
| 7 |
+
import java.time.LocalDateTime;
|
| 8 |
+
import java.util.HashMap;
|
| 9 |
+
import java.util.Map;
|
| 10 |
+
|
| 11 |
+
/**
|
| 12 |
+
* Simple REST controller for Eureka Server information
|
| 13 |
+
* Provides basic information about the Eureka server
|
| 14 |
+
*
|
| 15 |
+
* @author garvitpathak27
|
| 16 |
+
*/
|
| 17 |
+
@RestController
|
| 18 |
+
public class EurekaInfoController {
|
| 19 |
+
|
| 20 |
+
@Value("${spring.application.name:Eureka Server}")
|
| 21 |
+
private String applicationName;
|
| 22 |
+
|
| 23 |
+
@Value("${server.port:8085}")
|
| 24 |
+
private String serverPort;
|
| 25 |
+
|
| 26 |
+
@GetMapping("/info")
|
| 27 |
+
public Map<String, Object> getInfo() {
|
| 28 |
+
Map<String, Object> info = new HashMap<>();
|
| 29 |
+
info.put("applicationName", applicationName);
|
| 30 |
+
info.put("port", serverPort);
|
| 31 |
+
info.put("status", "UP");
|
| 32 |
+
info.put("timestamp", LocalDateTime.now());
|
| 33 |
+
info.put("version", "1.0.0");
|
| 34 |
+
info.put("description", "Eureka Server for Task Management Microservices");
|
| 35 |
+
return info;
|
| 36 |
+
}
|
| 37 |
+
|
| 38 |
+
@GetMapping("/eureka")
|
| 39 |
+
public Map<String, String> home() {
|
| 40 |
+
Map<String, String> response = new HashMap<>();
|
| 41 |
+
response.put("message", "Eureka Server is running");
|
| 42 |
+
response.put("dashboard", "http://localhost:" + serverPort + "/eureka/");
|
| 43 |
+
return response;
|
| 44 |
+
}
|
| 45 |
+
}
|
EurekaServerConfiguration/src/main/resources/META-INF/additional-spring-configuration-metadata.json
ADDED
|
@@ -0,0 +1,34 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"properties": [
|
| 3 |
+
{
|
| 4 |
+
"name": "eureka.server.enable-self-preservation",
|
| 5 |
+
"type": "java.lang.Boolean",
|
| 6 |
+
"description": "Enable self-preservation mode in Eureka server.",
|
| 7 |
+
"defaultValue": true
|
| 8 |
+
},
|
| 9 |
+
{
|
| 10 |
+
"name": "eureka.server.renewal-percent-threshold",
|
| 11 |
+
"type": "java.lang.Double",
|
| 12 |
+
"description": "The minimum percentage of renewals that is expected from the clients in the specified renewal interval.",
|
| 13 |
+
"defaultValue": 0.85
|
| 14 |
+
},
|
| 15 |
+
{
|
| 16 |
+
"name": "eureka.server.eviction-interval-timer-in-ms",
|
| 17 |
+
"type": "java.lang.Integer",
|
| 18 |
+
"description": "The time interval with which the task that expires instances should wake up and run.",
|
| 19 |
+
"defaultValue": 30000
|
| 20 |
+
},
|
| 21 |
+
{
|
| 22 |
+
"name": "eureka.server.response-cache-update-interval-ms",
|
| 23 |
+
"type": "java.lang.Integer",
|
| 24 |
+
"description": "The time interval with which the payload cache of the client should be updated.",
|
| 25 |
+
"defaultValue": 30000
|
| 26 |
+
},
|
| 27 |
+
{
|
| 28 |
+
"name": "eureka.server.response-cache-auto-expiration-in-seconds",
|
| 29 |
+
"type": "java.lang.Integer",
|
| 30 |
+
"description": "The time for which the registry payload should be kept in the cache if it is not invalidated by change events.",
|
| 31 |
+
"defaultValue": 180
|
| 32 |
+
}
|
| 33 |
+
]
|
| 34 |
+
}
|
EurekaServerConfiguration/src/main/resources/application-docker.properties
ADDED
|
@@ -0,0 +1,38 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Server Configuration for Docker Environment
|
| 2 |
+
server.port=8085
|
| 3 |
+
server.servlet.context-path=/
|
| 4 |
+
spring.application.name=EUREKA-SERVER
|
| 5 |
+
# Eureka Server Configuration for Docker
|
| 6 |
+
eureka.instance.hostname=eureka-server
|
| 7 |
+
eureka.instance.prefer-ip-address=true
|
| 8 |
+
eureka.client.register-with-eureka=false
|
| 9 |
+
eureka.client.fetch-registry=false
|
| 10 |
+
eureka.client.service-url.defaultZone=http://eureka-server:8085/eureka
|
| 11 |
+
eureka.server.enable-self-preservation=true
|
| 12 |
+
eureka.server.renewal-percent-threshold=0.85
|
| 13 |
+
eureka.server.eviction-interval-timer-in-ms=30000
|
| 14 |
+
|
| 15 |
+
# Zipkin Tracing Configuration for Docker
|
| 16 |
+
management.tracing.sampling.probability=1.0
|
| 17 |
+
management.zipkin.tracing.endpoint=http://zipkin:9411/api/v2/spans
|
| 18 |
+
|
| 19 |
+
# Actuator Configuration
|
| 20 |
+
management.endpoints.web.exposure.include=*
|
| 21 |
+
management.endpoint.health.show-details=always
|
| 22 |
+
management.endpoint.health.probes.enabled=true
|
| 23 |
+
management.health.livenessstate.enabled=true
|
| 24 |
+
management.health.readinessstate.enabled=true
|
| 25 |
+
|
| 26 |
+
# Logging Configuration
|
| 27 |
+
logging.level.com.netflix.eureka=INFO
|
| 28 |
+
logging.level.com.netflix.discovery=INFO
|
| 29 |
+
logging.level.root=INFO
|
| 30 |
+
logging.pattern.console=%clr(%d{yyyy-MM-dd HH:mm:ss.SSS}){faint} %clr(${LOG_LEVEL_PATTERN:-%5p}) %clr([%15.15t]){faint} %clr(%-40.40logger{39}){cyan} %clr(:){faint} %m%n${LOG_EXCEPTION_CONVERSION_WORD:-%wEx}
|
| 31 |
+
|
| 32 |
+
# Performance Tuning
|
| 33 |
+
eureka.server.response-cache-update-interval-ms=30000
|
| 34 |
+
eureka.server.response-cache-auto-expiration-in-seconds=180
|
| 35 |
+
|
| 36 |
+
# Docker specific network settings
|
| 37 |
+
eureka.instance.lease-renewal-interval-in-seconds=30
|
| 38 |
+
eureka.instance.lease-expiration-duration-in-seconds=90
|
EurekaServerConfiguration/src/main/resources/application.properties
ADDED
|
@@ -0,0 +1,40 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Server Configuration
|
| 2 |
+
server.port=8085
|
| 3 |
+
server.servlet.context-path=/
|
| 4 |
+
spring.application.name=EUREKA-SERVER
|
| 5 |
+
|
| 6 |
+
# Eureka Server Configuration
|
| 7 |
+
eureka.instance.hostname=localhost
|
| 8 |
+
eureka.instance.prefer-ip-address=true
|
| 9 |
+
eureka.client.register-with-eureka=false
|
| 10 |
+
eureka.client.fetch-registry=false
|
| 11 |
+
eureka.client.service-url.defaultZone=http://${eureka.instance.hostname}:${server.port}/eureka
|
| 12 |
+
eureka.server.enable-self-preservation=true
|
| 13 |
+
eureka.server.renewal-percent-threshold=0.85
|
| 14 |
+
eureka.server.eviction-interval-timer-in-ms=30000
|
| 15 |
+
|
| 16 |
+
# Zipkin Tracing Configuration
|
| 17 |
+
management.tracing.sampling.probability=1.0
|
| 18 |
+
management.zipkin.tracing.endpoint=http://localhost:9411/api/v2/spans
|
| 19 |
+
|
| 20 |
+
# Actuator Configuration
|
| 21 |
+
management.endpoints.web.exposure.include=*
|
| 22 |
+
management.endpoint.health.show-details=always
|
| 23 |
+
management.endpoint.health.probes.enabled=true
|
| 24 |
+
management.health.livenessstate.enabled=true
|
| 25 |
+
management.health.readinessstate.enabled=true
|
| 26 |
+
|
| 27 |
+
# Logging Configuration
|
| 28 |
+
logging.level.com.netflix.eureka=INFO
|
| 29 |
+
logging.level.com.netflix.discovery=INFO
|
| 30 |
+
logging.level.root=INFO
|
| 31 |
+
logging.pattern.console=%clr(%d{yyyy-MM-dd HH:mm:ss.SSS}){faint} %clr(${LOG_LEVEL_PATTERN:-%5p}) %clr([%15.15t]){faint} %clr(%-40.40logger{39}){cyan} %clr(:){faint} %m%n${LOG_EXCEPTION_CONVERSION_WORD:-%wEx}
|
| 32 |
+
|
| 33 |
+
# Performance Tuning
|
| 34 |
+
eureka.server.response-cache-update-interval-ms=30000
|
| 35 |
+
eureka.server.response-cache-auto-expiration-in-seconds=180
|
| 36 |
+
|
| 37 |
+
|
| 38 |
+
|
| 39 |
+
|
| 40 |
+
|
EurekaServerConfiguration/src/main/resources/logback-spring.xml
ADDED
|
@@ -0,0 +1,49 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
<?xml version="1.0" encoding="UTF-8"?>
|
| 2 |
+
<configuration>
|
| 3 |
+
<!-- Console Appender -->
|
| 4 |
+
<appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
|
| 5 |
+
<encoder class="net.logstash.logback.encoder.LoggingEventCompositeJsonEncoder">
|
| 6 |
+
<providers>
|
| 7 |
+
<timestamp/>
|
| 8 |
+
<logLevel/>
|
| 9 |
+
<loggerName/>
|
| 10 |
+
<mdc/>
|
| 11 |
+
<arguments/>
|
| 12 |
+
<message/>
|
| 13 |
+
<stackTrace/>
|
| 14 |
+
</providers>
|
| 15 |
+
</encoder>
|
| 16 |
+
</appender>
|
| 17 |
+
|
| 18 |
+
<!-- File Appender -->
|
| 19 |
+
<appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
|
| 20 |
+
<file>logs/eureka-server.log</file>
|
| 21 |
+
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
|
| 22 |
+
<fileNamePattern>logs/eureka-server.%d{yyyy-MM-dd}.gz</fileNamePattern>
|
| 23 |
+
<maxHistory>30</maxHistory>
|
| 24 |
+
<totalSizeCap>1GB</totalSizeCap>
|
| 25 |
+
</rollingPolicy>
|
| 26 |
+
<encoder>
|
| 27 |
+
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
|
| 28 |
+
</encoder>
|
| 29 |
+
</appender>
|
| 30 |
+
|
| 31 |
+
<!-- Spring profile specific configurations -->
|
| 32 |
+
<springProfile name="!docker">
|
| 33 |
+
<root level="INFO">
|
| 34 |
+
<appender-ref ref="CONSOLE"/>
|
| 35 |
+
<appender-ref ref="FILE"/>
|
| 36 |
+
</root>
|
| 37 |
+
</springProfile>
|
| 38 |
+
|
| 39 |
+
<springProfile name="docker">
|
| 40 |
+
<root level="INFO">
|
| 41 |
+
<appender-ref ref="CONSOLE"/>
|
| 42 |
+
</root>
|
| 43 |
+
</springProfile>
|
| 44 |
+
|
| 45 |
+
<!-- Package level logging -->
|
| 46 |
+
<logger name="com.netflix.eureka" level="INFO"/>
|
| 47 |
+
<logger name="com.netflix.discovery" level="INFO"/>
|
| 48 |
+
<logger name="in.garvit.tasks" level="DEBUG"/>
|
| 49 |
+
</configuration>
|
EurekaServerConfiguration/src/test/java/in/garvit/tasks/EurekaServerConfigurationApplicationTests.java
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
package in.garvit.tasks;
|
| 2 |
+
|
| 3 |
+
import org.junit.jupiter.api.Test;
|
| 4 |
+
import org.springframework.boot.test.context.SpringBootTest;
|
| 5 |
+
import org.springframework.test.context.ActiveProfiles;
|
| 6 |
+
import org.springframework.test.context.TestPropertySource;
|
| 7 |
+
|
| 8 |
+
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
|
| 9 |
+
@ActiveProfiles("test")
|
| 10 |
+
@TestPropertySource(properties = {
|
| 11 |
+
"eureka.client.register-with-eureka=false",
|
| 12 |
+
"eureka.client.fetch-registry=false",
|
| 13 |
+
"management.zipkin.tracing.endpoint="
|
| 14 |
+
})
|
| 15 |
+
class EurekaServerConfigurationApplicationTests {
|
| 16 |
+
|
| 17 |
+
@Test
|
| 18 |
+
void contextLoads() {
|
| 19 |
+
// Test that the Spring context loads successfully
|
| 20 |
+
// This test ensures all beans are properly configured
|
| 21 |
+
}
|
| 22 |
+
|
| 23 |
+
@Test
|
| 24 |
+
void applicationStartsSuccessfully() {
|
| 25 |
+
// Test that the Eureka server starts without any configuration errors
|
| 26 |
+
// The @SpringBootTest annotation ensures the full application context is loaded
|
| 27 |
+
}
|
| 28 |
+
}
|
EurekaServerConfiguration/src/test/resources/application-test.properties
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Test Configuration
|
| 2 |
+
server.port=0
|
| 3 |
+
spring.application.name=EUREKA-SERVER-TEST
|
| 4 |
+
|
| 5 |
+
# Eureka Test Configuration
|
| 6 |
+
eureka.instance.hostname=localhost
|
| 7 |
+
eureka.client.register-with-eureka=false
|
| 8 |
+
eureka.client.fetch-registry=false
|
| 9 |
+
eureka.client.service-url.defaultZone=http://localhost:8085/eureka
|
| 10 |
+
eureka.server.enable-self-preservation=false
|
| 11 |
+
eureka.server.renewal-percent-threshold=0.85
|
| 12 |
+
eureka.server.eviction-interval-timer-in-ms=10000
|
| 13 |
+
|
| 14 |
+
# Disable Zipkin for tests
|
| 15 |
+
management.tracing.sampling.probability=0
|
| 16 |
+
management.zipkin.tracing.endpoint=
|
| 17 |
+
|
| 18 |
+
# Actuator for tests
|
| 19 |
+
management.endpoints.web.exposure.include=health,info
|
| 20 |
+
management.endpoint.health.show-details=always
|
| 21 |
+
|
| 22 |
+
# Logging for tests
|
| 23 |
+
logging.level.root=WARN
|
| 24 |
+
logging.level.in.garvit.tasks=INFO
|
| 25 |
+
logging.level.com.netflix.eureka=WARN
|
FRONTEND_INTEGRATION_ISSUES.md
ADDED
|
@@ -0,0 +1,200 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Frontend Integration Issues & Solutions
|
| 2 |
+
|
| 3 |
+
## Issues Found and Fixed
|
| 4 |
+
|
| 5 |
+
### 1. **API Gateway Configuration Issue** ✅ FIXED
|
| 6 |
+
**Problem:** The API Gateway was constantly restarting due to an invalid Spring Boot configuration.
|
| 7 |
+
|
| 8 |
+
**Root Cause:** In `APIGateWay/src/main/resources/application-docker.yml`, the property `spring.profiles.active: docker` was set inside a profile-specific configuration file, which is not allowed in Spring Boot.
|
| 9 |
+
|
| 10 |
+
**Fix Applied:**
|
| 11 |
+
```yaml
|
| 12 |
+
# REMOVED this line from application-docker.yml:
|
| 13 |
+
spring:
|
| 14 |
+
profiles:
|
| 15 |
+
active: docker # ❌ Invalid in profile-specific files
|
| 16 |
+
```
|
| 17 |
+
|
| 18 |
+
**Status:** ✅ API Gateway is now healthy and running on port 8090
|
| 19 |
+
|
| 20 |
+
---
|
| 21 |
+
|
| 22 |
+
## Remaining Issues to Fix
|
| 23 |
+
|
| 24 |
+
### 2. **Missing Frontend .env File** ⚠️ CRITICAL
|
| 25 |
+
**Problem:** The frontend doesn't have a `.env` file to configure the API endpoint.
|
| 26 |
+
|
| 27 |
+
**Impact:** Frontend will use the default `http://localhost:8090` which won't work in Docker environment.
|
| 28 |
+
|
| 29 |
+
**Solution Required:**
|
| 30 |
+
Create `/home/garvitpathak27/cloud_computing/Task-Management-System-using-microservices/task-management-ui/.env`:
|
| 31 |
+
```bash
|
| 32 |
+
REACT_APP_API_BASE_URL=http://localhost:8090
|
| 33 |
+
```
|
| 34 |
+
|
| 35 |
+
**For Docker deployment (if running UI in container):**
|
| 36 |
+
```bash
|
| 37 |
+
REACT_APP_API_BASE_URL=http://api-gateway:8090
|
| 38 |
+
```
|
| 39 |
+
|
| 40 |
+
---
|
| 41 |
+
|
| 42 |
+
### 3. **Frontend Not Running** ⚠️ CRITICAL
|
| 43 |
+
**Problem:** The frontend service is not included in `docker-compose.yml` and is not running.
|
| 44 |
+
|
| 45 |
+
**Impact:** Users cannot access the web interface.
|
| 46 |
+
|
| 47 |
+
**Solutions:**
|
| 48 |
+
|
| 49 |
+
#### Option A: Run Frontend Locally (Recommended for Development)
|
| 50 |
+
```bash
|
| 51 |
+
cd /home/garvitpathak27/cloud_computing/Task-Management-System-using-microservices/task-management-ui
|
| 52 |
+
npm install
|
| 53 |
+
npm start
|
| 54 |
+
```
|
| 55 |
+
|
| 56 |
+
#### Option B: Add Frontend to Docker Compose
|
| 57 |
+
1. Create `task-management-ui/Dockerfile`:
|
| 58 |
+
```dockerfile
|
| 59 |
+
FROM node:18-alpine AS builder
|
| 60 |
+
WORKDIR /app
|
| 61 |
+
COPY package*.json ./
|
| 62 |
+
RUN npm ci
|
| 63 |
+
COPY . .
|
| 64 |
+
ENV REACT_APP_API_BASE_URL=http://localhost:8090
|
| 65 |
+
RUN npm run build
|
| 66 |
+
|
| 67 |
+
FROM nginx:alpine
|
| 68 |
+
COPY --from=builder /app/build /usr/share/nginx/html
|
| 69 |
+
EXPOSE 3000
|
| 70 |
+
CMD ["nginx", "-g", "daemon off;"]
|
| 71 |
+
```
|
| 72 |
+
|
| 73 |
+
2. Add to `docker-compose.yml`:
|
| 74 |
+
```yaml
|
| 75 |
+
frontend:
|
| 76 |
+
build:
|
| 77 |
+
context: ./task-management-ui
|
| 78 |
+
dockerfile: Dockerfile
|
| 79 |
+
container_name: task-management-ui
|
| 80 |
+
restart: unless-stopped
|
| 81 |
+
ports:
|
| 82 |
+
- "3000:80"
|
| 83 |
+
environment:
|
| 84 |
+
REACT_APP_API_BASE_URL: http://localhost:8090
|
| 85 |
+
networks:
|
| 86 |
+
- task-management-network
|
| 87 |
+
```
|
| 88 |
+
|
| 89 |
+
---
|
| 90 |
+
|
| 91 |
+
### 4. **CORS Configuration Review** ℹ️ INFO
|
| 92 |
+
**Current Status:** CORS is properly configured in multiple places:
|
| 93 |
+
|
| 94 |
+
1. **API Gateway** (`application.yml`):
|
| 95 |
+
- Allows origins: `http://localhost:3000`, `http://localhost:8080`
|
| 96 |
+
- Allows methods: GET, POST, PUT, PATCH, DELETE, OPTIONS
|
| 97 |
+
- Allows credentials: true
|
| 98 |
+
|
| 99 |
+
2. **User Service** (`SecurityConfig.java`):
|
| 100 |
+
- Configurable via environment variable: `TASK_ALLOWED_ORIGINS`
|
| 101 |
+
- Docker config allows: `http://task-management-ui:3000,http://localhost:3000`
|
| 102 |
+
|
| 103 |
+
**Note:** Make sure your frontend runs on `http://localhost:3000` to match CORS configuration.
|
| 104 |
+
|
| 105 |
+
---
|
| 106 |
+
|
| 107 |
+
## How to Test the Integration
|
| 108 |
+
|
| 109 |
+
### 1. Start Backend Services (Already Running ✅)
|
| 110 |
+
```bash
|
| 111 |
+
cd /home/garvitpathak27/cloud_computing/Task-Management-System-using-microservices
|
| 112 |
+
docker-compose -f docker-compose.yml ps
|
| 113 |
+
```
|
| 114 |
+
|
| 115 |
+
### 2. Start Frontend
|
| 116 |
+
```bash
|
| 117 |
+
cd task-management-ui
|
| 118 |
+
echo "REACT_APP_API_BASE_URL=http://localhost:8090" > .env
|
| 119 |
+
npm install
|
| 120 |
+
npm start
|
| 121 |
+
```
|
| 122 |
+
|
| 123 |
+
### 3. Verify Services
|
| 124 |
+
- **Frontend:** http://localhost:3000
|
| 125 |
+
- **API Gateway:** http://localhost:8090
|
| 126 |
+
- **Eureka Dashboard:** http://localhost:8085
|
| 127 |
+
- **Zipkin:** http://localhost:9411
|
| 128 |
+
|
| 129 |
+
### 4. Test API Endpoints
|
| 130 |
+
```bash
|
| 131 |
+
# Health check
|
| 132 |
+
curl http://localhost:8090/actuator/health
|
| 133 |
+
|
| 134 |
+
# Auth endpoint (should return 401 or error without credentials)
|
| 135 |
+
curl http://localhost:8090/auth/signin \
|
| 136 |
+
-H "Content-Type: application/json" \
|
| 137 |
+
-d '{"email":"test@test.com","password":"test123"}'
|
| 138 |
+
```
|
| 139 |
+
|
| 140 |
+
---
|
| 141 |
+
|
| 142 |
+
## Architecture Overview
|
| 143 |
+
|
| 144 |
+
```
|
| 145 |
+
┌─────────────────┐
|
| 146 |
+
│ React UI │ (Port 3000)
|
| 147 |
+
│ (Frontend) │
|
| 148 |
+
└────────┬────────┘
|
| 149 |
+
│ HTTP Requests
|
| 150 |
+
↓
|
| 151 |
+
┌─────────────────┐
|
| 152 |
+
│ API Gateway │ (Port 8090) ✅ Fixed
|
| 153 |
+
│ Spring Cloud │
|
| 154 |
+
└────────┬────────┘
|
| 155 |
+
│ Load Balancing via Eureka
|
| 156 |
+
↓
|
| 157 |
+
┌────────────────────────────────────┐
|
| 158 |
+
│ Eureka Server │ (Port 8085)
|
| 159 |
+
│ Service Discovery │
|
| 160 |
+
└────────────────┬───────────────────┘
|
| 161 |
+
│
|
| 162 |
+
┌────────────┼────────────┐
|
| 163 |
+
↓ ↓ ↓
|
| 164 |
+
┌─────────┐ ┌──────────┐ ┌─────────────┐
|
| 165 |
+
│ User │ │ Task │ │ Submission │
|
| 166 |
+
│ Service │ │ Service │ │ Service │
|
| 167 |
+
│ (8081) │ │ (8082) │ │ (8083) │
|
| 168 |
+
└────┬────┘ └────┬─────┘ └──────┬──────┘
|
| 169 |
+
│ │ │
|
| 170 |
+
└───────────┴───────────────┘
|
| 171 |
+
│
|
| 172 |
+
┌─────┴──────┐
|
| 173 |
+
│ MongoDB │ (Port 27017)
|
| 174 |
+
└────────────┘
|
| 175 |
+
```
|
| 176 |
+
|
| 177 |
+
---
|
| 178 |
+
|
| 179 |
+
## Next Steps
|
| 180 |
+
|
| 181 |
+
1. ✅ **Fixed:** API Gateway configuration issue
|
| 182 |
+
2. ⚠️ **TODO:** Create `.env` file in `task-management-ui/`
|
| 183 |
+
3. ⚠️ **TODO:** Start the frontend application
|
| 184 |
+
4. ℹ️ **Optional:** Add frontend to Docker Compose for production deployment
|
| 185 |
+
5. 🧪 **Test:** Complete end-to-end testing of authentication and API calls
|
| 186 |
+
|
| 187 |
+
---
|
| 188 |
+
|
| 189 |
+
## Quick Start Frontend
|
| 190 |
+
|
| 191 |
+
Run these commands to start the frontend:
|
| 192 |
+
|
| 193 |
+
```bash
|
| 194 |
+
cd /home/garvitpathak27/cloud_computing/Task-Management-System-using-microservices/task-management-ui
|
| 195 |
+
echo "REACT_APP_API_BASE_URL=http://localhost:8090" > .env
|
| 196 |
+
npm install
|
| 197 |
+
npm start
|
| 198 |
+
```
|
| 199 |
+
|
| 200 |
+
The frontend will be available at **http://localhost:3000**
|
QUICKSTART.md
ADDED
|
@@ -0,0 +1,297 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# 🚀 Quick Start Guide
|
| 2 |
+
|
| 3 |
+
## Prerequisites
|
| 4 |
+
|
| 5 |
+
Make sure you have these installed:
|
| 6 |
+
- ✅ Docker & Docker Compose
|
| 7 |
+
- ✅ Java 17 or higher
|
| 8 |
+
- ✅ Node.js & npm (for frontend)
|
| 9 |
+
|
| 10 |
+
---
|
| 11 |
+
|
| 12 |
+
## 🎯 Option 1: Start Everything at Once (Recommended)
|
| 13 |
+
|
| 14 |
+
### Start All Services (Backend + Frontend)
|
| 15 |
+
```bash
|
| 16 |
+
cd /home/garvitpathak27/cloud_computing/Task-Management-System-using-microservices
|
| 17 |
+
./start-all.sh
|
| 18 |
+
```
|
| 19 |
+
|
| 20 |
+
### Stop All Services
|
| 21 |
+
```bash
|
| 22 |
+
./stop-all.sh
|
| 23 |
+
```
|
| 24 |
+
|
| 25 |
+
**That's it!** After running `./start-all.sh`:
|
| 26 |
+
- Backend services will be ready in ~30 seconds
|
| 27 |
+
- Frontend will be available at http://localhost:3000 in ~45 seconds
|
| 28 |
+
|
| 29 |
+
---
|
| 30 |
+
|
| 31 |
+
## 🎯 Option 2: Start Services Separately
|
| 32 |
+
|
| 33 |
+
### Backend Services Only
|
| 34 |
+
|
| 35 |
+
**Start:**
|
| 36 |
+
```bash
|
| 37 |
+
cd /home/garvitpathak27/cloud_computing/Task-Management-System-using-microservices
|
| 38 |
+
./run-system.sh
|
| 39 |
+
```
|
| 40 |
+
|
| 41 |
+
**Stop:**
|
| 42 |
+
```bash
|
| 43 |
+
./stop-system.sh
|
| 44 |
+
```
|
| 45 |
+
|
| 46 |
+
### Frontend Only
|
| 47 |
+
|
| 48 |
+
**Start:**
|
| 49 |
+
```bash
|
| 50 |
+
cd /home/garvitpathak27/cloud_computing/Task-Management-System-using-microservices/task-management-ui
|
| 51 |
+
npm install # First time only
|
| 52 |
+
npm start
|
| 53 |
+
```
|
| 54 |
+
|
| 55 |
+
**Stop:** Press `Ctrl+C` in the terminal
|
| 56 |
+
|
| 57 |
+
---
|
| 58 |
+
|
| 59 |
+
## 🎯 Option 3: Manual Docker Commands
|
| 60 |
+
|
| 61 |
+
If the scripts don't work, you can use Docker commands directly:
|
| 62 |
+
|
| 63 |
+
### Start Backend
|
| 64 |
+
```bash
|
| 65 |
+
cd /home/garvitpathak27/cloud_computing/Task-Management-System-using-microservices
|
| 66 |
+
|
| 67 |
+
# Build all services first
|
| 68 |
+
./build-all.sh
|
| 69 |
+
|
| 70 |
+
# Start with Docker Compose
|
| 71 |
+
docker-compose up -d
|
| 72 |
+
|
| 73 |
+
# Check status
|
| 74 |
+
docker-compose ps
|
| 75 |
+
```
|
| 76 |
+
|
| 77 |
+
### Stop Backend
|
| 78 |
+
```bash
|
| 79 |
+
cd /home/garvitpathak27/cloud_computing/Task-Management-System-using-microservices
|
| 80 |
+
docker-compose down
|
| 81 |
+
```
|
| 82 |
+
|
| 83 |
+
---
|
| 84 |
+
|
| 85 |
+
## 📊 Access the Application
|
| 86 |
+
|
| 87 |
+
Once everything is running:
|
| 88 |
+
|
| 89 |
+
| Service | URL | Description |
|
| 90 |
+
|---------|-----|-------------|
|
| 91 |
+
| **Frontend** | http://localhost:3000 | React web interface |
|
| 92 |
+
| **API Gateway** | http://localhost:8090 | Main API endpoint |
|
| 93 |
+
| **Eureka Dashboard** | http://localhost:8085 | Service discovery |
|
| 94 |
+
| **Zipkin** | http://localhost:9411 | Distributed tracing |
|
| 95 |
+
| **User Service** | http://localhost:8081 | User management |
|
| 96 |
+
| **Task Service** | http://localhost:8082 | Task management |
|
| 97 |
+
| **Submission Service** | http://localhost:8083 | Submission management |
|
| 98 |
+
|
| 99 |
+
---
|
| 100 |
+
|
| 101 |
+
## 🔍 Troubleshooting
|
| 102 |
+
|
| 103 |
+
### Check if services are running
|
| 104 |
+
```bash
|
| 105 |
+
cd /home/garvitpathak27/cloud_computing/Task-Management-System-using-microservices
|
| 106 |
+
docker-compose ps
|
| 107 |
+
```
|
| 108 |
+
|
| 109 |
+
All services should show "Up (healthy)".
|
| 110 |
+
|
| 111 |
+
### View logs
|
| 112 |
+
```bash
|
| 113 |
+
# All services
|
| 114 |
+
docker-compose logs -f
|
| 115 |
+
|
| 116 |
+
# Specific service
|
| 117 |
+
docker-compose logs -f api-gateway
|
| 118 |
+
docker-compose logs -f user-service
|
| 119 |
+
```
|
| 120 |
+
|
| 121 |
+
### Services not starting?
|
| 122 |
+
```bash
|
| 123 |
+
# Stop everything
|
| 124 |
+
docker-compose down
|
| 125 |
+
|
| 126 |
+
# Remove old containers and volumes
|
| 127 |
+
docker-compose down -v
|
| 128 |
+
|
| 129 |
+
# Rebuild and start fresh
|
| 130 |
+
./build-all.sh
|
| 131 |
+
docker-compose up -d
|
| 132 |
+
```
|
| 133 |
+
|
| 134 |
+
### Frontend not loading?
|
| 135 |
+
```bash
|
| 136 |
+
cd task-management-ui
|
| 137 |
+
|
| 138 |
+
# Check if .env file exists
|
| 139 |
+
cat .env
|
| 140 |
+
|
| 141 |
+
# Should show: REACT_APP_API_BASE_URL=http://localhost:8090
|
| 142 |
+
|
| 143 |
+
# Reinstall dependencies
|
| 144 |
+
rm -rf node_modules package-lock.json
|
| 145 |
+
npm install
|
| 146 |
+
npm start
|
| 147 |
+
```
|
| 148 |
+
|
| 149 |
+
### Port already in use?
|
| 150 |
+
```bash
|
| 151 |
+
# Check what's using the port (e.g., 3000)
|
| 152 |
+
lsof -i :3000
|
| 153 |
+
|
| 154 |
+
# Kill the process
|
| 155 |
+
kill -9 <PID>
|
| 156 |
+
```
|
| 157 |
+
|
| 158 |
+
---
|
| 159 |
+
|
| 160 |
+
## 🏗️ Architecture
|
| 161 |
+
|
| 162 |
+
```
|
| 163 |
+
┌─────────────────┐
|
| 164 |
+
│ React UI │ ← You interact here (localhost:3000)
|
| 165 |
+
│ (Frontend) │
|
| 166 |
+
└────────┬────────┘
|
| 167 |
+
│ HTTP Requests
|
| 168 |
+
↓
|
| 169 |
+
┌─────────────────┐
|
| 170 |
+
│ API Gateway │ ← All requests go through here (localhost:8090)
|
| 171 |
+
│ (Port 8090) │
|
| 172 |
+
└────────┬────────┘
|
| 173 |
+
│ Service Discovery
|
| 174 |
+
↓
|
| 175 |
+
┌─────────────────┐
|
| 176 |
+
│ Eureka Server │ ← Manages all microservices (localhost:8085)
|
| 177 |
+
│ (Port 8085) │
|
| 178 |
+
└────────┬────────┘
|
| 179 |
+
│
|
| 180 |
+
┌────┴────┬────────────┐
|
| 181 |
+
↓ ↓ ↓
|
| 182 |
+
┌─────────┐ ┌──────────┐ ┌─────────────┐
|
| 183 |
+
│ User │ │ Task │ │ Submission │
|
| 184 |
+
│ Service │ │ Service │ │ Service │
|
| 185 |
+
│ (8081) │ │ (8082) │ │ (8083) │
|
| 186 |
+
└────┬────┘ └────┬─────┘ └──────┬──────┘
|
| 187 |
+
│ │ │
|
| 188 |
+
└───────────┴───────────────┘
|
| 189 |
+
│
|
| 190 |
+
┌─────┴──────┐
|
| 191 |
+
│ MongoDB │ ← Database (localhost:27017)
|
| 192 |
+
└────────────┘
|
| 193 |
+
```
|
| 194 |
+
|
| 195 |
+
---
|
| 196 |
+
|
| 197 |
+
## 📝 Development Workflow
|
| 198 |
+
|
| 199 |
+
### Starting development for the day
|
| 200 |
+
```bash
|
| 201 |
+
cd /home/garvitpathak27/cloud_computing/Task-Management-System-using-microservices
|
| 202 |
+
./start-all.sh
|
| 203 |
+
```
|
| 204 |
+
|
| 205 |
+
### Making changes to backend code
|
| 206 |
+
1. Make your changes in the respective service folder
|
| 207 |
+
2. Rebuild that specific service:
|
| 208 |
+
```bash
|
| 209 |
+
cd TaskUserService # or TaskService, etc.
|
| 210 |
+
./gradlew build
|
| 211 |
+
```
|
| 212 |
+
3. Restart the service:
|
| 213 |
+
```bash
|
| 214 |
+
docker-compose restart user-service
|
| 215 |
+
```
|
| 216 |
+
|
| 217 |
+
### Making changes to frontend code
|
| 218 |
+
- Just save the file - React hot reloads automatically! ✨
|
| 219 |
+
|
| 220 |
+
### Ending development for the day
|
| 221 |
+
```bash
|
| 222 |
+
cd /home/garvitpathak27/cloud_computing/Task-Management-System-using-microservices
|
| 223 |
+
./stop-all.sh
|
| 224 |
+
```
|
| 225 |
+
|
| 226 |
+
---
|
| 227 |
+
|
| 228 |
+
## 🎓 First Time Setup
|
| 229 |
+
|
| 230 |
+
If this is your first time running the project:
|
| 231 |
+
|
| 232 |
+
1. **Clone the repository** (if not already done)
|
| 233 |
+
2. **Navigate to the project:**
|
| 234 |
+
```bash
|
| 235 |
+
cd /home/garvitpathak27/cloud_computing/Task-Management-System-using-microservices
|
| 236 |
+
```
|
| 237 |
+
|
| 238 |
+
3. **Install frontend dependencies:**
|
| 239 |
+
```bash
|
| 240 |
+
cd task-management-ui
|
| 241 |
+
npm install
|
| 242 |
+
cd ..
|
| 243 |
+
```
|
| 244 |
+
|
| 245 |
+
4. **Start everything:**
|
| 246 |
+
```bash
|
| 247 |
+
./start-all.sh
|
| 248 |
+
```
|
| 249 |
+
|
| 250 |
+
5. **Wait ~1 minute** for all services to start
|
| 251 |
+
|
| 252 |
+
6. **Open your browser:** http://localhost:3000
|
| 253 |
+
|
| 254 |
+
---
|
| 255 |
+
|
| 256 |
+
## ✅ Current Status
|
| 257 |
+
|
| 258 |
+
**All services are currently running!** 🎉
|
| 259 |
+
|
| 260 |
+
You can verify by running:
|
| 261 |
+
```bash
|
| 262 |
+
docker-compose ps
|
| 263 |
+
```
|
| 264 |
+
|
| 265 |
+
To stop them:
|
| 266 |
+
```bash
|
| 267 |
+
./stop-all.sh
|
| 268 |
+
```
|
| 269 |
+
|
| 270 |
+
To restart them:
|
| 271 |
+
```bash
|
| 272 |
+
./start-all.sh
|
| 273 |
+
```
|
| 274 |
+
|
| 275 |
+
---
|
| 276 |
+
|
| 277 |
+
## 💡 Tips
|
| 278 |
+
|
| 279 |
+
- **First startup takes longer** (~2-3 minutes) as Docker downloads images
|
| 280 |
+
- **Subsequent startups are faster** (~30 seconds)
|
| 281 |
+
- **Frontend compilation** takes ~10-15 seconds
|
| 282 |
+
- **Check Eureka dashboard** to see all registered services
|
| 283 |
+
- **Use Zipkin** to trace requests across microservices
|
| 284 |
+
- **MongoDB data persists** between restarts (stored in Docker volume)
|
| 285 |
+
|
| 286 |
+
---
|
| 287 |
+
|
| 288 |
+
## 🆘 Need Help?
|
| 289 |
+
|
| 290 |
+
1. Check the logs: `docker-compose logs -f`
|
| 291 |
+
2. Verify all services are healthy: `docker-compose ps`
|
| 292 |
+
3. Make sure ports are not in use: `lsof -i :3000,8081,8082,8083,8090`
|
| 293 |
+
4. See detailed troubleshooting: [FRONTEND_INTEGRATION_ISSUES.md](./FRONTEND_INTEGRATION_ISSUES.md)
|
| 294 |
+
|
| 295 |
+
---
|
| 296 |
+
|
| 297 |
+
**Happy Coding! 🚀**
|
README.md
CHANGED
|
@@ -1,10 +1,219 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
---
|
| 2 |
-
|
| 3 |
-
|
| 4 |
-
|
| 5 |
-
|
| 6 |
-
|
| 7 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 8 |
---
|
| 9 |
|
| 10 |
-
|
|
|
|
| 1 |
+
# Task Management System (Microservices)
|
| 2 |
+
|
| 3 |
+
A Spring Cloud microservice ecosystem for managing tasks with a React front-end. An API Gateway exposes the platform through a single port, Eureka provides service discovery, and MongoDB persists user, task, and submission data. The solution can be run locally with Gradle/npm or containerised end-to-end with Docker Compose.
|
| 4 |
+
|
| 5 |
---
|
| 6 |
+
|
| 7 |
+
## Overview
|
| 8 |
+
|
| 9 |
+
This project implements a Task Management system using a microservices architecture. The system consists of three main microservices plus infrastructure components:
|
| 10 |
+
|
| 11 |
+
- **TaskUserService** – authentication, JWT issuance, profile and admin endpoints.
|
| 12 |
+
- **TaskService** – task CRUD, assignment and completion workflows.
|
| 13 |
+
- **TaskSubmissionService** – submission lifecycle and coordination with other services via OpenFeign.
|
| 14 |
+
- **EurekaServerConfiguration** – service registry for discovery and health status.
|
| 15 |
+
- **APIGateway** – Spring Cloud Gateway with resilience policies and CORS/fallback handling.
|
| 16 |
+
- **task-management-ui** – React SPA consuming the gateway APIs.
|
| 17 |
+
|
| 18 |
+
Additional runtime services in Docker Compose:
|
| 19 |
+
- **MongoDB** (Docker)
|
| 20 |
+
- **Zipkin** (Docker) for tracing
|
| 21 |
+
|
| 22 |
+
---
|
| 23 |
+
|
| 24 |
+
## Tech stack
|
| 25 |
+
|
| 26 |
+
- Java 17, Spring Boot 3.2, Spring Cloud 2023.0
|
| 27 |
+
- Gradle 8
|
| 28 |
+
- React 18 (Create React App)
|
| 29 |
+
- Node.js 18+, npm 9+
|
| 30 |
+
- MongoDB 6
|
| 31 |
+
- Docker & Docker Compose (Docker Engine 24+, Compose v2 recommended)
|
| 32 |
+
- Spring Security, Resilience4j, OpenFeign, Micrometer/Zipkin
|
| 33 |
+
|
| 34 |
+
|
| 35 |
+
## Repository layout (high level)
|
| 36 |
+
|
| 37 |
+
```
|
| 38 |
+
APIGateWay/ # Spring Cloud Gateway service
|
| 39 |
+
EurekaServerConfiguration/ # Eureka discovery server
|
| 40 |
+
TaskUserService/ # Authentication / User management service
|
| 41 |
+
TaskService/ # Task domain microservice
|
| 42 |
+
TaskSubmissionService/ # Submission microservice
|
| 43 |
+
task-management-ui/ # React single page application
|
| 44 |
+
build-all.sh # Builds all services and UI
|
| 45 |
+
run-system.sh # Builds and launches full stack with Compose
|
| 46 |
+
stop-system.sh # Stops the Compose stack
|
| 47 |
+
docker-compose.yml # Compose orchestration for services + MongoDB + Zipkin
|
| 48 |
+
```
|
| 49 |
+
|
| 50 |
+
---
|
| 51 |
+
|
| 52 |
+
## Features (selected)
|
| 53 |
+
|
| 54 |
+
### UserService
|
| 55 |
+
- `POST /auth/signup` — user registration
|
| 56 |
+
- `POST /auth/signin` — authentication (returns JWT)
|
| 57 |
+
- `GET /api/user/profile` — get user profile
|
| 58 |
+
|
| 59 |
+
### TaskService
|
| 60 |
+
- `POST /api/tasks/create` — create new task (admin only)
|
| 61 |
+
- `GET /api/tasks/{taskId}` — get task details
|
| 62 |
+
- `PUT /api/tasks/{taskId}/assign/{userId}` — assign task to user (admin only)
|
| 63 |
+
|
| 64 |
+
### TaskSubmissionService
|
| 65 |
+
- `POST /api/submissions/submit` — submit completed task (authenticated users)
|
| 66 |
+
- `GET /api/submissions/{submissionId}` — get submission details
|
| 67 |
+
|
| 68 |
+
---
|
| 69 |
+
|
| 70 |
+
## Configuration
|
| 71 |
+
|
| 72 |
+
All Spring services accept environment overrides (via environment variables or `application-*.properties`) for values such as:
|
| 73 |
+
|
| 74 |
+
| Variable | Applies to | Purpose | Default (local) |
|
| 75 |
+
|---|---:|---|---:|
|
| 76 |
+
| `SERVER_PORT` | All Spring services | HTTP port override | service-specific |
|
| 77 |
+
| `SPRING_APP_NAME` | All services | Service identifier / registration name | - |
|
| 78 |
+
| `EUREKA_SERVER_URI` | Gateway & microservices | Eureka discovery endpoint | `http://localhost:8085/eureka` |
|
| 79 |
+
| `MONGODB_URI` | Backends | MongoDB connection string | `mongodb://localhost:27017/<db>` |
|
| 80 |
+
| `ZIPKIN_BASE_URL` | All services | Zipkin tracing endpoint | `http://localhost:9411` |
|
| 81 |
+
| `ZIPKIN_SAMPLER_PROBABILITY` | All services | Tracing sampling rate | `1.0` |
|
| 82 |
+
|
| 83 |
+
Each service also exposes domain-specific properties (JWT secrets, CORS allowed origins, etc.) in its `application.properties`/`application-docker.properties` files. Defaults are safe for local usage but **must** be overridden for production.
|
| 84 |
+
|
| 85 |
+
---
|
| 86 |
+
|
| 87 |
+
## Prerequisites / System requirements
|
| 88 |
+
|
| 89 |
+
- JDK 17+
|
| 90 |
+
- Node.js 18+, npm 9+
|
| 91 |
+
- Docker Engine 24+ and Docker Compose v2 (or docker-compose v1)
|
| 92 |
+
- 8 GB RAM recommended when running full stack locally
|
| 93 |
+
|
| 94 |
+
---
|
| 95 |
+
|
| 96 |
+
## Setup & Running
|
| 97 |
+
|
| 98 |
+
### Option 1 — Full stack via Docker Compose (recommended for quick end-to-end runs)
|
| 99 |
+
|
| 100 |
+
1. (Optional) Create a Docker volume for MongoDB persistence:
|
| 101 |
+
```bash
|
| 102 |
+
docker volume create mongo-data
|
| 103 |
+
```
|
| 104 |
+
2. Build and run everything (the `run-system.sh` helper can be used if present):
|
| 105 |
+
```bash
|
| 106 |
+
./run-system.sh
|
| 107 |
+
# or
|
| 108 |
+
docker compose up --build
|
| 109 |
+
```
|
| 110 |
+
3. Verify services are registered in Eureka (default port shown by the compose file):
|
| 111 |
+
- Eureka dashboard: `http://localhost:8085`
|
| 112 |
+
- API Gateway health: `http://localhost:8090/actuator/health`
|
| 113 |
+
- Zipkin UI: `http://localhost:9411`
|
| 114 |
+
- React dev UI: `http://localhost:3000` (if using `npm start` instead of build)
|
| 115 |
+
|
| 116 |
+
Stop everything:
|
| 117 |
+
```bash
|
| 118 |
+
./stop-system.sh
|
| 119 |
+
# or
|
| 120 |
+
docker compose down
|
| 121 |
+
```
|
| 122 |
+
|
| 123 |
+
To remove persisted MongoDB data:
|
| 124 |
+
```bash
|
| 125 |
+
docker volume rm mongo-data
|
| 126 |
+
```
|
| 127 |
+
|
| 128 |
+
### Option 2 — Run services locally (development)
|
| 129 |
+
|
| 130 |
+
1. Start MongoDB locally or via Docker:
|
| 131 |
+
```bash
|
| 132 |
+
docker run -p 27017:27017 --name mongo -d mongo:6.0
|
| 133 |
+
```
|
| 134 |
+
2. Start Eureka server:
|
| 135 |
+
```bash
|
| 136 |
+
cd EurekaServerConfiguration
|
| 137 |
+
./gradlew bootRun
|
| 138 |
+
```
|
| 139 |
+
3. Start services in separate terminals:
|
| 140 |
+
```bash
|
| 141 |
+
cd TaskUserService && ./gradlew bootRun
|
| 142 |
+
cd TaskService && ./gradlew bootRun
|
| 143 |
+
cd TaskSubmissionService && ./gradlew bootRun
|
| 144 |
+
cd APIGateWay && ./gradlew bootRun
|
| 145 |
+
```
|
| 146 |
+
4. Start React UI (dev mode):
|
| 147 |
+
```bash
|
| 148 |
+
cd task-management-ui
|
| 149 |
+
npm install
|
| 150 |
+
npm start
|
| 151 |
+
```
|
| 152 |
+
|
| 153 |
+
When running behind the gateway, point the UI to the gateway base URL (example `.env`):
|
| 154 |
+
```
|
| 155 |
+
REACT_APP_API_BASE_URL=http://localhost:8090
|
| 156 |
+
```
|
| 157 |
+
|
| 158 |
+
---
|
| 159 |
+
|
| 160 |
+
## Build
|
| 161 |
+
|
| 162 |
+
### One-step build (bundles backends and UI)
|
| 163 |
+
|
| 164 |
+
```bash
|
| 165 |
+
./build-all.sh
|
| 166 |
+
```
|
| 167 |
+
|
| 168 |
+
### Manual builds
|
| 169 |
+
|
| 170 |
+
- Backends: inside each service directory
|
| 171 |
+
```bash
|
| 172 |
+
./gradlew clean bootJar -x test
|
| 173 |
+
```
|
| 174 |
+
- UI
|
| 175 |
+
```bash
|
| 176 |
+
cd task-management-ui
|
| 177 |
+
npm install
|
| 178 |
+
npm run build
|
| 179 |
+
```
|
| 180 |
+
|
| 181 |
+
---
|
| 182 |
+
|
| 183 |
+
## Troubleshooting
|
| 184 |
+
|
| 185 |
+
- **MongoDB health check fails**: ensure your host CPU supports AVX (required for MongoDB 6), or run a remote MongoDB instance and set `MONGODB_URI` accordingly.
|
| 186 |
+
- **Port conflicts**: adjust `SERVER_PORT` environment variable for services.
|
| 187 |
+
- **Gateway CORS errors**: set appropriate `GATEWAY_ALLOWED_ORIGIN_*` and `TASK_ALLOWED_ORIGINS` env vars to match your front-end origin(s).
|
| 188 |
+
- **Zipkin unreachable**: either run Zipkin container or comment out `ZIPKIN_BASE_URL` in configs to disable tracing.
|
| 189 |
+
|
| 190 |
+
---
|
| 191 |
+
|
| 192 |
+
## Verification checklist
|
| 193 |
+
|
| 194 |
+
- Eureka dashboard shows `USER-SERVICE`, `TASK-SERVICE`, and `TASK-SUBMISSION` as `UP`.
|
| 195 |
+
- Gateway health endpoint returns `{"status":"UP"}`.
|
| 196 |
+
- Service actuator health endpoints are available (e.g. `http://localhost:8081/actuator/health`, `:8082`, `:8083`).
|
| 197 |
+
- MongoDB collections: `users`, `tasks`, `submissions`.
|
| 198 |
+
|
| 199 |
+
---
|
| 200 |
+
|
| 201 |
+
## Notes
|
| 202 |
+
|
| 203 |
+
- Admin-only endpoints are protected by role checks (create/assign tasks).
|
| 204 |
+
- OpenFeign is used for inter-service HTTP clients.
|
| 205 |
+
- Production deployments should rotate secrets and secure all JWT keys / database credentials.
|
| 206 |
+
|
| 207 |
+
---
|
| 208 |
+
|
| 209 |
+
## Contribution
|
| 210 |
+
|
| 211 |
+
Contributions are welcome — open an issue or submit a PR.
|
| 212 |
+
|
| 213 |
+
## License
|
| 214 |
+
|
| 215 |
+
This project is licensed under the MIT License.
|
| 216 |
+
|
| 217 |
---
|
| 218 |
|
| 219 |
+
*Happy shipping! 🚀*
|
TaskService/.gitignore
ADDED
|
@@ -0,0 +1,37 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 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/
|
TaskService/API_REFERENCE.md
ADDED
|
@@ -0,0 +1,425 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Task Service API Quick Reference
|
| 2 |
+
|
| 3 |
+
## Base URL
|
| 4 |
+
```
|
| 5 |
+
http://localhost:8082
|
| 6 |
+
```
|
| 7 |
+
|
| 8 |
+
## Authentication
|
| 9 |
+
All endpoints (except health check) require JWT authentication in the header:
|
| 10 |
+
```
|
| 11 |
+
Authorization: Bearer <your_jwt_token>
|
| 12 |
+
```
|
| 13 |
+
|
| 14 |
+
---
|
| 15 |
+
|
| 16 |
+
## Endpoints Summary
|
| 17 |
+
|
| 18 |
+
| Method | Endpoint | Description | Auth | Admin Only |
|
| 19 |
+
|--------|----------|-------------|------|------------|
|
| 20 |
+
| GET | `/tasks` | Health check | No | No |
|
| 21 |
+
| POST | `/api/tasks` | Create task | Yes | Yes |
|
| 22 |
+
| GET | `/api/tasks` | Get all tasks | Yes | No |
|
| 23 |
+
| GET | `/api/tasks/{id}` | Get task by ID | Yes | No |
|
| 24 |
+
| GET | `/api/tasks/user` | Get user's assigned tasks | Yes | No |
|
| 25 |
+
| PUT | `/api/tasks/{id}` | Update task | Yes | No |
|
| 26 |
+
| PUT | `/api/tasks/{id}/user/{userId}/assigned` | Assign task to user | Yes | No |
|
| 27 |
+
| PUT | `/api/tasks/{id}/complete` | Mark task as complete | Yes | No |
|
| 28 |
+
| DELETE | `/api/tasks/{id}` | Delete task | Yes | No |
|
| 29 |
+
|
| 30 |
+
---
|
| 31 |
+
|
| 32 |
+
## Detailed API Documentation
|
| 33 |
+
|
| 34 |
+
### 1. Health Check
|
| 35 |
+
Check if service is running.
|
| 36 |
+
|
| 37 |
+
**Request:**
|
| 38 |
+
```http
|
| 39 |
+
GET /tasks
|
| 40 |
+
```
|
| 41 |
+
|
| 42 |
+
**Response:**
|
| 43 |
+
```json
|
| 44 |
+
"Welcome to Task Service"
|
| 45 |
+
```
|
| 46 |
+
|
| 47 |
+
---
|
| 48 |
+
|
| 49 |
+
### 2. Create Task (Admin Only)
|
| 50 |
+
Create a new task. Only users with ROLE_ADMIN can create tasks.
|
| 51 |
+
|
| 52 |
+
**Request:**
|
| 53 |
+
```http
|
| 54 |
+
POST /api/tasks
|
| 55 |
+
Authorization: Bearer <jwt_token>
|
| 56 |
+
Content-Type: application/json
|
| 57 |
+
|
| 58 |
+
{
|
| 59 |
+
"title": "Implement new feature",
|
| 60 |
+
"description": "Implement the new authentication feature",
|
| 61 |
+
"imageUrl": "https://example.com/image.png",
|
| 62 |
+
"deadline": "2024-12-31T23:59:59",
|
| 63 |
+
"tags": ["backend", "security", "priority-high"]
|
| 64 |
+
}
|
| 65 |
+
```
|
| 66 |
+
|
| 67 |
+
**Response (201 CREATED):**
|
| 68 |
+
```json
|
| 69 |
+
{
|
| 70 |
+
"id": "65f9a1234567890abcdef123",
|
| 71 |
+
"title": "Implement new feature",
|
| 72 |
+
"description": "Implement the new authentication feature",
|
| 73 |
+
"imageUrl": "https://example.com/image.png",
|
| 74 |
+
"assignedUserId": null,
|
| 75 |
+
"status": "PENDING",
|
| 76 |
+
"deadline": "2024-12-31T23:59:59",
|
| 77 |
+
"createAt": "2024-11-10T10:30:00",
|
| 78 |
+
"tags": ["backend", "security", "priority-high"]
|
| 79 |
+
}
|
| 80 |
+
```
|
| 81 |
+
|
| 82 |
+
---
|
| 83 |
+
|
| 84 |
+
### 3. Get All Tasks
|
| 85 |
+
Retrieve all tasks with optional filtering and sorting.
|
| 86 |
+
|
| 87 |
+
**Request:**
|
| 88 |
+
```http
|
| 89 |
+
GET /api/tasks?status=PENDING&sortByDeadline=asc
|
| 90 |
+
Authorization: Bearer <jwt_token>
|
| 91 |
+
```
|
| 92 |
+
|
| 93 |
+
**Query Parameters:**
|
| 94 |
+
- `status` (optional): Filter by status - `PENDING`, `ASSIGNED`, or `DONE`
|
| 95 |
+
- `sortByDeadline` (optional): Sort by deadline - `asc` or `desc`
|
| 96 |
+
- `sortByCreatedAt` (optional): Sort by creation date - `asc` or `desc`
|
| 97 |
+
|
| 98 |
+
**Response (200 OK):**
|
| 99 |
+
```json
|
| 100 |
+
[
|
| 101 |
+
{
|
| 102 |
+
"id": "65f9a1234567890abcdef123",
|
| 103 |
+
"title": "Implement new feature",
|
| 104 |
+
"description": "Implement the new authentication feature",
|
| 105 |
+
"imageUrl": "https://example.com/image.png",
|
| 106 |
+
"assignedUserId": null,
|
| 107 |
+
"status": "PENDING",
|
| 108 |
+
"deadline": "2024-12-31T23:59:59",
|
| 109 |
+
"createAt": "2024-11-10T10:30:00",
|
| 110 |
+
"tags": ["backend", "security"]
|
| 111 |
+
},
|
| 112 |
+
{
|
| 113 |
+
"id": "65f9a1234567890abcdef456",
|
| 114 |
+
"title": "Fix bug in payment module",
|
| 115 |
+
"description": "Resolve the payment gateway timeout issue",
|
| 116 |
+
"imageUrl": null,
|
| 117 |
+
"assignedUserId": null,
|
| 118 |
+
"status": "PENDING",
|
| 119 |
+
"deadline": "2024-11-15T18:00:00",
|
| 120 |
+
"createAt": "2024-11-10T11:00:00",
|
| 121 |
+
"tags": ["bug", "payment"]
|
| 122 |
+
}
|
| 123 |
+
]
|
| 124 |
+
```
|
| 125 |
+
|
| 126 |
+
---
|
| 127 |
+
|
| 128 |
+
### 4. Get Task by ID
|
| 129 |
+
Retrieve a specific task by its ID.
|
| 130 |
+
|
| 131 |
+
**Request:**
|
| 132 |
+
```http
|
| 133 |
+
GET /api/tasks/65f9a1234567890abcdef123
|
| 134 |
+
Authorization: Bearer <jwt_token>
|
| 135 |
+
```
|
| 136 |
+
|
| 137 |
+
**Response (200 OK):**
|
| 138 |
+
```json
|
| 139 |
+
{
|
| 140 |
+
"id": "65f9a1234567890abcdef123",
|
| 141 |
+
"title": "Implement new feature",
|
| 142 |
+
"description": "Implement the new authentication feature",
|
| 143 |
+
"imageUrl": "https://example.com/image.png",
|
| 144 |
+
"assignedUserId": "user123",
|
| 145 |
+
"status": "ASSIGNED",
|
| 146 |
+
"deadline": "2024-12-31T23:59:59",
|
| 147 |
+
"createAt": "2024-11-10T10:30:00",
|
| 148 |
+
"tags": ["backend", "security"]
|
| 149 |
+
}
|
| 150 |
+
```
|
| 151 |
+
|
| 152 |
+
**Error Response (404 NOT FOUND):**
|
| 153 |
+
```json
|
| 154 |
+
{
|
| 155 |
+
"timestamp": "2024-11-10T10:30:00",
|
| 156 |
+
"message": "Task not found with id: 65f9a1234567890abcdef123",
|
| 157 |
+
"status": 404,
|
| 158 |
+
"error": "Task Not Found"
|
| 159 |
+
}
|
| 160 |
+
```
|
| 161 |
+
|
| 162 |
+
---
|
| 163 |
+
|
| 164 |
+
### 5. Get User's Assigned Tasks
|
| 165 |
+
Retrieve all tasks assigned to the authenticated user.
|
| 166 |
+
|
| 167 |
+
**Request:**
|
| 168 |
+
```http
|
| 169 |
+
GET /api/tasks/user?status=ASSIGNED&sortByDeadline=asc
|
| 170 |
+
Authorization: Bearer <jwt_token>
|
| 171 |
+
```
|
| 172 |
+
|
| 173 |
+
**Query Parameters:**
|
| 174 |
+
- `status` (optional): Filter by status - `PENDING`, `ASSIGNED`, or `DONE`
|
| 175 |
+
- `sortByDeadline` (optional): Sort by deadline - `asc` or `desc`
|
| 176 |
+
- `sortByCreatedAt` (optional): Sort by creation date - `asc` or `desc`
|
| 177 |
+
|
| 178 |
+
**Response (200 OK):**
|
| 179 |
+
```json
|
| 180 |
+
[
|
| 181 |
+
{
|
| 182 |
+
"id": "65f9a1234567890abcdef123",
|
| 183 |
+
"title": "Implement new feature",
|
| 184 |
+
"description": "Implement the new authentication feature",
|
| 185 |
+
"imageUrl": "https://example.com/image.png",
|
| 186 |
+
"assignedUserId": "user123",
|
| 187 |
+
"status": "ASSIGNED",
|
| 188 |
+
"deadline": "2024-12-31T23:59:59",
|
| 189 |
+
"createAt": "2024-11-10T10:30:00",
|
| 190 |
+
"tags": ["backend", "security"]
|
| 191 |
+
}
|
| 192 |
+
]
|
| 193 |
+
```
|
| 194 |
+
|
| 195 |
+
---
|
| 196 |
+
|
| 197 |
+
### 6. Update Task
|
| 198 |
+
Update an existing task's information.
|
| 199 |
+
|
| 200 |
+
**Request:**
|
| 201 |
+
```http
|
| 202 |
+
PUT /api/tasks/65f9a1234567890abcdef123
|
| 203 |
+
Authorization: Bearer <jwt_token>
|
| 204 |
+
Content-Type: application/json
|
| 205 |
+
|
| 206 |
+
{
|
| 207 |
+
"title": "Implement new feature (Updated)",
|
| 208 |
+
"description": "Updated description",
|
| 209 |
+
"status": "ASSIGNED",
|
| 210 |
+
"deadline": "2024-12-25T23:59:59",
|
| 211 |
+
"tags": ["backend", "security", "updated"]
|
| 212 |
+
}
|
| 213 |
+
```
|
| 214 |
+
|
| 215 |
+
**Response (200 OK):**
|
| 216 |
+
```json
|
| 217 |
+
{
|
| 218 |
+
"id": "65f9a1234567890abcdef123",
|
| 219 |
+
"title": "Implement new feature (Updated)",
|
| 220 |
+
"description": "Updated description",
|
| 221 |
+
"imageUrl": "https://example.com/image.png",
|
| 222 |
+
"assignedUserId": "user123",
|
| 223 |
+
"status": "ASSIGNED",
|
| 224 |
+
"deadline": "2024-12-25T23:59:59",
|
| 225 |
+
"createAt": "2024-11-10T10:30:00",
|
| 226 |
+
"tags": ["backend", "security", "updated"]
|
| 227 |
+
}
|
| 228 |
+
```
|
| 229 |
+
|
| 230 |
+
---
|
| 231 |
+
|
| 232 |
+
### 7. Assign Task to User
|
| 233 |
+
Assign a task to a specific user.
|
| 234 |
+
|
| 235 |
+
**Request:**
|
| 236 |
+
```http
|
| 237 |
+
PUT /api/tasks/65f9a1234567890abcdef123/user/user456/assigned
|
| 238 |
+
Authorization: Bearer <jwt_token>
|
| 239 |
+
```
|
| 240 |
+
|
| 241 |
+
**Response (200 OK):**
|
| 242 |
+
```json
|
| 243 |
+
{
|
| 244 |
+
"id": "65f9a1234567890abcdef123",
|
| 245 |
+
"title": "Implement new feature",
|
| 246 |
+
"description": "Implement the new authentication feature",
|
| 247 |
+
"imageUrl": "https://example.com/image.png",
|
| 248 |
+
"assignedUserId": "user456",
|
| 249 |
+
"status": "ASSIGNED",
|
| 250 |
+
"deadline": "2024-12-31T23:59:59",
|
| 251 |
+
"createAt": "2024-11-10T10:30:00",
|
| 252 |
+
"tags": ["backend", "security"]
|
| 253 |
+
}
|
| 254 |
+
```
|
| 255 |
+
|
| 256 |
+
---
|
| 257 |
+
|
| 258 |
+
### 8. Complete Task
|
| 259 |
+
Mark a task as completed.
|
| 260 |
+
|
| 261 |
+
**Request:**
|
| 262 |
+
```http
|
| 263 |
+
PUT /api/tasks/65f9a1234567890abcdef123/complete
|
| 264 |
+
Authorization: Bearer <jwt_token>
|
| 265 |
+
```
|
| 266 |
+
|
| 267 |
+
**Response (200 OK):**
|
| 268 |
+
```json
|
| 269 |
+
{
|
| 270 |
+
"id": "65f9a1234567890abcdef123",
|
| 271 |
+
"title": "Implement new feature",
|
| 272 |
+
"description": "Implement the new authentication feature",
|
| 273 |
+
"imageUrl": "https://example.com/image.png",
|
| 274 |
+
"assignedUserId": "user123",
|
| 275 |
+
"status": "DONE",
|
| 276 |
+
"deadline": "2024-12-31T23:59:59",
|
| 277 |
+
"createAt": "2024-11-10T10:30:00",
|
| 278 |
+
"tags": ["backend", "security"]
|
| 279 |
+
}
|
| 280 |
+
```
|
| 281 |
+
|
| 282 |
+
---
|
| 283 |
+
|
| 284 |
+
### 9. Delete Task
|
| 285 |
+
Delete a task by ID.
|
| 286 |
+
|
| 287 |
+
**Request:**
|
| 288 |
+
```http
|
| 289 |
+
DELETE /api/tasks/65f9a1234567890abcdef123
|
| 290 |
+
Authorization: Bearer <jwt_token>
|
| 291 |
+
```
|
| 292 |
+
|
| 293 |
+
**Response (204 NO CONTENT):**
|
| 294 |
+
```
|
| 295 |
+
(No body returned)
|
| 296 |
+
```
|
| 297 |
+
|
| 298 |
+
---
|
| 299 |
+
|
| 300 |
+
## Task Status Flow
|
| 301 |
+
|
| 302 |
+
```
|
| 303 |
+
PENDING → ASSIGNED → DONE
|
| 304 |
+
```
|
| 305 |
+
|
| 306 |
+
1. **PENDING**: Task created by admin, not assigned to anyone
|
| 307 |
+
2. **ASSIGNED**: Task assigned to a user
|
| 308 |
+
3. **DONE**: Task marked as completed
|
| 309 |
+
|
| 310 |
+
---
|
| 311 |
+
|
| 312 |
+
## Common Error Responses
|
| 313 |
+
|
| 314 |
+
### 400 Bad Request
|
| 315 |
+
```json
|
| 316 |
+
{
|
| 317 |
+
"timestamp": "2024-11-10T10:30:00",
|
| 318 |
+
"message": "Invalid request parameters",
|
| 319 |
+
"status": 400,
|
| 320 |
+
"error": "Bad Request"
|
| 321 |
+
}
|
| 322 |
+
```
|
| 323 |
+
|
| 324 |
+
### 401 Unauthorized
|
| 325 |
+
```json
|
| 326 |
+
{
|
| 327 |
+
"timestamp": "2024-11-10T10:30:00",
|
| 328 |
+
"message": "JWT required...",
|
| 329 |
+
"status": 401,
|
| 330 |
+
"error": "Unauthorized"
|
| 331 |
+
}
|
| 332 |
+
```
|
| 333 |
+
|
| 334 |
+
### 403 Forbidden
|
| 335 |
+
```json
|
| 336 |
+
{
|
| 337 |
+
"timestamp": "2024-11-10T10:30:00",
|
| 338 |
+
"message": "Only admin can create tasks",
|
| 339 |
+
"status": 403,
|
| 340 |
+
"error": "Forbidden"
|
| 341 |
+
}
|
| 342 |
+
```
|
| 343 |
+
|
| 344 |
+
### 404 Not Found
|
| 345 |
+
```json
|
| 346 |
+
{
|
| 347 |
+
"timestamp": "2024-11-10T10:30:00",
|
| 348 |
+
"message": "Task not found with id: 65f9a1234567890abcdef123",
|
| 349 |
+
"status": 404,
|
| 350 |
+
"error": "Task Not Found"
|
| 351 |
+
}
|
| 352 |
+
```
|
| 353 |
+
|
| 354 |
+
### 500 Internal Server Error
|
| 355 |
+
```json
|
| 356 |
+
{
|
| 357 |
+
"timestamp": "2024-11-10T10:30:00",
|
| 358 |
+
"message": "Internal server error",
|
| 359 |
+
"status": 500,
|
| 360 |
+
"error": "Internal Server Error"
|
| 361 |
+
}
|
| 362 |
+
```
|
| 363 |
+
|
| 364 |
+
---
|
| 365 |
+
|
| 366 |
+
## Testing with cURL
|
| 367 |
+
|
| 368 |
+
### Create Task (Admin)
|
| 369 |
+
```bash
|
| 370 |
+
curl -X POST http://localhost:8082/api/tasks \
|
| 371 |
+
-H "Authorization: Bearer YOUR_JWT_TOKEN" \
|
| 372 |
+
-H "Content-Type: application/json" \
|
| 373 |
+
-d '{
|
| 374 |
+
"title": "Test Task",
|
| 375 |
+
"description": "This is a test task",
|
| 376 |
+
"deadline": "2024-12-31T23:59:59",
|
| 377 |
+
"tags": ["test"]
|
| 378 |
+
}'
|
| 379 |
+
```
|
| 380 |
+
|
| 381 |
+
### Get All Tasks
|
| 382 |
+
```bash
|
| 383 |
+
curl -X GET "http://localhost:8082/api/tasks?status=PENDING" \
|
| 384 |
+
-H "Authorization: Bearer YOUR_JWT_TOKEN"
|
| 385 |
+
```
|
| 386 |
+
|
| 387 |
+
### Get Task by ID
|
| 388 |
+
```bash
|
| 389 |
+
curl -X GET http://localhost:8082/api/tasks/TASK_ID \
|
| 390 |
+
-H "Authorization: Bearer YOUR_JWT_TOKEN"
|
| 391 |
+
```
|
| 392 |
+
|
| 393 |
+
### Update Task
|
| 394 |
+
```bash
|
| 395 |
+
curl -X PUT http://localhost:8082/api/tasks/TASK_ID \
|
| 396 |
+
-H "Authorization: Bearer YOUR_JWT_TOKEN" \
|
| 397 |
+
-H "Content-Type: application/json" \
|
| 398 |
+
-d '{
|
| 399 |
+
"title": "Updated Task Title",
|
| 400 |
+
"status": "ASSIGNED"
|
| 401 |
+
}'
|
| 402 |
+
```
|
| 403 |
+
|
| 404 |
+
### Complete Task
|
| 405 |
+
```bash
|
| 406 |
+
curl -X PUT http://localhost:8082/api/tasks/TASK_ID/complete \
|
| 407 |
+
-H "Authorization: Bearer YOUR_JWT_TOKEN"
|
| 408 |
+
```
|
| 409 |
+
|
| 410 |
+
### Delete Task
|
| 411 |
+
```bash
|
| 412 |
+
curl -X DELETE http://localhost:8082/api/tasks/TASK_ID \
|
| 413 |
+
-H "Authorization: Bearer YOUR_JWT_TOKEN"
|
| 414 |
+
```
|
| 415 |
+
|
| 416 |
+
---
|
| 417 |
+
|
| 418 |
+
## Notes
|
| 419 |
+
|
| 420 |
+
- All timestamps are in ISO 8601 format
|
| 421 |
+
- Task IDs are MongoDB ObjectIds (24-character hexadecimal strings)
|
| 422 |
+
- JWT tokens must be obtained from the User Service authentication endpoint
|
| 423 |
+
- Only admin users can create tasks
|
| 424 |
+
- Tasks can be in one of three states: PENDING, ASSIGNED, or DONE
|
| 425 |
+
- Sorting can be applied to either deadline or creation date, but not both simultaneously
|
TaskService/CHANGELOG.md
ADDED
|
@@ -0,0 +1,94 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Changelog
|
| 2 |
+
|
| 3 |
+
All notable changes and improvements to the Task Service are documented in this file.
|
| 4 |
+
|
| 5 |
+
## [1.0.0] - 2024-11-10
|
| 6 |
+
|
| 7 |
+
### Added
|
| 8 |
+
- Comprehensive JavaDoc comments for all classes, methods, and fields
|
| 9 |
+
- Global exception handler (`GlobalExceptionHandler`) for centralized error handling
|
| 10 |
+
- Custom exception (`TaskNotFoundException`) for task not found scenarios
|
| 11 |
+
- Detailed README.md with complete service documentation
|
| 12 |
+
- Example configuration file (`application.properties.example`) with detailed comments
|
| 13 |
+
- Enhanced Docker configuration with better labels and working directory
|
| 14 |
+
- Improved code comments and documentation throughout
|
| 15 |
+
|
| 16 |
+
### Fixed
|
| 17 |
+
- **TaskServiceImplementation.java**:
|
| 18 |
+
- Fixed `getAllTasks()` method - was returning null, now properly implements filtering and sorting
|
| 19 |
+
- Fixed `assignedToUser()` method - was incorrectly setting status to DONE instead of ASSIGNED
|
| 20 |
+
- Removed duplicate `assignedUsersTask()` method with inconsistent signatures
|
| 21 |
+
- Fixed `getTaskById()` - now properly throws exception instead of returning null
|
| 22 |
+
- Added proper null handling in sorting with `Comparator.nullsLast()`
|
| 23 |
+
- Added support for both "asc" and "desc" sorting directions
|
| 24 |
+
- Added tags update in `updateTask()` method
|
| 25 |
+
|
| 26 |
+
- **TaskRepository.java**:
|
| 27 |
+
- Cleaned up unnecessary method declarations (removed redundant `deleteById` and `getTaskById`)
|
| 28 |
+
- MongoRepository already provides these methods by default
|
| 29 |
+
- Added comprehensive JavaDoc
|
| 30 |
+
|
| 31 |
+
- **TaskController.java**:
|
| 32 |
+
- Fixed `completeTask()` - changed response status from NO_CONTENT to OK (should return task)
|
| 33 |
+
- Fixed `getTaskById()` - removed unnecessary null check (service now throws exception)
|
| 34 |
+
- Removed unused commented code
|
| 35 |
+
- Made fields final for better immutability
|
| 36 |
+
- Enhanced error handling consistency
|
| 37 |
+
|
| 38 |
+
- **HomeController.java**:
|
| 39 |
+
- Removed unused import (`UserService`)
|
| 40 |
+
- Fixed method naming inconsistency (method name matched class name)
|
| 41 |
+
- Cleaned up unnecessary whitespace
|
| 42 |
+
|
| 43 |
+
### Changed
|
| 44 |
+
- Improved consistency in exception handling across all endpoints
|
| 45 |
+
- Enhanced method documentation with detailed parameter and return descriptions
|
| 46 |
+
- Standardized code formatting and style
|
| 47 |
+
- Improved variable naming (e.g., `existingTasks` → `existingTask`)
|
| 48 |
+
- Enhanced test documentation
|
| 49 |
+
|
| 50 |
+
### Documentation
|
| 51 |
+
- Created comprehensive README.md covering:
|
| 52 |
+
- Service overview and purpose
|
| 53 |
+
- Architecture and technology stack
|
| 54 |
+
- Database schema
|
| 55 |
+
- Complete API documentation with examples
|
| 56 |
+
- Configuration guide
|
| 57 |
+
- Multiple deployment methods (Gradle, JAR, Docker, Docker Compose)
|
| 58 |
+
- Integration details with other services
|
| 59 |
+
- Troubleshooting guide
|
| 60 |
+
- Security considerations
|
| 61 |
+
- Performance tips
|
| 62 |
+
- Future enhancement ideas
|
| 63 |
+
|
| 64 |
+
- Added detailed configuration documentation:
|
| 65 |
+
- Server configuration
|
| 66 |
+
- MongoDB setup
|
| 67 |
+
- Eureka integration
|
| 68 |
+
- Zipkin tracing
|
| 69 |
+
- Feign client configuration
|
| 70 |
+
- Logging options
|
| 71 |
+
- Actuator endpoints
|
| 72 |
+
|
| 73 |
+
### Technical Improvements
|
| 74 |
+
- Better separation of concerns in service layer
|
| 75 |
+
- Improved error messages for debugging
|
| 76 |
+
- Enhanced logging readiness (commented examples provided)
|
| 77 |
+
- Docker-ready with proper configuration overrides
|
| 78 |
+
- Production-ready exception handling
|
| 79 |
+
- Consistent HTTP status code usage
|
| 80 |
+
|
| 81 |
+
### Code Quality
|
| 82 |
+
- Added comprehensive JavaDoc (100% coverage)
|
| 83 |
+
- Removed code duplication
|
| 84 |
+
- Fixed potential NPE issues
|
| 85 |
+
- Improved code readability
|
| 86 |
+
- Better method organization
|
| 87 |
+
- Consistent coding style
|
| 88 |
+
|
| 89 |
+
## Future Enhancements
|
| 90 |
+
See README.md for planned features and improvements.
|
| 91 |
+
|
| 92 |
+
---
|
| 93 |
+
|
| 94 |
+
**Note**: This changelog reflects the refactoring and improvement session on November 10, 2024.
|
TaskService/Dockerfile
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
FROM eclipse-temurin:17-jre-alpine
|
| 2 |
+
|
| 3 |
+
LABEL maintainer="garvitpathak27"
|
| 4 |
+
LABEL description="Task Management Service - Microservice for managing tasks"
|
| 5 |
+
LABEL version="1.0"
|
| 6 |
+
|
| 7 |
+
WORKDIR /app
|
| 8 |
+
|
| 9 |
+
# Install curl for Docker health checks
|
| 10 |
+
RUN apk add --no-cache curl
|
| 11 |
+
|
| 12 |
+
COPY build/libs/task-service.jar app.jar
|
| 13 |
+
|
| 14 |
+
EXPOSE 8082
|
| 15 |
+
|
| 16 |
+
ENTRYPOINT ["java", "-jar", "/app/app.jar"]
|