diff --git a/src/main/bin/wrapper.log b/src/main/bin/wrapper.log deleted file mode 100644 index f45ee9531..000000000 --- a/src/main/bin/wrapper.log +++ /dev/null @@ -1,221 +0,0 @@ -FATAL | wrapper | 2017/11/15 11:19:39 | Unable to open configuration file: /Users/jeubank/workspace/overture-stack/ego/src/main/bin/../conf/wrapper.conf (No such file or directory) -FATAL | wrapper | 2017/11/15 11:19:39 | Current working directory: /Users/jeubank/workspace/overture-stack/ego/src/main/bin -WARN | wrapper | 2017/11/15 11:20:22 | Unable to write to the configured log directory: ../logs (No such file or directory) -WARN | wrapper | 2017/11/15 11:20:22 | The directory does not exist. -WARN | wrapper | 2017/11/15 11:20:22 | Unable to write to the configured log file: ../logs/wrapper.20171115.log (No such file or directory) -WARN | wrapper | 2017/11/15 11:20:22 | Falling back to the default file in the current working directory: wrapper.log -WARN | wrapper | 2017/11/15 11:20:22 | The version of the script (3.5.19) doesn't match the version of this Wrapper (3.5.21). This might cause some problems -STATUS | wrapper | 2017/11/15 11:20:22 | --> Wrapper Started as Daemon -STATUS | wrapper | 2017/11/15 11:20:22 | Java Service Wrapper Community Edition 64-bit 3.5.21 -STATUS | wrapper | 2017/11/15 11:20:22 | Copyright (C) 1999-2013 Tanuki Software, Ltd. All Rights Reserved. -STATUS | wrapper | 2017/11/15 11:20:22 | http://wrapper.tanukisoftware.com -STATUS | wrapper | 2017/11/15 11:20:22 | -STATUS | wrapper | 2017/11/15 11:20:22 | Launching a JVM... -INFO | jvm 1 | 2017/11/15 11:20:23 | WrapperManager: Initializing... -INFO | jvm 1 | 2017/11/15 11:20:23 | WrapperSimpleApp Error: Unable to locate the class org.springframework.boot.loader.JarLauncher : java.lang.ClassNotFoundException: org.springframework.boot.loader.JarLauncher -INFO | jvm 1 | 2017/11/15 11:20:23 | -INFO | jvm 1 | 2017/11/15 11:20:23 | WrapperSimpleApp Usage: -INFO | jvm 1 | 2017/11/15 11:20:23 | java org.tanukisoftware.wrapper.WrapperSimpleApp {app_class{/app_method}} [app_arguments] -INFO | jvm 1 | 2017/11/15 11:20:23 | -INFO | jvm 1 | 2017/11/15 11:20:23 | Where: -INFO | jvm 1 | 2017/11/15 11:20:23 | app_class: The fully qualified class name of the application to run. -INFO | jvm 1 | 2017/11/15 11:20:23 | app_arguments: The arguments that would normally be passed to the -INFO | jvm 1 | 2017/11/15 11:20:23 | application. -ERROR | wrapper | 2017/11/15 11:20:25 | JVM exited while loading the application. -STATUS | wrapper | 2017/11/15 11:20:29 | Launching a JVM... -INFO | jvm 2 | 2017/11/15 11:20:30 | WrapperManager: Initializing... -INFO | jvm 2 | 2017/11/15 11:20:30 | WrapperSimpleApp Error: Unable to locate the class org.springframework.boot.loader.JarLauncher : java.lang.ClassNotFoundException: org.springframework.boot.loader.JarLauncher -INFO | jvm 2 | 2017/11/15 11:20:30 | -INFO | jvm 2 | 2017/11/15 11:20:30 | WrapperSimpleApp Usage: -INFO | jvm 2 | 2017/11/15 11:20:30 | java org.tanukisoftware.wrapper.WrapperSimpleApp {app_class{/app_method}} [app_arguments] -INFO | jvm 2 | 2017/11/15 11:20:30 | -INFO | jvm 2 | 2017/11/15 11:20:30 | Where: -INFO | jvm 2 | 2017/11/15 11:20:30 | app_class: The fully qualified class name of the application to run. -INFO | jvm 2 | 2017/11/15 11:20:30 | app_arguments: The arguments that would normally be passed to the -INFO | jvm 2 | 2017/11/15 11:20:30 | application. -ERROR | wrapper | 2017/11/15 11:20:32 | JVM exited while loading the application. -STATUS | wrapper | 2017/11/15 11:20:36 | Launching a JVM... -INFO | jvm 3 | 2017/11/15 11:20:37 | WrapperManager: Initializing... -INFO | jvm 3 | 2017/11/15 11:20:37 | WrapperSimpleApp Error: Unable to locate the class org.springframework.boot.loader.JarLauncher : java.lang.ClassNotFoundException: org.springframework.boot.loader.JarLauncher -INFO | jvm 3 | 2017/11/15 11:20:37 | -INFO | jvm 3 | 2017/11/15 11:20:37 | WrapperSimpleApp Usage: -INFO | jvm 3 | 2017/11/15 11:20:37 | java org.tanukisoftware.wrapper.WrapperSimpleApp {app_class{/app_method}} [app_arguments] -INFO | jvm 3 | 2017/11/15 11:20:37 | -INFO | jvm 3 | 2017/11/15 11:20:37 | Where: -INFO | jvm 3 | 2017/11/15 11:20:37 | app_class: The fully qualified class name of the application to run. -INFO | jvm 3 | 2017/11/15 11:20:37 | app_arguments: The arguments that would normally be passed to the -INFO | jvm 3 | 2017/11/15 11:20:37 | application. -ERROR | wrapper | 2017/11/15 11:20:39 | JVM exited while loading the application. -STATUS | wrapper | 2017/11/15 11:20:44 | Launching a JVM... -INFO | jvm 4 | 2017/11/15 11:20:44 | WrapperManager: Initializing... -INFO | jvm 4 | 2017/11/15 11:20:44 | WrapperSimpleApp Error: Unable to locate the class org.springframework.boot.loader.JarLauncher : java.lang.ClassNotFoundException: org.springframework.boot.loader.JarLauncher -INFO | jvm 4 | 2017/11/15 11:20:44 | -INFO | jvm 4 | 2017/11/15 11:20:44 | WrapperSimpleApp Usage: -INFO | jvm 4 | 2017/11/15 11:20:44 | java org.tanukisoftware.wrapper.WrapperSimpleApp {app_class{/app_method}} [app_arguments] -INFO | jvm 4 | 2017/11/15 11:20:44 | -INFO | jvm 4 | 2017/11/15 11:20:44 | Where: -INFO | jvm 4 | 2017/11/15 11:20:44 | app_class: The fully qualified class name of the application to run. -INFO | jvm 4 | 2017/11/15 11:20:44 | app_arguments: The arguments that would normally be passed to the -INFO | jvm 4 | 2017/11/15 11:20:44 | application. -ERROR | wrapper | 2017/11/15 11:20:46 | JVM exited while loading the application. -STATUS | wrapper | 2017/11/15 11:20:51 | Launching a JVM... -INFO | jvm 5 | 2017/11/15 11:20:51 | WrapperManager: Initializing... -INFO | jvm 5 | 2017/11/15 11:20:51 | WrapperSimpleApp Error: Unable to locate the class org.springframework.boot.loader.JarLauncher : java.lang.ClassNotFoundException: org.springframework.boot.loader.JarLauncher -INFO | jvm 5 | 2017/11/15 11:20:51 | -INFO | jvm 5 | 2017/11/15 11:20:51 | WrapperSimpleApp Usage: -INFO | jvm 5 | 2017/11/15 11:20:51 | java org.tanukisoftware.wrapper.WrapperSimpleApp {app_class{/app_method}} [app_arguments] -INFO | jvm 5 | 2017/11/15 11:20:51 | -INFO | jvm 5 | 2017/11/15 11:20:51 | Where: -INFO | jvm 5 | 2017/11/15 11:20:51 | app_class: The fully qualified class name of the application to run. -INFO | jvm 5 | 2017/11/15 11:20:51 | app_arguments: The arguments that would normally be passed to the -INFO | jvm 5 | 2017/11/15 11:20:51 | application. -ERROR | wrapper | 2017/11/15 11:20:53 | JVM exited while loading the application. -FATAL | wrapper | 2017/11/15 11:20:53 | There were 5 failed launches in a row, each lasting less than 300 seconds. Giving up. -FATAL | wrapper | 2017/11/15 11:20:53 | There may be a configuration problem: please check the logs. -STATUS | wrapper | 2017/11/15 11:20:53 | <-- Wrapper Stopped -WARN | wrapper | 2017/11/15 11:21:01 | Unable to write to the configured log directory: ../logs (No such file or directory) -WARN | wrapper | 2017/11/15 11:21:01 | The directory does not exist. -WARN | wrapper | 2017/11/15 11:21:01 | Unable to write to the configured log file: ../logs/wrapper.20171115.log (No such file or directory) -WARN | wrapper | 2017/11/15 11:21:01 | Falling back to the default file in the current working directory: wrapper.log -WARN | wrapper | 2017/11/15 11:21:01 | The version of the script (3.5.19) doesn't match the version of this Wrapper (3.5.21). This might cause some problems -STATUS | wrapper | 2017/11/15 11:21:01 | --> Wrapper Started as Daemon -STATUS | wrapper | 2017/11/15 11:21:01 | Java Service Wrapper Community Edition 64-bit 3.5.21 -STATUS | wrapper | 2017/11/15 11:21:01 | Copyright (C) 1999-2013 Tanuki Software, Ltd. All Rights Reserved. -STATUS | wrapper | 2017/11/15 11:21:01 | http://wrapper.tanukisoftware.com -STATUS | wrapper | 2017/11/15 11:21:01 | -STATUS | wrapper | 2017/11/15 11:21:01 | Launching a JVM... -INFO | jvm 1 | 2017/11/15 11:21:02 | WrapperManager: Initializing... -INFO | jvm 1 | 2017/11/15 11:21:02 | WrapperSimpleApp Error: Unable to locate the class org.springframework.boot.loader.JarLauncher : java.lang.ClassNotFoundException: org.springframework.boot.loader.JarLauncher -INFO | jvm 1 | 2017/11/15 11:21:02 | -INFO | jvm 1 | 2017/11/15 11:21:02 | WrapperSimpleApp Usage: -INFO | jvm 1 | 2017/11/15 11:21:02 | java org.tanukisoftware.wrapper.WrapperSimpleApp {app_class{/app_method}} [app_arguments] -INFO | jvm 1 | 2017/11/15 11:21:02 | -INFO | jvm 1 | 2017/11/15 11:21:02 | Where: -INFO | jvm 1 | 2017/11/15 11:21:02 | app_class: The fully qualified class name of the application to run. -INFO | jvm 1 | 2017/11/15 11:21:02 | app_arguments: The arguments that would normally be passed to the -INFO | jvm 1 | 2017/11/15 11:21:02 | application. -ERROR | wrapper | 2017/11/15 11:21:04 | JVM exited while loading the application. -STATUS | wrapper | 2017/11/15 11:21:08 | Launching a JVM... -INFO | jvm 2 | 2017/11/15 11:21:09 | WrapperManager: Initializing... -INFO | jvm 2 | 2017/11/15 11:21:09 | WrapperSimpleApp Error: Unable to locate the class org.springframework.boot.loader.JarLauncher : java.lang.ClassNotFoundException: org.springframework.boot.loader.JarLauncher -INFO | jvm 2 | 2017/11/15 11:21:09 | -INFO | jvm 2 | 2017/11/15 11:21:09 | WrapperSimpleApp Usage: -INFO | jvm 2 | 2017/11/15 11:21:09 | java org.tanukisoftware.wrapper.WrapperSimpleApp {app_class{/app_method}} [app_arguments] -INFO | jvm 2 | 2017/11/15 11:21:09 | -INFO | jvm 2 | 2017/11/15 11:21:09 | Where: -INFO | jvm 2 | 2017/11/15 11:21:09 | app_class: The fully qualified class name of the application to run. -INFO | jvm 2 | 2017/11/15 11:21:09 | app_arguments: The arguments that would normally be passed to the -INFO | jvm 2 | 2017/11/15 11:21:09 | application. -ERROR | wrapper | 2017/11/15 11:21:11 | JVM exited while loading the application. -STATUS | wrapper | 2017/11/15 11:21:15 | Launching a JVM... -INFO | jvm 3 | 2017/11/15 11:21:16 | WrapperManager: Initializing... -INFO | jvm 3 | 2017/11/15 11:21:16 | WrapperSimpleApp Error: Unable to locate the class org.springframework.boot.loader.JarLauncher : java.lang.ClassNotFoundException: org.springframework.boot.loader.JarLauncher -INFO | jvm 3 | 2017/11/15 11:21:16 | -INFO | jvm 3 | 2017/11/15 11:21:16 | WrapperSimpleApp Usage: -INFO | jvm 3 | 2017/11/15 11:21:16 | java org.tanukisoftware.wrapper.WrapperSimpleApp {app_class{/app_method}} [app_arguments] -INFO | jvm 3 | 2017/11/15 11:21:16 | -INFO | jvm 3 | 2017/11/15 11:21:16 | Where: -INFO | jvm 3 | 2017/11/15 11:21:16 | app_class: The fully qualified class name of the application to run. -INFO | jvm 3 | 2017/11/15 11:21:16 | app_arguments: The arguments that would normally be passed to the -INFO | jvm 3 | 2017/11/15 11:21:16 | application. -ERROR | wrapper | 2017/11/15 11:21:18 | JVM exited while loading the application. -STATUS | wrapper | 2017/11/15 11:21:22 | Launching a JVM... -INFO | jvm 4 | 2017/11/15 11:21:23 | WrapperManager: Initializing... -INFO | jvm 4 | 2017/11/15 11:21:23 | WrapperSimpleApp Error: Unable to locate the class org.springframework.boot.loader.JarLauncher : java.lang.ClassNotFoundException: org.springframework.boot.loader.JarLauncher -INFO | jvm 4 | 2017/11/15 11:21:23 | -INFO | jvm 4 | 2017/11/15 11:21:23 | WrapperSimpleApp Usage: -INFO | jvm 4 | 2017/11/15 11:21:23 | java org.tanukisoftware.wrapper.WrapperSimpleApp {app_class{/app_method}} [app_arguments] -INFO | jvm 4 | 2017/11/15 11:21:23 | -INFO | jvm 4 | 2017/11/15 11:21:23 | Where: -INFO | jvm 4 | 2017/11/15 11:21:23 | app_class: The fully qualified class name of the application to run. -INFO | jvm 4 | 2017/11/15 11:21:23 | app_arguments: The arguments that would normally be passed to the -INFO | jvm 4 | 2017/11/15 11:21:23 | application. -ERROR | wrapper | 2017/11/15 11:21:25 | JVM exited while loading the application. -STATUS | wrapper | 2017/11/15 11:21:30 | Launching a JVM... -INFO | jvm 5 | 2017/11/15 11:21:30 | WrapperManager: Initializing... -INFO | jvm 5 | 2017/11/15 11:21:30 | WrapperSimpleApp Error: Unable to locate the class org.springframework.boot.loader.JarLauncher : java.lang.ClassNotFoundException: org.springframework.boot.loader.JarLauncher -INFO | jvm 5 | 2017/11/15 11:21:30 | -INFO | jvm 5 | 2017/11/15 11:21:30 | WrapperSimpleApp Usage: -INFO | jvm 5 | 2017/11/15 11:21:30 | java org.tanukisoftware.wrapper.WrapperSimpleApp {app_class{/app_method}} [app_arguments] -INFO | jvm 5 | 2017/11/15 11:21:30 | -INFO | jvm 5 | 2017/11/15 11:21:30 | Where: -INFO | jvm 5 | 2017/11/15 11:21:30 | app_class: The fully qualified class name of the application to run. -INFO | jvm 5 | 2017/11/15 11:21:30 | app_arguments: The arguments that would normally be passed to the -INFO | jvm 5 | 2017/11/15 11:21:30 | application. -ERROR | wrapper | 2017/11/15 11:21:32 | JVM exited while loading the application. -FATAL | wrapper | 2017/11/15 11:21:32 | There were 5 failed launches in a row, each lasting less than 300 seconds. Giving up. -FATAL | wrapper | 2017/11/15 11:21:32 | There may be a configuration problem: please check the logs. -STATUS | wrapper | 2017/11/15 11:21:32 | <-- Wrapper Stopped -WARN | wrapper | 2017/11/15 11:21:42 | Unable to write to the configured log directory: ../logs (No such file or directory) -WARN | wrapper | 2017/11/15 11:21:42 | The directory does not exist. -WARN | wrapper | 2017/11/15 11:21:42 | Unable to write to the configured log file: ../logs/wrapper.20171115.log (No such file or directory) -WARN | wrapper | 2017/11/15 11:21:42 | Falling back to the default file in the current working directory: wrapper.log -WARN | wrapper | 2017/11/15 11:21:42 | The version of the script (3.5.19) doesn't match the version of this Wrapper (3.5.21). This might cause some problems -STATUS | wrapper | 2017/11/15 11:21:42 | --> Wrapper Started as Daemon -STATUS | wrapper | 2017/11/15 11:21:42 | Java Service Wrapper Community Edition 64-bit 3.5.21 -STATUS | wrapper | 2017/11/15 11:21:42 | Copyright (C) 1999-2013 Tanuki Software, Ltd. All Rights Reserved. -STATUS | wrapper | 2017/11/15 11:21:42 | http://wrapper.tanukisoftware.com -STATUS | wrapper | 2017/11/15 11:21:42 | -STATUS | wrapper | 2017/11/15 11:21:42 | Launching a JVM... -INFO | jvm 1 | 2017/11/15 11:21:42 | WrapperManager: Initializing... -INFO | jvm 1 | 2017/11/15 11:21:42 | WrapperSimpleApp Error: Unable to locate the class org.springframework.boot.loader.JarLauncher : java.lang.ClassNotFoundException: org.springframework.boot.loader.JarLauncher -INFO | jvm 1 | 2017/11/15 11:21:42 | -INFO | jvm 1 | 2017/11/15 11:21:42 | WrapperSimpleApp Usage: -INFO | jvm 1 | 2017/11/15 11:21:42 | java org.tanukisoftware.wrapper.WrapperSimpleApp {app_class{/app_method}} [app_arguments] -INFO | jvm 1 | 2017/11/15 11:21:42 | -INFO | jvm 1 | 2017/11/15 11:21:42 | Where: -INFO | jvm 1 | 2017/11/15 11:21:42 | app_class: The fully qualified class name of the application to run. -INFO | jvm 1 | 2017/11/15 11:21:42 | app_arguments: The arguments that would normally be passed to the -INFO | jvm 1 | 2017/11/15 11:21:42 | application. -ERROR | wrapper | 2017/11/15 11:21:44 | JVM exited while loading the application. -STATUS | wrapper | 2017/11/15 11:21:49 | Launching a JVM... -INFO | jvm 2 | 2017/11/15 11:21:49 | WrapperManager: Initializing... -INFO | jvm 2 | 2017/11/15 11:21:49 | WrapperSimpleApp Error: Unable to locate the class org.springframework.boot.loader.JarLauncher : java.lang.ClassNotFoundException: org.springframework.boot.loader.JarLauncher -INFO | jvm 2 | 2017/11/15 11:21:49 | -INFO | jvm 2 | 2017/11/15 11:21:49 | WrapperSimpleApp Usage: -INFO | jvm 2 | 2017/11/15 11:21:49 | java org.tanukisoftware.wrapper.WrapperSimpleApp {app_class{/app_method}} [app_arguments] -INFO | jvm 2 | 2017/11/15 11:21:49 | -INFO | jvm 2 | 2017/11/15 11:21:49 | Where: -INFO | jvm 2 | 2017/11/15 11:21:49 | app_class: The fully qualified class name of the application to run. -INFO | jvm 2 | 2017/11/15 11:21:49 | app_arguments: The arguments that would normally be passed to the -INFO | jvm 2 | 2017/11/15 11:21:49 | application. -ERROR | wrapper | 2017/11/15 11:21:52 | JVM exited while loading the application. -STATUS | wrapper | 2017/11/15 11:21:56 | Launching a JVM... -INFO | jvm 3 | 2017/11/15 11:21:56 | WrapperManager: Initializing... -INFO | jvm 3 | 2017/11/15 11:21:56 | WrapperSimpleApp Error: Unable to locate the class org.springframework.boot.loader.JarLauncher : java.lang.ClassNotFoundException: org.springframework.boot.loader.JarLauncher -INFO | jvm 3 | 2017/11/15 11:21:56 | -INFO | jvm 3 | 2017/11/15 11:21:56 | WrapperSimpleApp Usage: -INFO | jvm 3 | 2017/11/15 11:21:56 | java org.tanukisoftware.wrapper.WrapperSimpleApp {app_class{/app_method}} [app_arguments] -INFO | jvm 3 | 2017/11/15 11:21:56 | -INFO | jvm 3 | 2017/11/15 11:21:56 | Where: -INFO | jvm 3 | 2017/11/15 11:21:56 | app_class: The fully qualified class name of the application to run. -INFO | jvm 3 | 2017/11/15 11:21:56 | app_arguments: The arguments that would normally be passed to the -INFO | jvm 3 | 2017/11/15 11:21:56 | application. -ERROR | wrapper | 2017/11/15 11:21:59 | JVM exited while loading the application. -STATUS | wrapper | 2017/11/15 11:22:03 | Launching a JVM... -INFO | jvm 4 | 2017/11/15 11:22:03 | WrapperManager: Initializing... -INFO | jvm 4 | 2017/11/15 11:22:04 | WrapperSimpleApp Error: Unable to locate the class org.springframework.boot.loader.JarLauncher : java.lang.ClassNotFoundException: org.springframework.boot.loader.JarLauncher -INFO | jvm 4 | 2017/11/15 11:22:04 | -INFO | jvm 4 | 2017/11/15 11:22:04 | WrapperSimpleApp Usage: -INFO | jvm 4 | 2017/11/15 11:22:04 | java org.tanukisoftware.wrapper.WrapperSimpleApp {app_class{/app_method}} [app_arguments] -INFO | jvm 4 | 2017/11/15 11:22:04 | -INFO | jvm 4 | 2017/11/15 11:22:04 | Where: -INFO | jvm 4 | 2017/11/15 11:22:04 | app_class: The fully qualified class name of the application to run. -INFO | jvm 4 | 2017/11/15 11:22:04 | app_arguments: The arguments that would normally be passed to the -INFO | jvm 4 | 2017/11/15 11:22:04 | application. -ERROR | wrapper | 2017/11/15 11:22:06 | JVM exited while loading the application. -STATUS | wrapper | 2017/11/15 11:22:10 | Launching a JVM... -INFO | jvm 5 | 2017/11/15 11:22:11 | WrapperManager: Initializing... -INFO | jvm 5 | 2017/11/15 11:22:11 | WrapperSimpleApp Error: Unable to locate the class org.springframework.boot.loader.JarLauncher : java.lang.ClassNotFoundException: org.springframework.boot.loader.JarLauncher -INFO | jvm 5 | 2017/11/15 11:22:11 | -INFO | jvm 5 | 2017/11/15 11:22:11 | WrapperSimpleApp Usage: -INFO | jvm 5 | 2017/11/15 11:22:11 | java org.tanukisoftware.wrapper.WrapperSimpleApp {app_class{/app_method}} [app_arguments] -INFO | jvm 5 | 2017/11/15 11:22:11 | -INFO | jvm 5 | 2017/11/15 11:22:11 | Where: -INFO | jvm 5 | 2017/11/15 11:22:11 | app_class: The fully qualified class name of the application to run. -INFO | jvm 5 | 2017/11/15 11:22:11 | app_arguments: The arguments that would normally be passed to the -INFO | jvm 5 | 2017/11/15 11:22:11 | application. -ERROR | wrapper | 2017/11/15 11:22:13 | JVM exited while loading the application. -FATAL | wrapper | 2017/11/15 11:22:13 | There were 5 failed launches in a row, each lasting less than 300 seconds. Giving up. -FATAL | wrapper | 2017/11/15 11:22:13 | There may be a configuration problem: please check the logs. -STATUS | wrapper | 2017/11/15 11:22:13 | <-- Wrapper Stopped diff --git a/src/main/java/bio/overture/ego/AuthorizationServiceMain.java b/src/main/java/bio/overture/ego/AuthorizationServiceMain.java index 1fbc9b94a..9ef972a81 100644 --- a/src/main/java/bio/overture/ego/AuthorizationServiceMain.java +++ b/src/main/java/bio/overture/ego/AuthorizationServiceMain.java @@ -18,8 +18,10 @@ import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.cache.annotation.EnableCaching; @SpringBootApplication +@EnableCaching public class AuthorizationServiceMain { public static void main(String[] args) { diff --git a/src/main/java/bio/overture/ego/controller/PassportController.java b/src/main/java/bio/overture/ego/controller/PassportController.java new file mode 100644 index 000000000..bb2a042bf --- /dev/null +++ b/src/main/java/bio/overture/ego/controller/PassportController.java @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2017. The Ontario Institute for Cancer Research. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package bio.overture.ego.controller; + +import static org.springframework.http.HttpStatus.*; +import static org.springframework.web.bind.annotation.RequestMethod.*; + +import bio.overture.ego.model.entity.VisaPermission; +import bio.overture.ego.service.PassportService; +import io.swagger.v3.oas.annotations.tags.Tag; +import java.util.List; +import lombok.NonNull; +import lombok.SneakyThrows; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.*; + +@Slf4j +@RestController +@RequestMapping("/passport") +@Tag(name = "Passport", description = "passport-controller") +public class PassportController { + + private final PassportService passportService; + + @Autowired + public PassportController(@NonNull PassportService passportService) { + this.passportService = passportService; + } + + @RequestMapping(method = POST, value = "/passport/token") + @ResponseStatus(value = OK) + @SneakyThrows + public @ResponseBody List getVisaPermissions(@RequestBody String authToken) { + return passportService.getPermissions(authToken); + } +} diff --git a/src/main/java/bio/overture/ego/model/dto/Ga4ghVisaV1.java b/src/main/java/bio/overture/ego/model/dto/Ga4ghVisaV1.java new file mode 100644 index 000000000..11c1bdc52 --- /dev/null +++ b/src/main/java/bio/overture/ego/model/dto/Ga4ghVisaV1.java @@ -0,0 +1,31 @@ +package bio.overture.ego.model.dto; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonProperty; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +@Data +@Builder +@AllArgsConstructor +@NoArgsConstructor +@JsonIgnoreProperties(ignoreUnknown = true) +public class Ga4ghVisaV1 { + + @JsonProperty("asserted") + private int asserted; + + @JsonProperty("by") + private String by; + + @JsonProperty("source") + private Object source; + + @JsonProperty("type") + private String type; + + @JsonProperty("value") + private String value; +} diff --git a/src/main/java/bio/overture/ego/model/dto/Passport.java b/src/main/java/bio/overture/ego/model/dto/Passport.java new file mode 100644 index 000000000..36ed9a561 --- /dev/null +++ b/src/main/java/bio/overture/ego/model/dto/Passport.java @@ -0,0 +1,35 @@ +package bio.overture.ego.model.dto; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonProperty; +import java.util.List; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +@Data +@Builder +@AllArgsConstructor +@NoArgsConstructor +@JsonIgnoreProperties(ignoreUnknown = true) +public class Passport { + + @JsonProperty("sub") + private String sub; + + @JsonProperty("iss") + private String iss; + + @JsonProperty("exp") + private long exp; + + @JsonProperty("iat") + private int iat; + + @JsonProperty("ga4gh_passport_v1") + private List ga4ghPassportV1; + + @JsonProperty("jti") + private String jti; +} diff --git a/src/main/java/bio/overture/ego/model/dto/PassportVisa.java b/src/main/java/bio/overture/ego/model/dto/PassportVisa.java new file mode 100644 index 000000000..3afe19857 --- /dev/null +++ b/src/main/java/bio/overture/ego/model/dto/PassportVisa.java @@ -0,0 +1,34 @@ +package bio.overture.ego.model.dto; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonProperty; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +@Data +@Builder +@AllArgsConstructor +@NoArgsConstructor +@JsonIgnoreProperties(ignoreUnknown = true) +public class PassportVisa { + + @JsonProperty("sub") + private String sub; + + @JsonProperty("ga4gh_visa_v1") + private Ga4ghVisaV1 ga4ghVisaV1; + + @JsonProperty("iss") + private String iss; + + @JsonProperty("exp") + private long exp; + + @JsonProperty("iat") + private int iat; + + @JsonProperty("jti") + private String jti; +} diff --git a/src/main/java/bio/overture/ego/service/PassportService.java b/src/main/java/bio/overture/ego/service/PassportService.java new file mode 100644 index 000000000..106e79b82 --- /dev/null +++ b/src/main/java/bio/overture/ego/service/PassportService.java @@ -0,0 +1,127 @@ +package bio.overture.ego.service; + +import bio.overture.ego.model.dto.Passport; +import bio.overture.ego.model.dto.PassportVisa; +import bio.overture.ego.model.entity.Visa; +import bio.overture.ego.model.entity.VisaPermission; +import bio.overture.ego.model.exceptions.InvalidTokenException; +import bio.overture.ego.utils.CacheUtil; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.ObjectMapper; +import io.jsonwebtoken.Claims; +import io.jsonwebtoken.Jwts; +import java.util.*; +import java.util.stream.Collectors; +import lombok.NonNull; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.codec.binary.Base64; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +@Slf4j +@Service +@Transactional +public class PassportService { + + /** Dependencies */ + @Autowired private VisaService visaService; + + @Autowired private VisaPermissionService visaPermissionService; + + @Autowired private CacheUtil cacheUtil; + + @Autowired + public PassportService( + @NonNull VisaPermissionService visaPermissionService, @NonNull VisaService visaService) { + this.visaService = visaService; + this.visaPermissionService = visaPermissionService; + } + + public List getPermissions(String authToken) throws JsonProcessingException { + // Validates passport auth token + if (!isValidPassport(authToken)) { + throw new InvalidTokenException("The passport token received from broker is invalid"); + } + // Parses passport JWT token + Passport parsedPassport = parsePassport(authToken); + // Fetches visas for parsed passport + List visas = getVisas(parsedPassport); + // Fetches visa permissions for extracted visas + List visaPermissions = getVisaPermissions(visas); + // removes deduplicates from visaPermissions + visaPermissions = deDupeVisaPermissions(visaPermissions); + return visaPermissions; + } + + // Validates passport token based on public key + private boolean isValidPassport(@NonNull String authToken) { + Claims claims; + try { + claims = + Jwts.parser() + .setSigningKey(cacheUtil.getPassportBrokerPublicKey()) + .parseClaimsJws(authToken) + .getBody(); + if (claims != null) { + return true; + } + } catch (Exception exception) { + throw new InvalidTokenException("The passport token received from broker is invalid"); + } + return false; + } + + // Extracts Visas from parsed passport object + private List getVisas(Passport passport) { + List visas = new ArrayList<>(); + passport.getGa4ghPassportV1().stream() + .forEach( + visaJwt -> { + try { + if (visaService.isValidVisa(visaJwt)) { + PassportVisa visa = visaService.parseVisa(visaJwt); + if (visa != null) { + visas.add(visa); + } + } + } catch (JsonProcessingException e) { + e.printStackTrace(); + } + }); + return visas; + } + + // Fetches Visa Permissions for extracted Visa list + private List getVisaPermissions(List visas) { + List visaPermissions = new ArrayList<>(); + visas.stream() + .distinct() + .forEach( + visa -> { + Visa visaEntity = new Visa(); + visaEntity.setId(UUID.fromString(visa.getJti())); + visaPermissions.addAll(visaPermissionService.getPermissionsForVisa(visaEntity)); + }); + return visaPermissions; + } + + // Parse Passport token to extract the passport body + public Passport parsePassport(@NonNull String passportJwtToken) throws JsonProcessingException { + String[] split_string = passportJwtToken.split("\\."); + String base64EncodedHeader = split_string[0]; + String base64EncodedBody = split_string[1]; + String base64EncodedSignature = split_string[2]; + Base64 base64Url = new Base64(true); + String header = new String(base64Url.decode(base64EncodedHeader)); + String body = new String(base64Url.decode(base64EncodedBody)); + return new ObjectMapper().readValue(body, Passport.class); + } + + // Removes duplicates from the VisaPermissons List + private List deDupeVisaPermissions(List visaPermissions) { + Set permissionsSet = new HashSet(); + permissionsSet.addAll(visaPermissions); + return permissionsSet.stream().collect(Collectors.toList()); + } +} diff --git a/src/main/java/bio/overture/ego/service/VisaPermissionService.java b/src/main/java/bio/overture/ego/service/VisaPermissionService.java index 6057ce5bc..b381a9e97 100644 --- a/src/main/java/bio/overture/ego/service/VisaPermissionService.java +++ b/src/main/java/bio/overture/ego/service/VisaPermissionService.java @@ -1,116 +1,120 @@ -package bio.overture.ego.service; - -import static java.lang.String.format; -import static org.mapstruct.factory.Mappers.getMapper; - -import bio.overture.ego.event.token.ApiKeyEventsPublisher; -import bio.overture.ego.model.dto.VisaPermissionRequest; -import bio.overture.ego.model.entity.VisaPermission; -import bio.overture.ego.model.exceptions.NotFoundException; -import bio.overture.ego.repository.VisaPermissionRepository; -import jakarta.validation.constraints.NotNull; -import java.util.List; -import java.util.UUID; -import lombok.NonNull; -import lombok.extern.slf4j.Slf4j; -import lombok.val; -import org.mapstruct.Mapper; -import org.mapstruct.MappingTarget; -import org.mapstruct.NullValueCheckStrategy; -import org.mapstruct.ReportingPolicy; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Service; -import org.springframework.transaction.annotation.Transactional; - -@Slf4j -@Service -@Transactional -public class VisaPermissionService extends AbstractNamedService { - - /** Dependencies */ - @Autowired private VisaService visaService; - - @Autowired private PolicyService policyService; - - @Autowired private VisaPermissionRepository visaPermissionRepository; - private final ApiKeyEventsPublisher apiKeyEventsPublisher; - - private static final VisaPermissionService.VisaPermissionConverter VISA_PERMISSION_CONVERTER = - getMapper(VisaPermissionService.VisaPermissionConverter.class); - - @Autowired - public VisaPermissionService( - @NonNull VisaPermissionRepository visaPermissionRepository, - @NonNull VisaService visaService, - @NonNull ApiKeyEventsPublisher apiKeyEventsPublisher) { - super(VisaPermission.class, visaPermissionRepository); - this.visaPermissionRepository = visaPermissionRepository; - this.visaService = visaService; - this.apiKeyEventsPublisher = apiKeyEventsPublisher; - } - - public List getPermissionsByVisaId(@NonNull UUID visaId) { - val result = (List) visaPermissionRepository.findByVisa_Id(visaId); - if (result.isEmpty()) { - throw new NotFoundException(format("No VisaPermissions exists with visaId '%s'", visaId)); - } - return result; - } - - public List getPermissionsByPolicyId(@NonNull UUID policyId) { - val result = (List) visaPermissionRepository.findByPolicy_Id(policyId); - if (result.isEmpty()) { - throw new NotFoundException(format("No VisaPermissions exists with policyId '%s'", policyId)); - } - return result; - } - - public VisaPermission createOrUpdatePermissions( - @NonNull VisaPermissionRequest visaPermissionRequest) { - VisaPermission visaPermission = null; - List visaPermissionEntities = - visaPermissionRepository.findByPolicyIdAndVisaId( - visaPermissionRequest.getPolicyId(), visaPermissionRequest.getVisaId()); - if (visaPermissionEntities.isEmpty()) { - visaPermission = new VisaPermission(); - visaPermission.setVisa(visaService.getById(visaPermissionRequest.getVisaId())); - visaPermission.setPolicy(policyService.getById(visaPermissionRequest.getPolicyId())); - visaPermission.setAccessLevel(visaPermissionRequest.getAccessLevel()); - return visaPermissionRepository.save(visaPermission); - } else { - VISA_PERMISSION_CONVERTER.updateVisaPermission( - visaPermissionRequest, visaPermissionEntities.get(0)); - return visaPermissionRepository.save(visaPermissionEntities.get(0)); - } - } - - public void removePermission(@NonNull UUID policyId, @NotNull UUID visaId) { - VisaPermission visaPermission = null; - List visaPermissionEntities = - visaPermissionRepository.findByPolicyIdAndVisaId(policyId, visaId); - if (!visaPermissionEntities.isEmpty()) { - visaPermissionRepository.deleteById(visaPermissionEntities.get(0).getId()); - } else { - throw new NotFoundException( - format("No VisaPermissions exists with policyId '%s' and visaId '%s'", policyId, visaId)); - } - } - - @Override - public VisaPermission getById(@NonNull UUID uuid) { - return super.getById(uuid); - } - - @Override - public VisaPermission getWithRelationships(UUID uuid) { - return null; - } - - @Mapper( - nullValueCheckStrategy = NullValueCheckStrategy.ALWAYS, - unmappedTargetPolicy = ReportingPolicy.WARN) - public abstract static class VisaPermissionConverter { - public abstract void updateVisaPermission( - VisaPermissionRequest visaPermissionRequest, @MappingTarget VisaPermission visaPermission); - } -} +package bio.overture.ego.service; + +import static java.lang.String.format; +import static org.mapstruct.factory.Mappers.getMapper; + +import bio.overture.ego.event.token.ApiKeyEventsPublisher; +import bio.overture.ego.model.dto.VisaPermissionRequest; +import bio.overture.ego.model.entity.Visa; +import bio.overture.ego.model.entity.VisaPermission; +import bio.overture.ego.model.exceptions.NotFoundException; +import bio.overture.ego.repository.VisaPermissionRepository; +import jakarta.validation.constraints.NotNull; +import java.util.List; +import java.util.UUID; +import lombok.NonNull; +import lombok.extern.slf4j.Slf4j; +import lombok.val; +import org.mapstruct.Mapper; +import org.mapstruct.MappingTarget; +import org.mapstruct.NullValueCheckStrategy; +import org.mapstruct.ReportingPolicy; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +@Slf4j +@Service +@Transactional +public class VisaPermissionService extends AbstractNamedService { + /** Dependencies */ + @Autowired private VisaService visaService; + + @Autowired private PolicyService policyService; + @Autowired private VisaPermissionRepository visaPermissionRepository; + private final ApiKeyEventsPublisher apiKeyEventsPublisher; + private static final VisaPermissionConverter VISA_PERMISSION_CONVERTER = + getMapper(VisaPermissionConverter.class); + + @Autowired + public VisaPermissionService( + @NonNull VisaPermissionRepository visaPermissionRepository, + @NonNull VisaService visaService, + @NonNull ApiKeyEventsPublisher apiKeyEventsPublisher) { + super(VisaPermission.class, visaPermissionRepository); + this.visaPermissionRepository = visaPermissionRepository; + this.visaService = visaService; + this.apiKeyEventsPublisher = apiKeyEventsPublisher; + } + + public List getPermissionsByVisaId(@NonNull UUID visaId) { + val result = (List) visaPermissionRepository.findByVisa_Id(visaId); + if (result.isEmpty()) { + throw new NotFoundException(format("No VisaPermissions exists with visaId '%s'", visaId)); + } + return result; + } + + public List getPermissionsByPolicyId(@NonNull UUID policyId) { + val result = (List) visaPermissionRepository.findByPolicy_Id(policyId); + if (result.isEmpty()) { + throw new NotFoundException(format("No VisaPermissions exists with policyId '%s'", policyId)); + } + return result; + } + + public VisaPermission createOrUpdatePermissions( + @NonNull VisaPermissionRequest visaPermissionRequest) { + VisaPermission visaPermission = null; + List visaPermissionEntities = + visaPermissionRepository.findByPolicyIdAndVisaId( + visaPermissionRequest.getPolicyId(), visaPermissionRequest.getVisaId()); + if (visaPermissionEntities.isEmpty()) { + visaPermission = new VisaPermission(); + visaPermission.setVisa(visaService.getById(visaPermissionRequest.getVisaId())); + visaPermission.setPolicy(policyService.getById(visaPermissionRequest.getPolicyId())); + visaPermission.setAccessLevel(visaPermissionRequest.getAccessLevel()); + return visaPermissionRepository.save(visaPermission); + } else { + VISA_PERMISSION_CONVERTER.updateVisaPermission( + visaPermissionRequest, visaPermissionEntities.get(0)); + return visaPermissionRepository.save(visaPermissionEntities.get(0)); + } + } + + public void removePermission(@NonNull UUID policyId, @NotNull UUID visaId) { + VisaPermission visaPermission = null; + List visaPermissionEntities = + visaPermissionRepository.findByPolicyIdAndVisaId(policyId, visaId); + if (!visaPermissionEntities.isEmpty()) { + visaPermissionRepository.deleteById(visaPermissionEntities.get(0).getId()); + } else { + throw new NotFoundException( + format("No VisaPermissions exists with policyId '%s' and visaId '%s'", policyId, visaId)); + } + } + + // Fetches visa permissions for given visa request + public List getPermissionsForVisa(@NonNull Visa visa) { + val result = (List) visaPermissionRepository.findByVisa_Id(visa.getId()); + return result; + } + + @Override + public VisaPermission getById(@NonNull UUID uuid) { + return super.getById(uuid); + } + + @Override + public VisaPermission getWithRelationships(UUID uuid) { + return null; + } + + @Mapper( + nullValueCheckStrategy = NullValueCheckStrategy.ALWAYS, + unmappedTargetPolicy = ReportingPolicy.WARN) + public abstract static class VisaPermissionConverter { + public abstract void updateVisaPermission( + VisaPermissionRequest visaPermissionRequest, @MappingTarget VisaPermission visaPermission); + } +} diff --git a/src/main/java/bio/overture/ego/service/VisaService.java b/src/main/java/bio/overture/ego/service/VisaService.java index 9e65f8db1..c7e651105 100644 --- a/src/main/java/bio/overture/ego/service/VisaService.java +++ b/src/main/java/bio/overture/ego/service/VisaService.java @@ -1,91 +1,129 @@ -package bio.overture.ego.service; - -import static bio.overture.ego.model.exceptions.NotFoundException.checkNotFound; -import static bio.overture.ego.model.exceptions.RequestValidationException.checkRequestValid; -import static org.mapstruct.factory.Mappers.getMapper; - -import bio.overture.ego.event.token.ApiKeyEventsPublisher; -import bio.overture.ego.model.dto.VisaRequest; -import bio.overture.ego.model.entity.Visa; -import bio.overture.ego.repository.VisaRepository; -import jakarta.validation.constraints.NotNull; -import java.util.Optional; -import java.util.UUID; -import lombok.NonNull; -import lombok.extern.slf4j.Slf4j; -import lombok.val; -import org.mapstruct.Mapper; -import org.mapstruct.MappingTarget; -import org.mapstruct.NullValueCheckStrategy; -import org.mapstruct.ReportingPolicy; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.data.domain.Page; -import org.springframework.data.domain.Pageable; -import org.springframework.stereotype.Service; -import org.springframework.transaction.annotation.Transactional; - -@Slf4j -@Service -@Transactional -public class VisaService extends AbstractNamedService { - - /** Constants */ - private static final VisaService.VisaConverter VISA_CONVERTER = - getMapper(VisaService.VisaConverter.class); - - /** Dependencies */ - @Autowired private VisaRepository visaRepository; - - private final ApiKeyEventsPublisher apiKeyEventsPublisher; - - @Autowired - public VisaService( - @NonNull VisaRepository visaRepository, - @NonNull ApiKeyEventsPublisher apiKeyEventsPublisher) { - super(Visa.class, visaRepository); - this.visaRepository = visaRepository; - this.apiKeyEventsPublisher = apiKeyEventsPublisher; - } - - public Visa create(@NonNull VisaRequest createRequest) { - checkRequestValid(createRequest); - val visa = VISA_CONVERTER.convertToVisa(createRequest); - return getRepository().save(visa); - } - - @Override - public Visa getById(@NonNull UUID uuid) { - val result = (Optional) getRepository().findById(uuid); - checkNotFound(result.isPresent(), "The visaId '%s' does not exist", uuid); - return result.get(); - } - - public void delete(@NonNull UUID id) { - checkExistence(id); - super.delete(id); - } - - public Page listVisa(@NonNull Pageable pageable) { - return visaRepository.findAll(pageable); - } - - public Visa partialUpdate(@NotNull UUID id, @NonNull VisaRequest updateRequest) { - val visa = getById(id); - VISA_CONVERTER.updateVisa(updateRequest, visa); - return getRepository().save(visa); - } - - @Mapper( - nullValueCheckStrategy = NullValueCheckStrategy.ALWAYS, - unmappedTargetPolicy = ReportingPolicy.WARN) - public abstract static class VisaConverter { - public abstract Visa convertToVisa(VisaRequest request); - - public abstract void updateVisa(VisaRequest request, @MappingTarget Visa visaToUpdate); - } - - @Override - public Visa getWithRelationships(UUID uuid) { - return null; - } -} +package bio.overture.ego.service; + +import static bio.overture.ego.model.exceptions.NotFoundException.checkNotFound; +import static bio.overture.ego.model.exceptions.RequestValidationException.checkRequestValid; +import static org.mapstruct.factory.Mappers.getMapper; + +import bio.overture.ego.event.token.ApiKeyEventsPublisher; +import bio.overture.ego.model.dto.PassportVisa; +import bio.overture.ego.model.dto.VisaRequest; +import bio.overture.ego.model.entity.Visa; +import bio.overture.ego.model.exceptions.InvalidTokenException; +import bio.overture.ego.repository.VisaRepository; +import bio.overture.ego.utils.CacheUtil; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.ObjectMapper; +import io.jsonwebtoken.Claims; +import io.jsonwebtoken.Jwts; +import jakarta.validation.constraints.NotNull; +import java.util.Optional; +import java.util.UUID; +import lombok.NonNull; +import lombok.extern.slf4j.Slf4j; +import lombok.val; +import org.apache.commons.codec.binary.Base64; +import org.mapstruct.Mapper; +import org.mapstruct.MappingTarget; +import org.mapstruct.NullValueCheckStrategy; +import org.mapstruct.ReportingPolicy; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +@Slf4j +@Service +@Transactional +public class VisaService extends AbstractNamedService { + /** Constants */ + private static final VisaConverter VISA_CONVERTER = getMapper(VisaConverter.class); + + /** Dependencies */ + @Autowired private VisaRepository visaRepository; + + @Autowired private CacheUtil cacheUtil; + + private final ApiKeyEventsPublisher apiKeyEventsPublisher; + + @Autowired + public VisaService( + @NonNull VisaRepository visaRepository, + @NonNull ApiKeyEventsPublisher apiKeyEventsPublisher) { + super(Visa.class, visaRepository); + this.visaRepository = visaRepository; + this.apiKeyEventsPublisher = apiKeyEventsPublisher; + } + + public Visa create(@NonNull VisaRequest createRequest) { + checkRequestValid(createRequest); + val visa = VISA_CONVERTER.convertToVisa(createRequest); + return getRepository().save(visa); + } + + @Override + public Visa getById(@NonNull UUID uuid) { + val result = (Optional) getRepository().findById(uuid); + checkNotFound(result.isPresent(), "The visaId '%s' does not exist", uuid); + return result.get(); + } + + public void delete(@NonNull UUID id) { + checkExistence(id); + super.delete(id); + } + + // Parses Visa JWT token to convert into Visa Object + public PassportVisa parseVisa(@NonNull String visaJwtToken) throws JsonProcessingException { + String[] split_string = visaJwtToken.split("\\."); + String base64EncodedHeader = split_string[0]; + String base64EncodedBody = split_string[1]; + String base64EncodedSignature = split_string[2]; + Base64 base64Url = new Base64(true); + String header = new String(base64Url.decode(base64EncodedHeader)); + String body = new String(base64Url.decode(base64EncodedBody)); + return new ObjectMapper().readValue(body, PassportVisa.class); + } + + // Checks if the visa is a valid visa + public boolean isValidVisa(@NonNull String authToken) { + Claims claims; + try { + claims = + Jwts.parser() + .setSigningKey(cacheUtil.getPassportBrokerPublicKey()) + .parseClaimsJws(authToken) + .getBody(); + if (claims != null) { + return true; + } + } catch (Exception exception) { + throw new InvalidTokenException("The visa token received from broker is invalid"); + } + return false; + } + + public Page listVisa(@NonNull Pageable pageable) { + return visaRepository.findAll(pageable); + } + + public Visa partialUpdate(@NotNull UUID id, @NonNull VisaRequest updateRequest) { + val visa = getById(id); + VISA_CONVERTER.updateVisa(updateRequest, visa); + return getRepository().save(visa); + } + + @Mapper( + nullValueCheckStrategy = NullValueCheckStrategy.ALWAYS, + unmappedTargetPolicy = ReportingPolicy.WARN) + public abstract static class VisaConverter { + public abstract Visa convertToVisa(VisaRequest request); + + public abstract void updateVisa(VisaRequest request, @MappingTarget Visa visaToUpdate); + } + + @Override + public Visa getWithRelationships(UUID uuid) { + return null; + } +} diff --git a/src/main/java/bio/overture/ego/utils/CacheUtil.java b/src/main/java/bio/overture/ego/utils/CacheUtil.java new file mode 100644 index 000000000..f512a6522 --- /dev/null +++ b/src/main/java/bio/overture/ego/utils/CacheUtil.java @@ -0,0 +1,48 @@ +package bio.overture.ego.utils; + +import static bio.overture.ego.model.exceptions.InternalServerException.buildInternalServerException; +import static org.springframework.http.HttpMethod.GET; + +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.cache.annotation.CacheEvict; +import org.springframework.cache.annotation.Cacheable; +import org.springframework.http.ResponseEntity; +import org.springframework.scheduling.annotation.Scheduled; +import org.springframework.stereotype.Component; +import org.springframework.web.client.HttpStatusCodeException; +import org.springframework.web.client.RestTemplate; + +@Slf4j +@Component +public class CacheUtil { + + @Value("${broker.publicKey.url}") + private String brokerPublicKeyUrl; + + private RestTemplate restTemplate; + + @Cacheable("getPassportBrokerPublicKey") + public String getPassportBrokerPublicKey() { + ResponseEntity response; + try { + response = restTemplate.exchange(brokerPublicKeyUrl, GET, null, String.class); + } catch (HttpStatusCodeException err) { + log.error( + "Invalid {} response from passport broker service: {}", + err.getStatusCode().value(), + err.getMessage()); + throw buildInternalServerException( + "Invalid %s response from passport broker service.", err.getStatusCode().value()); + } + return response.getBody(); + } + + @CacheEvict(value = "evictAll", allEntries = true) + public void evictAllCaches() {} + + @Scheduled(fixedRate = 6000) + public void evictAllCachesEveryDay() { + evictAllCaches(); + } +} diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml index ee273dfd0..cd5e9f76b 100644 --- a/src/main/resources/application.yml +++ b/src/main/resources/application.yml @@ -184,6 +184,10 @@ token: private-key: MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQDSU6oy48sJW6xzqzOSU1dAvUUeFKQSBHsCf7wGWUGpOxEczhtFiiyx4YUJtg+fyvwWxa4wO3GnQLBPIxBHY8JsnvjQN2lsTUoLqMB9nGpwF617uA/S2igm1u+cDpfi82kbi6SG1Sg30PM047R6oxTRGDLLkeMRF1gRaTBM0HfSL0j6ccU5KPgwYsFLE2We6jeR56iYJGC2KYLH4v8rcc2jRAdMbUntHMtUByF9BPSW7elQnyQH5Qzr/o0b59XLKwnJFn2Bp2yviC8cdyTDyhQGna0e+oESQR1j6u3Ux/mOmm3slRXscA8sH+pHmOEAtjYVf/ww36U8uZv+ctBCJyFVAgMBAAECggEBALrEeJqAFUfWFCkSmdUSFKT0bW/svFUTjXgGnZy1ncz9GpENpMH3lQDQVibteKpYwcom+Cr0XlQ66VUcudPrDjcOY7vhuMfnSh1YWLYyM4IeRHtcUxDVkFoM+vEFNHLf2zIOqqbgmboW3iDVIurT7iRO7KxAe/YtWJL9aVqMtBn7Lu7S7OvAU4ji5iLIBxjl82JYA+9lu/aQ6YGaoZuSO7bcU8Sivi+DKAahqN9XMKiB1XpC+PpaS/aec2S7xIlTdzoDGxEALRGlMe+xBEeQTBVJHBWrRIDPoHLTREeRC/9Pp+1Y4Dz8hd5Bi0n8/5r/q0liD+0vtmjsdU4E2QrktYECgYEA73qWvhCYHPMREAFtwz1mpp9ZhDCW6SF+njG7fBKcjz8OLcy15LXiTGc268ewtQqTMjPQlm1n2C6hGccGAIlMibQJo3KZHlTs125FUzDpTVgdlei6vU7M+gmfRSZed00J6jC04/qMR1tnV3HME3np7eRTKTA6Ts+zBwEvkbCetSkCgYEA4NY5iSBO1ybouIecDdD15uI2ItLPCBNMzu7IiK7IygIzuf+SyKyjhtFSR4vEi0gScOM7UMlwCMOVU10e4nMDknIWCDG9iFvmIEkGHGxgRrN5hX1Wrq74wF212lvvagH1IVWSHa8cVpMe+UwKu5Q1h4yzuYt6Q9wPQ7Qtn5emBE0CgYB2syispMUA9GnsqQii0Xhj9nAEWaEzhOqhtrzbTs5TIkoA4Yr3BkBY5oAOdjhcRBWZuJ0XMrtaKCKqCEAtW+CYEKkGXvMOWcHbNkkeZwv8zkQ73dNRqhFnjgVn3RDNyV20uteueK23YNLkQP+KV89fnuCpdcIw9joiqq/NYuIHoQKBgB5WaZ8KH/lCA8babYEjv/pubZWXUl4plISbja17wBYZ4/bl+F1hhhMr7Wk//743dF2NG7TT6W0VTvHXr9IoaMP65uQmKgfbNpsGn294ZClGEFClz+t0KpZyTpZvL0fjibr8u+GLfkxkP5qt2wjif7KRlrKjklTTva+KAVn2cW1FAoGBAMkX9ekIwhx/7uY6ndxKl8ZMDerjr6MhV0b08hHp3RxHbYVbcpN0UKspoYvZVgHwP18xlDij8yWRE2fapwgi4m82ZmYlg0qqJmyqIU9vBB3Jow903h1KPQrkmQEZxJ/4H8yrbgVf2HT+WUfjTFgaDZRl01bI3YkydCw91/Ub9HU6 public-key: MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA0lOqMuPLCVusc6szklNXQL1FHhSkEgR7An+8BllBqTsRHM4bRYosseGFCbYPn8r8FsWuMDtxp0CwTyMQR2PCbJ740DdpbE1KC6jAfZxqcBete7gP0tooJtbvnA6X4vNpG4ukhtUoN9DzNOO0eqMU0Rgyy5HjERdYEWkwTNB30i9I+nHFOSj4MGLBSxNlnuo3keeomCRgtimCx+L/K3HNo0QHTG1J7RzLVAchfQT0lu3pUJ8kB+UM6/6NG+fVyysJyRZ9gadsr4gvHHckw8oUBp2tHvqBEkEdY+rt1Mf5jppt7JUV7HAPLB/qR5jhALY2FX/8MN+lPLmb/nLQQichVQIDAQAB +broker: + publicKey: + url: http://localhost:8082/token/public_key + # Default values available for creation of entities default: user: