diff --git a/java/mon-middleware/.idea/.name b/java/mon-middleware/.idea/.name new file mode 100644 index 00000000..4b66ee67 --- /dev/null +++ b/java/mon-middleware/.idea/.name @@ -0,0 +1 @@ +mon-middleware \ No newline at end of file diff --git a/java/mon-middleware/.idea/compiler.xml b/java/mon-middleware/.idea/compiler.xml new file mode 100644 index 00000000..03995707 --- /dev/null +++ b/java/mon-middleware/.idea/compiler.xml @@ -0,0 +1,33 @@ + + + + + + diff --git a/java/mon-middleware/.idea/copyright/profiles_settings.xml b/java/mon-middleware/.idea/copyright/profiles_settings.xml new file mode 100644 index 00000000..e7bedf33 --- /dev/null +++ b/java/mon-middleware/.idea/copyright/profiles_settings.xml @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/java/mon-middleware/.idea/encodings.xml b/java/mon-middleware/.idea/encodings.xml new file mode 100644 index 00000000..74c0d0a5 --- /dev/null +++ b/java/mon-middleware/.idea/encodings.xml @@ -0,0 +1,7 @@ + + + + + + + diff --git a/java/mon-middleware/.idea/inspectionProfiles/Project_Default.xml b/java/mon-middleware/.idea/inspectionProfiles/Project_Default.xml new file mode 100644 index 00000000..efd12889 --- /dev/null +++ b/java/mon-middleware/.idea/inspectionProfiles/Project_Default.xml @@ -0,0 +1,14 @@ + + + + \ No newline at end of file diff --git a/java/mon-middleware/.idea/inspectionProfiles/profiles_settings.xml b/java/mon-middleware/.idea/inspectionProfiles/profiles_settings.xml new file mode 100644 index 00000000..3b312839 --- /dev/null +++ b/java/mon-middleware/.idea/inspectionProfiles/profiles_settings.xml @@ -0,0 +1,7 @@ + + + + \ No newline at end of file diff --git a/java/mon-middleware/.idea/libraries/Maven__aopalliance_aopalliance_1_0.xml b/java/mon-middleware/.idea/libraries/Maven__aopalliance_aopalliance_1_0.xml new file mode 100644 index 00000000..30ff5cb7 --- /dev/null +++ b/java/mon-middleware/.idea/libraries/Maven__aopalliance_aopalliance_1_0.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/java/mon-middleware/.idea/libraries/Maven__ch_qos_logback_logback_classic_1_1_1.xml b/java/mon-middleware/.idea/libraries/Maven__ch_qos_logback_logback_classic_1_1_1.xml new file mode 100644 index 00000000..6f8c5c90 --- /dev/null +++ b/java/mon-middleware/.idea/libraries/Maven__ch_qos_logback_logback_classic_1_1_1.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/java/mon-middleware/.idea/libraries/Maven__ch_qos_logback_logback_core_1_1_1.xml b/java/mon-middleware/.idea/libraries/Maven__ch_qos_logback_logback_core_1_1_1.xml new file mode 100644 index 00000000..e9c2383e --- /dev/null +++ b/java/mon-middleware/.idea/libraries/Maven__ch_qos_logback_logback_core_1_1_1.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/java/mon-middleware/.idea/libraries/Maven__com_beust_jcommander_1_27.xml b/java/mon-middleware/.idea/libraries/Maven__com_beust_jcommander_1_27.xml new file mode 100644 index 00000000..f0f9060d --- /dev/null +++ b/java/mon-middleware/.idea/libraries/Maven__com_beust_jcommander_1_27.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/java/mon-middleware/.idea/libraries/Maven__com_codahale_metrics_metrics_core_3_0_2.xml b/java/mon-middleware/.idea/libraries/Maven__com_codahale_metrics_metrics_core_3_0_2.xml new file mode 100644 index 00000000..25642354 --- /dev/null +++ b/java/mon-middleware/.idea/libraries/Maven__com_codahale_metrics_metrics_core_3_0_2.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/java/mon-middleware/.idea/libraries/Maven__com_fasterxml_jackson_core_jackson_annotations_2_3_0.xml b/java/mon-middleware/.idea/libraries/Maven__com_fasterxml_jackson_core_jackson_annotations_2_3_0.xml new file mode 100644 index 00000000..e90bc9cb --- /dev/null +++ b/java/mon-middleware/.idea/libraries/Maven__com_fasterxml_jackson_core_jackson_annotations_2_3_0.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/java/mon-middleware/.idea/libraries/Maven__com_fasterxml_jackson_core_jackson_core_2_3_0.xml b/java/mon-middleware/.idea/libraries/Maven__com_fasterxml_jackson_core_jackson_core_2_3_0.xml new file mode 100644 index 00000000..0272e3bc --- /dev/null +++ b/java/mon-middleware/.idea/libraries/Maven__com_fasterxml_jackson_core_jackson_core_2_3_0.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/java/mon-middleware/.idea/libraries/Maven__com_fasterxml_jackson_core_jackson_databind_2_3_0.xml b/java/mon-middleware/.idea/libraries/Maven__com_fasterxml_jackson_core_jackson_databind_2_3_0.xml new file mode 100644 index 00000000..a250fb4c --- /dev/null +++ b/java/mon-middleware/.idea/libraries/Maven__com_fasterxml_jackson_core_jackson_databind_2_3_0.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/java/mon-middleware/.idea/libraries/Maven__com_fasterxml_jackson_dataformat_jackson_dataformat_yaml_2_3_0.xml b/java/mon-middleware/.idea/libraries/Maven__com_fasterxml_jackson_dataformat_jackson_dataformat_yaml_2_3_0.xml new file mode 100644 index 00000000..05816612 --- /dev/null +++ b/java/mon-middleware/.idea/libraries/Maven__com_fasterxml_jackson_dataformat_jackson_dataformat_yaml_2_3_0.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/java/mon-middleware/.idea/libraries/Maven__com_fasterxml_jackson_datatype_jackson_datatype_joda_2_3_0.xml b/java/mon-middleware/.idea/libraries/Maven__com_fasterxml_jackson_datatype_jackson_datatype_joda_2_3_0.xml new file mode 100644 index 00000000..0036f1fd --- /dev/null +++ b/java/mon-middleware/.idea/libraries/Maven__com_fasterxml_jackson_datatype_jackson_datatype_joda_2_3_0.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/java/mon-middleware/.idea/libraries/Maven__com_google_code_findbugs_jsr305_2_0_0.xml b/java/mon-middleware/.idea/libraries/Maven__com_google_code_findbugs_jsr305_2_0_0.xml new file mode 100644 index 00000000..67df9888 --- /dev/null +++ b/java/mon-middleware/.idea/libraries/Maven__com_google_code_findbugs_jsr305_2_0_0.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/java/mon-middleware/.idea/libraries/Maven__com_google_code_gson_gson_2_2_4.xml b/java/mon-middleware/.idea/libraries/Maven__com_google_code_gson_gson_2_2_4.xml new file mode 100644 index 00000000..4533c1ba --- /dev/null +++ b/java/mon-middleware/.idea/libraries/Maven__com_google_code_gson_gson_2_2_4.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/java/mon-middleware/.idea/libraries/Maven__com_google_guava_guava_17_0.xml b/java/mon-middleware/.idea/libraries/Maven__com_google_guava_guava_17_0.xml new file mode 100644 index 00000000..2a9069ca --- /dev/null +++ b/java/mon-middleware/.idea/libraries/Maven__com_google_guava_guava_17_0.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/java/mon-middleware/.idea/libraries/Maven__com_google_inject_guice_3_0.xml b/java/mon-middleware/.idea/libraries/Maven__com_google_inject_guice_3_0.xml new file mode 100644 index 00000000..b5a7a25b --- /dev/null +++ b/java/mon-middleware/.idea/libraries/Maven__com_google_inject_guice_3_0.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/java/mon-middleware/.idea/libraries/Maven__com_h2database_h2_1_3_175.xml b/java/mon-middleware/.idea/libraries/Maven__com_h2database_h2_1_3_175.xml new file mode 100644 index 00000000..8c776e18 --- /dev/null +++ b/java/mon-middleware/.idea/libraries/Maven__com_h2database_h2_1_3_175.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/java/mon-middleware/.idea/libraries/Maven__com_hpcloud_mon_testing_1_0_0_SNAPSHOT.xml b/java/mon-middleware/.idea/libraries/Maven__com_hpcloud_mon_testing_1_0_0_SNAPSHOT.xml new file mode 100644 index 00000000..f00ae202 --- /dev/null +++ b/java/mon-middleware/.idea/libraries/Maven__com_hpcloud_mon_testing_1_0_0_SNAPSHOT.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/java/mon-middleware/.idea/libraries/Maven__com_hpcloud_mon_util_1_0_0_SNAPSHOT.xml b/java/mon-middleware/.idea/libraries/Maven__com_hpcloud_mon_util_1_0_0_SNAPSHOT.xml new file mode 100644 index 00000000..ee09b2f1 --- /dev/null +++ b/java/mon-middleware/.idea/libraries/Maven__com_hpcloud_mon_util_1_0_0_SNAPSHOT.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/java/mon-middleware/.idea/libraries/Maven__commons_codec_commons_codec_1_6.xml b/java/mon-middleware/.idea/libraries/Maven__commons_codec_commons_codec_1_6.xml new file mode 100644 index 00000000..e8a6a9f9 --- /dev/null +++ b/java/mon-middleware/.idea/libraries/Maven__commons_codec_commons_codec_1_6.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/java/mon-middleware/.idea/libraries/Maven__commons_lang_commons_lang_2_5.xml b/java/mon-middleware/.idea/libraries/Maven__commons_lang_commons_lang_2_5.xml new file mode 100644 index 00000000..055afe5d --- /dev/null +++ b/java/mon-middleware/.idea/libraries/Maven__commons_lang_commons_lang_2_5.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/java/mon-middleware/.idea/libraries/Maven__commons_logging_commons_logging_1_1_1.xml b/java/mon-middleware/.idea/libraries/Maven__commons_logging_commons_logging_1_1_1.xml new file mode 100644 index 00000000..b770f56a --- /dev/null +++ b/java/mon-middleware/.idea/libraries/Maven__commons_logging_commons_logging_1_1_1.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/java/mon-middleware/.idea/libraries/Maven__commons_pool_commons_pool_1_6.xml b/java/mon-middleware/.idea/libraries/Maven__commons_pool_commons_pool_1_6.xml new file mode 100644 index 00000000..83936486 --- /dev/null +++ b/java/mon-middleware/.idea/libraries/Maven__commons_pool_commons_pool_1_6.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/java/mon-middleware/.idea/libraries/Maven__javax_inject_javax_inject_1.xml b/java/mon-middleware/.idea/libraries/Maven__javax_inject_javax_inject_1.xml new file mode 100644 index 00000000..93cf65ab --- /dev/null +++ b/java/mon-middleware/.idea/libraries/Maven__javax_inject_javax_inject_1.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/java/mon-middleware/.idea/libraries/Maven__javax_servlet_servlet_api_2_5.xml b/java/mon-middleware/.idea/libraries/Maven__javax_servlet_servlet_api_2_5.xml new file mode 100644 index 00000000..679e09a1 --- /dev/null +++ b/java/mon-middleware/.idea/libraries/Maven__javax_servlet_servlet_api_2_5.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/java/mon-middleware/.idea/libraries/Maven__javax_validation_validation_api_1_0_0_GA.xml b/java/mon-middleware/.idea/libraries/Maven__javax_validation_validation_api_1_0_0_GA.xml new file mode 100644 index 00000000..4b644e91 --- /dev/null +++ b/java/mon-middleware/.idea/libraries/Maven__javax_validation_validation_api_1_0_0_GA.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/java/mon-middleware/.idea/libraries/Maven__joda_time_joda_time_2_3.xml b/java/mon-middleware/.idea/libraries/Maven__joda_time_joda_time_2_3.xml new file mode 100644 index 00000000..20f5108a --- /dev/null +++ b/java/mon-middleware/.idea/libraries/Maven__joda_time_joda_time_2_3.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/java/mon-middleware/.idea/libraries/Maven__junit_junit_4_10.xml b/java/mon-middleware/.idea/libraries/Maven__junit_junit_4_10.xml new file mode 100644 index 00000000..ed8bf5fe --- /dev/null +++ b/java/mon-middleware/.idea/libraries/Maven__junit_junit_4_10.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/java/mon-middleware/.idea/libraries/Maven__org_apache_commons_commons_collections4_4_0.xml b/java/mon-middleware/.idea/libraries/Maven__org_apache_commons_commons_collections4_4_0.xml new file mode 100644 index 00000000..28cee2ad --- /dev/null +++ b/java/mon-middleware/.idea/libraries/Maven__org_apache_commons_commons_collections4_4_0.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/java/mon-middleware/.idea/libraries/Maven__org_apache_httpcomponents_httpclient_4_2_1.xml b/java/mon-middleware/.idea/libraries/Maven__org_apache_httpcomponents_httpclient_4_2_1.xml new file mode 100644 index 00000000..9dedb802 --- /dev/null +++ b/java/mon-middleware/.idea/libraries/Maven__org_apache_httpcomponents_httpclient_4_2_1.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/java/mon-middleware/.idea/libraries/Maven__org_apache_httpcomponents_httpcore_4_2_1.xml b/java/mon-middleware/.idea/libraries/Maven__org_apache_httpcomponents_httpcore_4_2_1.xml new file mode 100644 index 00000000..1b38fdaa --- /dev/null +++ b/java/mon-middleware/.idea/libraries/Maven__org_apache_httpcomponents_httpcore_4_2_1.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/java/mon-middleware/.idea/libraries/Maven__org_apache_thrift_libthrift_0_9_0.xml b/java/mon-middleware/.idea/libraries/Maven__org_apache_thrift_libthrift_0_9_0.xml new file mode 100644 index 00000000..bcd58a37 --- /dev/null +++ b/java/mon-middleware/.idea/libraries/Maven__org_apache_thrift_libthrift_0_9_0.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/java/mon-middleware/.idea/libraries/Maven__org_beanshell_bsh_2_0b4.xml b/java/mon-middleware/.idea/libraries/Maven__org_beanshell_bsh_2_0b4.xml new file mode 100644 index 00000000..d6f17aa7 --- /dev/null +++ b/java/mon-middleware/.idea/libraries/Maven__org_beanshell_bsh_2_0b4.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/java/mon-middleware/.idea/libraries/Maven__org_eclipse_jetty_jetty_continuation_7_0_0_M2.xml b/java/mon-middleware/.idea/libraries/Maven__org_eclipse_jetty_jetty_continuation_7_0_0_M2.xml new file mode 100644 index 00000000..430ea997 --- /dev/null +++ b/java/mon-middleware/.idea/libraries/Maven__org_eclipse_jetty_jetty_continuation_7_0_0_M2.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/java/mon-middleware/.idea/libraries/Maven__org_eclipse_jetty_jetty_http_7_0_0_M2.xml b/java/mon-middleware/.idea/libraries/Maven__org_eclipse_jetty_jetty_http_7_0_0_M2.xml new file mode 100644 index 00000000..a758aaaa --- /dev/null +++ b/java/mon-middleware/.idea/libraries/Maven__org_eclipse_jetty_jetty_http_7_0_0_M2.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/java/mon-middleware/.idea/libraries/Maven__org_eclipse_jetty_jetty_io_7_0_0_M2.xml b/java/mon-middleware/.idea/libraries/Maven__org_eclipse_jetty_jetty_io_7_0_0_M2.xml new file mode 100644 index 00000000..1f7566fa --- /dev/null +++ b/java/mon-middleware/.idea/libraries/Maven__org_eclipse_jetty_jetty_io_7_0_0_M2.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/java/mon-middleware/.idea/libraries/Maven__org_eclipse_jetty_jetty_security_7_0_0_M2.xml b/java/mon-middleware/.idea/libraries/Maven__org_eclipse_jetty_jetty_security_7_0_0_M2.xml new file mode 100644 index 00000000..5d20cce9 --- /dev/null +++ b/java/mon-middleware/.idea/libraries/Maven__org_eclipse_jetty_jetty_security_7_0_0_M2.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/java/mon-middleware/.idea/libraries/Maven__org_eclipse_jetty_jetty_server_7_0_0_M2.xml b/java/mon-middleware/.idea/libraries/Maven__org_eclipse_jetty_jetty_server_7_0_0_M2.xml new file mode 100644 index 00000000..30fb01ce --- /dev/null +++ b/java/mon-middleware/.idea/libraries/Maven__org_eclipse_jetty_jetty_server_7_0_0_M2.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/java/mon-middleware/.idea/libraries/Maven__org_eclipse_jetty_jetty_servlet_7_0_0_M2.xml b/java/mon-middleware/.idea/libraries/Maven__org_eclipse_jetty_jetty_servlet_7_0_0_M2.xml new file mode 100644 index 00000000..40e5e9a5 --- /dev/null +++ b/java/mon-middleware/.idea/libraries/Maven__org_eclipse_jetty_jetty_servlet_7_0_0_M2.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/java/mon-middleware/.idea/libraries/Maven__org_eclipse_jetty_jetty_servlet_tester_7_0_0_M2.xml b/java/mon-middleware/.idea/libraries/Maven__org_eclipse_jetty_jetty_servlet_tester_7_0_0_M2.xml new file mode 100644 index 00000000..5f6fff22 --- /dev/null +++ b/java/mon-middleware/.idea/libraries/Maven__org_eclipse_jetty_jetty_servlet_tester_7_0_0_M2.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/java/mon-middleware/.idea/libraries/Maven__org_eclipse_jetty_jetty_util_7_0_0_M2.xml b/java/mon-middleware/.idea/libraries/Maven__org_eclipse_jetty_jetty_util_7_0_0_M2.xml new file mode 100644 index 00000000..da44ccfa --- /dev/null +++ b/java/mon-middleware/.idea/libraries/Maven__org_eclipse_jetty_jetty_util_7_0_0_M2.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/java/mon-middleware/.idea/libraries/Maven__org_eclipse_jetty_jetty_webapp_7_0_0_M2.xml b/java/mon-middleware/.idea/libraries/Maven__org_eclipse_jetty_jetty_webapp_7_0_0_M2.xml new file mode 100644 index 00000000..c8a5a2bd --- /dev/null +++ b/java/mon-middleware/.idea/libraries/Maven__org_eclipse_jetty_jetty_webapp_7_0_0_M2.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/java/mon-middleware/.idea/libraries/Maven__org_eclipse_jetty_jetty_xml_7_0_0_M2.xml b/java/mon-middleware/.idea/libraries/Maven__org_eclipse_jetty_jetty_xml_7_0_0_M2.xml new file mode 100644 index 00000000..ced8cb47 --- /dev/null +++ b/java/mon-middleware/.idea/libraries/Maven__org_eclipse_jetty_jetty_xml_7_0_0_M2.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/java/mon-middleware/.idea/libraries/Maven__org_hamcrest_hamcrest_core_1_1.xml b/java/mon-middleware/.idea/libraries/Maven__org_hamcrest_hamcrest_core_1_1.xml new file mode 100644 index 00000000..acdf4430 --- /dev/null +++ b/java/mon-middleware/.idea/libraries/Maven__org_hamcrest_hamcrest_core_1_1.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/java/mon-middleware/.idea/libraries/Maven__org_hibernate_hibernate_validator_4_3_0_Final.xml b/java/mon-middleware/.idea/libraries/Maven__org_hibernate_hibernate_validator_4_3_0_Final.xml new file mode 100644 index 00000000..b8a4cea3 --- /dev/null +++ b/java/mon-middleware/.idea/libraries/Maven__org_hibernate_hibernate_validator_4_3_0_Final.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/java/mon-middleware/.idea/libraries/Maven__org_jboss_logging_jboss_logging_3_1_0_CR2.xml b/java/mon-middleware/.idea/libraries/Maven__org_jboss_logging_jboss_logging_3_1_0_CR2.xml new file mode 100644 index 00000000..3812cdd4 --- /dev/null +++ b/java/mon-middleware/.idea/libraries/Maven__org_jboss_logging_jboss_logging_3_1_0_CR2.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/java/mon-middleware/.idea/libraries/Maven__org_jodah_concurrentunit_0_3_0.xml b/java/mon-middleware/.idea/libraries/Maven__org_jodah_concurrentunit_0_3_0.xml new file mode 100644 index 00000000..a759de01 --- /dev/null +++ b/java/mon-middleware/.idea/libraries/Maven__org_jodah_concurrentunit_0_3_0.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/java/mon-middleware/.idea/libraries/Maven__org_mockito_mockito_all_1_9_5.xml b/java/mon-middleware/.idea/libraries/Maven__org_mockito_mockito_all_1_9_5.xml new file mode 100644 index 00000000..7797878d --- /dev/null +++ b/java/mon-middleware/.idea/libraries/Maven__org_mockito_mockito_all_1_9_5.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/java/mon-middleware/.idea/libraries/Maven__org_slf4j_slf4j_api_1_5_8.xml b/java/mon-middleware/.idea/libraries/Maven__org_slf4j_slf4j_api_1_5_8.xml new file mode 100644 index 00000000..0ea470ab --- /dev/null +++ b/java/mon-middleware/.idea/libraries/Maven__org_slf4j_slf4j_api_1_5_8.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/java/mon-middleware/.idea/libraries/Maven__org_testng_testng_6_8_7.xml b/java/mon-middleware/.idea/libraries/Maven__org_testng_testng_6_8_7.xml new file mode 100644 index 00000000..74e6a1f5 --- /dev/null +++ b/java/mon-middleware/.idea/libraries/Maven__org_testng_testng_6_8_7.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/java/mon-middleware/.idea/libraries/Maven__org_yaml_snakeyaml_1_12.xml b/java/mon-middleware/.idea/libraries/Maven__org_yaml_snakeyaml_1_12.xml new file mode 100644 index 00000000..7e6154cf --- /dev/null +++ b/java/mon-middleware/.idea/libraries/Maven__org_yaml_snakeyaml_1_12.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/java/mon-middleware/.idea/misc.xml b/java/mon-middleware/.idea/misc.xml new file mode 100644 index 00000000..1edcc416 --- /dev/null +++ b/java/mon-middleware/.idea/misc.xml @@ -0,0 +1,33 @@ + + + + + + + + + + + + + + + + 1.7 + + + + + + + + + diff --git a/java/mon-middleware/.idea/modules.xml b/java/mon-middleware/.idea/modules.xml new file mode 100644 index 00000000..98b2b082 --- /dev/null +++ b/java/mon-middleware/.idea/modules.xml @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/java/mon-middleware/.idea/scopes/scope_settings.xml b/java/mon-middleware/.idea/scopes/scope_settings.xml new file mode 100644 index 00000000..922003b8 --- /dev/null +++ b/java/mon-middleware/.idea/scopes/scope_settings.xml @@ -0,0 +1,5 @@ + + + + \ No newline at end of file diff --git a/java/mon-middleware/.idea/vcs.xml b/java/mon-middleware/.idea/vcs.xml new file mode 100644 index 00000000..def6a6a1 --- /dev/null +++ b/java/mon-middleware/.idea/vcs.xml @@ -0,0 +1,7 @@ + + + + + + + diff --git a/java/mon-middleware/.idea/workspace.xml b/java/mon-middleware/.idea/workspace.xml new file mode 100644 index 00000000..0d0b0a7a --- /dev/null +++ b/java/mon-middleware/.idea/workspace.xml @@ -0,0 +1,682 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Serialization issues + + + + + SerializableHasSerialVersionUIDField + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + localhost + 5050 + + + + + + + 1403761977800 + 1403761977800 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/java/mon-middleware/pom.xml b/java/mon-middleware/pom.xml new file mode 100644 index 00000000..e62a7f2c --- /dev/null +++ b/java/mon-middleware/pom.xml @@ -0,0 +1,103 @@ + + 4.0.0 + + com.hpcloud + mon-common + ${computedVersion} + + mon-middleware + jar + + + + + + + com.google.guava + guava + 17.0 + + + org.apache.httpcomponents + httpclient + 4.2.1 + + + + com.google.code.gson + gson + 2.2.4 + + + + commons-pool + commons-pool + 1.6 + + + + org.apache.thrift + libthrift + 0.9.0 + + + + org.apache.commons + commons-collections4 + 4.0 + + + + + org.eclipse.jetty + jetty-servlet-tester + 7.0.0.M2 + test + + + javax.servlet + servlet-api + provided + 2.5 + + + + com.hpcloud + mon-testing + ${project.version} + test + + + com.hpcloud + mon-util + ${project.version} + test + + + + + + clojars.org + http://clojars.org/repo + + + + + + + org.apache.maven.plugins + maven-jar-plugin + 2.4 + + + + test-jar + + + + + + + + diff --git a/java/mon-middleware/src/main/java/com/hpcloud/middleware/AuthClient.java b/java/mon-middleware/src/main/java/com/hpcloud/middleware/AuthClient.java new file mode 100644 index 00000000..7c508e47 --- /dev/null +++ b/java/mon-middleware/src/main/java/com/hpcloud/middleware/AuthClient.java @@ -0,0 +1,23 @@ +package com.hpcloud.middleware; + + +import java.util.Map; + +import org.apache.http.client.ClientProtocolException; +import org.apache.thrift.TException; + +/** + * A client that can communicate to an authentication server for authentication. + * + * @author liemmn + */ +public interface AuthClient { + public Object validateTokenForServiceEndpointV2(String token, + String serviceIds, String endpointIds, boolean includeCatalog) + throws TException, ClientProtocolException; + + public Object validateTokenForServiceEndpointV3(String token, + Map inputParams) throws TException, ClientProtocolException; + + +} diff --git a/java/mon-middleware/src/main/java/com/hpcloud/middleware/AuthClientFactory.java b/java/mon-middleware/src/main/java/com/hpcloud/middleware/AuthClientFactory.java new file mode 100644 index 00000000..a890b7b2 --- /dev/null +++ b/java/mon-middleware/src/main/java/com/hpcloud/middleware/AuthClientFactory.java @@ -0,0 +1,124 @@ +package com.hpcloud.middleware; + +import org.apache.commons.pool.impl.GenericObjectPool; + +/** + * A factory for building {@link AuthClient}s. + * + * @author liemmn + */ +public abstract class AuthClientFactory { + private static AuthClientFactory instance = null; + protected static GenericObjectPool pool; + + /** + * Build a AuthClientFactory. Singleton. + * + * @param host Auth host + * @param port Auth port + * @param timeout Auth connection timeout + * @param clientAuth 2-way SSL (if false, 1-way SSL is used) + * @param keyStore Keystore + * @param keyPass Keystore password + * @param trustStore Truststore + * @param trustPass Truststore password + * @param maxActive Maximum number of objects that can be allocated by the pool + * (checked out to clients, or idle awaiting checkout) at a given + * time. When non-positive, there is no limit to the number of + * objects that can be managed by the pool at one time. When + * maxActive is reached, the pool is said to be exhausted. The + * default setting for this parameter is 8. + * @param maxIdle Maximum number of objects that can sit idle in the pool at any + * time. When negative, there is no limit to the number of + * objects that may be idle at one time. The default setting for + * this parameter is 8. + * @param timeBetweenEvictionRunsMillis How long the eviction thread should sleep before "runs" of + * examining idle objects. When non-positive, no eviction thread + * will be launched. The default setting for this parameter is -1 + * (i.e., idle object eviction is disabled by default). + * @param minEvictableIdleTimeMillis Minimum amount of time that an object may sit idle in the pool + * before it is eligible for eviction due to idle time. When + * non-positive, no object will be dropped from the pool due to + * idle time alone. This setting has no effect unless + * timeBetweenEvictionRunsMillis > 0. The default setting for + * this parameter is 30 minutes. + * @param adminToken Admin token for use with vanilla Keystone. + * @return AuthClientFactory singleton. + * @throws Exception + */ + public static synchronized AuthClientFactory build(String host, int port, + int timeout, boolean clientAuth, String keyStore, String keyPass, + String trustStore, String trustPass, int maxActive, int maxIdle, + long timeBetweenEvictionRunsMillis, + long minEvictableIdleTimeMillis, String adminToken) + throws Exception { + if (instance == null) { + + instance = new HttpClientFactory(host, port, timeout, + clientAuth, keyStore, keyPass, trustStore, trustPass, + adminToken, maxActive, timeBetweenEvictionRunsMillis, + minEvictableIdleTimeMillis); + + // Pool tweaking + pool.setMaxActive(maxActive); + pool.setMaxIdle(maxIdle); + pool.setTimeBetweenEvictionRunsMillis(timeBetweenEvictionRunsMillis); + pool.setMinEvictableIdleTimeMillis(minEvictableIdleTimeMillis); + } + return instance; + } + + /** + * Get a client. Don't forget to {@link #recycleClient(Client)} after you + * are done using it, successfully or not. + * + * @return Client + * @throws Exception + */ + public AuthClient getClient() { + try { + return (AuthClient) pool.borrowObject(); + } catch (Exception e) { + throw new AuthConnectionException("Failed to get a client " + e.getMessage(), e); + } + } + + /** + * Recycle the client for next usage. + * + * @param client Client to recycle + * @throws Exception + */ + public void recycle(AuthClient client) { + try { + pool.returnObject(client); + } catch (Exception e) { + throw new AuthConnectionException("Failed to recycle client", e); + } + } + + /** + * Call this if the client is unusable (i.e., exception). + * + * @param client Client to discard. + */ + public void discard(AuthClient client) { + try { + pool.invalidateObject(client); + } catch (Exception e) { + System.out.println("AuthConnection problem destorying"); + throw new AuthConnectionException("Failed to destroy client", e); + } + } + + /** + * Shut down this factory. + */ + public void shutdown() { + try { + pool.close(); + } catch (Exception e) { + throw new AuthConnectionException("Failed to close client pool", e); + } + } +} diff --git a/java/mon-middleware/src/main/java/com/hpcloud/middleware/AuthConnectionException.java b/java/mon-middleware/src/main/java/com/hpcloud/middleware/AuthConnectionException.java new file mode 100644 index 00000000..778b148f --- /dev/null +++ b/java/mon-middleware/src/main/java/com/hpcloud/middleware/AuthConnectionException.java @@ -0,0 +1,18 @@ +package com.hpcloud.middleware; + +/** + * An exception to indicate any connection issue. + * + * @author liemmn + * + */ +public class AuthConnectionException extends RuntimeException { + private static final long serialVersionUID = 4318025130590973448L; + + public AuthConnectionException(String msg) { + super(msg); + } + public AuthConnectionException(String msg, Exception e) { + super(msg, e); + } +} diff --git a/java/mon-middleware/src/main/java/com/hpcloud/middleware/AuthConstants.java b/java/mon-middleware/src/main/java/com/hpcloud/middleware/AuthConstants.java new file mode 100644 index 00000000..2315bd7d --- /dev/null +++ b/java/mon-middleware/src/main/java/com/hpcloud/middleware/AuthConstants.java @@ -0,0 +1,234 @@ +package com.hpcloud.middleware; + +public interface AuthConstants { + /** + * 'Confirmed' or 'Invalid' + */ + public static enum IdentityStatus { + Confirmed, Invalid + } + + // =============================== TOKEN =================================== + /** + * Credential (token) header + */ + public static final String TOKEN = "X-AUTH-TOKEN"; + /** + * Auth status parameter + */ + public static final String AUTH_IDENTITY_STATUS = "X-IDENTITY-STATUS"; + /** + * Auth user Id parameter + */ + public static final String AUTH_USER_ID = "X-USER-ID"; + /** + * Auth user name parameter + */ + public static final String AUTH_USER_NAME = "X-USER-NAME"; + + /** + * Auth user roles parameter, comma-separated roles + */ + public static final String AUTH_ROLES = "X-ROLES"; + /** + * json encoded keystone service catalog + */ + public static final String AUTH_SERVICE_CATALOG = "X-SERVICE-CATALOG"; + /** + * Service Ids initialization parameter + */ + public static final String SERVICE_IDS = "ServiceIds"; + /** + * Endpoint Ids initialization parameter + */ + public static final String ENDPOINT_IDS = "EndpointIds"; + /** + * Keystone admin token for use in vanilla Keystone + */ + public static final String ADMIN_TOKEN = "AdminToken"; + + // ============================ CONNECTION ================================= + /** + * Auth server initialization parameter + */ + public static final String SERVER_VIP = "ServerVIP"; + /** + * Auth server port: 9543 for Thrift, 35357 for HTTP. + */ + public static final String SERVER_PORT = "ServerPort"; + /** + * connection timeout initialization parameter + */ + public static final String CONN_TIMEOUT = "ConnTimeout"; + /** + * 2-way SSL initialization parameter: True or False + */ + public static final String CONN_SSL_CLIENT_AUTH = "ConnSSLClientAuth"; + /** + * SSL keystore initialization parameter + */ + public static final String KEYSTORE = "Keystore"; + /** + * SSL keystore password initialization parameter + */ + public static final String KEYSTORE_PASS = "KeystorePass"; + /** + * SSL truststore initialization parameter + */ + public static final String TRUSTSTORE = "Truststore"; + /** + * SSL truststore password initialization parameter + */ + public static final String TRUSTSTORE_PASS = "TruststorePass"; + + // ============================== POOLING ================================== + /** + * Maximum number of objects that can be allocated by the pool (checked out + * to clients, or idle awaiting checkout) at a given time. When + * non-positive, there is no limit to the number of objects that can be + * managed by the pool at one time. When maxActive is reached, the pool is + * said to be exhausted. The default setting for this parameter is 8. + */ + public static final String CONN_POOL_MAX_ACTIVE = "ConnPoolMaxActive"; + /** + * Maximum number of objects that can sit idle in the pool at any time. When + * negative, there is no limit to the number of objects that may be idle at + * one time. The default setting for this parameter is 8. + */ + public static final String CONN_POOL_MAX_IDLE = "ConnPoolMaxIdle"; + /** + * How long the eviction thread should sleep before "runs" of examining idle + * objects. When non-positive, no eviction thread will be launched. The + * default setting for this parameter is -1 (i.e., idle object eviction is + * disabled by default). + */ + public static final String CONN_POOL_EVICT_PERIOD = "ConnPoolEvictPeriod"; + /** + * Minimum amount of time that an object may sit idle in the pool before it + * is eligible for eviction due to idle time. When non-positive, no object + * will be dropped from the pool due to idle time alone. This setting has no + * effect unless ConnPoolEvictPeriod > 0. The default setting for this + * parameter is 30 minutes. + */ + public static final String CONN_POOL_MIN_IDLE_TIME = "ConnPoolMinIdleTime"; + + // ============================== CACHING ================================== + public static final String TIME_TO_CACHE_TOKEN = "TimeToCacheToken"; + public static final String MAX_TOKEN_CACHE_SIZE = "MaxTokenCacheSize"; + + /** + * Number of connection timeout retries * + */ + public static final String CONN_TIMEOUT_RETRIES = "ConnRetryTimes"; + /** + * Number of connection timeout retries * + */ + public static final String PAUSE_BETWEEN_RETRIES = "ConnRetryInterval"; + /** + * Authentication decision is forwarded to next filter * + */ + public static final String DELAY_AUTH_DECISION = "DelayAuthDecision"; + + public static final String SIGNATURE_METHOD = "HmacSHA1"; + + + /** + * Version of CS to authenticate the credentials * + */ + public static final String AUTH_VERSION = "AuthVersion"; + + /** + * Include Service Catalog as part of Authentication Response * + */ + public static final String INCLUDE_SERVICE_CATALOG = "IncludeServiceCatalog"; + + /** + * Identity service managed unique identifier, string. Only present if this + * is a project-scoped v3 token, or a tenant-scoped v2 token. + */ + public static final String AUTH_PROJECT_ID = "X-PROJECT-ID"; + + /** + * Project name, unique within owning domain, string. Only present if this + * is a project-scoped v3 token, or a tenant-scoped v2 token. + */ + public static final String AUTH_PROJECT_NAME = "X-PROJECT-NAME"; + + /** + * Identity service managed unique identifier of owning domain of project, + * string. Only present if this is a project-scoped v3 token. If this + * variable is set, this indicates that the PROJECT_NAME can only be assumed + * to be unique within this domain. + */ + public static final String AUTH_PROJECT_DOMAIN_ID = "X-PROJECT-DOMAIN-ID"; + + /** + * Name of owning domain of project, string. Only present if this is a + * project-scoped v3 token. If this variable is set, this indicates that the + * PROJECT_NAME can only be assumed to be unique within this domain. + */ + public static final String AUTH_PROJECT_DOMAIN_NAME = "X-PROJECT-DOMAIN-NAME"; + + /** + * Identity service managed unique identifier of owning domain of user, + * string. If this variable is set, this indicates that the USER_NAME can + * only be assumed to be unique within this domain. + */ + public static final String AUTH_USER_DOMAIN_ID = "X-USER-DOMAIN-ID"; + + /** + * Name of owning domain of user, string. If this variable is set, this + * indicates that the USER_NAME can only be assumed to be unique within this + * domain. + */ + public static final String AUTH_USER_DOMAIN_NAME = "X-USER-DOMAIN-NAME"; + + /** + * Identity service managed unique identifier, string. Only present if this + * is a domain-scoped v3 token. + */ + public static final String AUTH_DOMAIN_ID = "X-DOMAIN-ID"; + + /** + * Unique domain name, string. Only present if this is a domain-scoped v3 + * token. + */ + public static final String AUTH_DOMAIN_NAME = "X-DOMAIN-NAME"; + + public static final String AUTH_HP_IDM_ROLES = "X-HP-IDM-Non-Tenant-Roles"; + + public static final String REMOTE_HOST = "RemoteHost"; + public static final String REMOTE_ADDR = "RemoteAddress"; + + // Depracated Headers. + /** + * Auth user roles parameter, comma-separated roles + */ + public static final String AUTH_ROLE = "X-ROLE"; + /** + * Auth tenant Id parameter + */ + public static final String AUTH_TENANT_ID = "X-TENANT-ID"; + /** + * Auth tenant name parameter + */ + public static final String AUTH_TENANT_NAME = "X-TENANT-NAME"; + /** + * Auth tenant name parameter + */ + public static final String AUTH_TENANT = "X-TENANT"; + /** + * *Deprecated* in favor of HTTP_X_USER_ID and HTTP_X_USER_NAME User name, + * unique within owning domain, string + */ + public static final String AUTH_USER = "X-USER"; + + public static final String AUTH_SUBJECT_TOKEN = "X-Subject-Token"; + public static final String ADMIN_USER = "AdminUser"; + public static final String ADMIN_PASSWORD = "AdminPassword"; + public static final String ADMIN_AUTH_METHOD = "AdminAuthMethod"; + public static final String ADMIN_ACCESS_KEY = "AdminAccessKey"; + public static final String ADMIN_SECRET_KEY = "AdminSecretKey"; + public static final String ADMIN_PROJECT_ID = "AdminProjectId"; + +} \ No newline at end of file diff --git a/java/mon-middleware/src/main/java/com/hpcloud/middleware/AuthException.java b/java/mon-middleware/src/main/java/com/hpcloud/middleware/AuthException.java new file mode 100644 index 00000000..345e804f --- /dev/null +++ b/java/mon-middleware/src/main/java/com/hpcloud/middleware/AuthException.java @@ -0,0 +1,20 @@ +package com.hpcloud.middleware; + +/** + * An exception to indicate any authentication error. + * + * @author liemmn + * + */ +public class AuthException extends RuntimeException { + + private static final long serialVersionUID = 5860956829821067827L; + + public AuthException(String msg) { + super(msg); + } + + public AuthException(String msg, Exception e) { + super(msg, e); + } +} diff --git a/java/mon-middleware/src/main/java/com/hpcloud/middleware/CatalogV3.java b/java/mon-middleware/src/main/java/com/hpcloud/middleware/CatalogV3.java new file mode 100644 index 00000000..c2de7cda --- /dev/null +++ b/java/mon-middleware/src/main/java/com/hpcloud/middleware/CatalogV3.java @@ -0,0 +1,37 @@ +package com.hpcloud.middleware; + +import java.util.List; + +public class CatalogV3 { + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getType() { + return type; + } + + public void setType(String type) { + this.type = type; + } + + public List getEndPoints() { + return endPoints; + } + + public void setEndPoints(List endPoints) { + this.endPoints = endPoints; + } + + String id; + String type; + List endPoints; + +} + + diff --git a/java/mon-middleware/src/main/java/com/hpcloud/middleware/Config.java b/java/mon-middleware/src/main/java/com/hpcloud/middleware/Config.java new file mode 100644 index 00000000..36720d8e --- /dev/null +++ b/java/mon-middleware/src/main/java/com/hpcloud/middleware/Config.java @@ -0,0 +1,281 @@ +package com.hpcloud.middleware; + +import javax.servlet.FilterConfig; +import javax.servlet.ServletContext; +import javax.servlet.ServletException; +import javax.servlet.ServletRequest; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.Map; + +public class Config implements AuthConstants { + + // Thee faithful logger + private static final Logger logger = LoggerFactory + .getLogger(Config.class); + + private static final Config instance = new Config(); + + private static final String PASSWORD = "password"; + private static final String ACCESS_KEY = "accesskey"; + + // Application wide init param -- ServletContext + private ServletContext context = null; + + private TokenCache client = null; + + // Auth client factory + private AuthClientFactory factory = null; + + // The service IDs that this filter serves + private String serviceIds; + + // The optional endpoint IDs that this filter serves + private String endpointIds; + + //the time to cache token + private long timeToCacheToken; + + // flag to set if auth decision can be delegated to next filter + private boolean delayAuthDecision; + + // retries and pauseTime configuration for retry logic + private int retries; + private int pauseTime; + + // configuration to authenticate against CS api + private String authVersion; + + // flag to include catalog in the response + private boolean includeCatalog; + + // configuration for admin authentication method to be used for 2-way SSL + private String adminAuthMethod; + + // configuration for admin default project + private String adminProjectId; + + // flag to indicate if the filter is already intialized with required parameters + private volatile boolean initialized = false; + + //context is not getting properly filed so will use FilterConfig + private FilterConfig filterConfig; + + private Config() { + } + + public static Config getInstance() { + return instance; + } + + public synchronized void initialize(FilterConfig config, ServletRequest req, Map map) throws ServletException { + this.context = config.getServletContext(); + this.filterConfig = config; + + try { + // Initialize serviceIds... + + serviceIds = filterConfig.getInitParameter(SERVICE_IDS); + // Initialize endpointIds... + endpointIds = filterConfig.getInitParameter(ENDPOINT_IDS); + + // Initialize auth server connection parameters... + + String host = filterConfig.getInitParameter(SERVER_VIP); + + int port = Integer.parseInt(filterConfig.getInitParameter(SERVER_PORT)); + + // HP Keystone Server only supports authentication against + // V3.0 api + authVersion = getValue(AUTH_VERSION, "v3.0"); + + if ((serviceIds == null || serviceIds.isEmpty()) + && (endpointIds == null || endpointIds.isEmpty()) + && authVersion.equalsIgnoreCase("v2.0")) { + throw new Throwable("Need to specify " + SERVICE_IDS); + } + + // Initialize Certificates + + String keyStore = filterConfig.getInitParameter(KEYSTORE); + String keyPass = filterConfig.getInitParameter(KEYSTORE_PASS); + String trustStore = filterConfig.getInitParameter(TRUSTSTORE); + String trustPass = filterConfig.getInitParameter(TRUSTSTORE_PASS); + + String adminToken = getValue(ADMIN_TOKEN, ""); + int timeout = getValue(CONN_TIMEOUT, 0); + boolean clientAuth = getValue(CONN_SSL_CLIENT_AUTH, true); + int maxActive = getValue(CONN_POOL_MAX_ACTIVE, 3); + int maxIdle = getValue(CONN_POOL_MAX_IDLE, 3); + long evictPeriod = getValue(CONN_POOL_EVICT_PERIOD, 60000L); + long minIdleTime = getValue(CONN_POOL_MIN_IDLE_TIME, 90000L); + retries = getValue(CONN_TIMEOUT_RETRIES, 3); + pauseTime = getValue(PAUSE_BETWEEN_RETRIES, 100); + delayAuthDecision = getValue(DELAY_AUTH_DECISION, false); + includeCatalog = getValue(INCLUDE_SERVICE_CATALOG, true); + adminAuthMethod = getValue(ADMIN_AUTH_METHOD, ""); + adminProjectId = getValue(ADMIN_PROJECT_ID, ""); + timeToCacheToken = getValue(TIME_TO_CACHE_TOKEN, 600); + long maxTokenCacheTime = getValue(MAX_TOKEN_CACHE_SIZE, 1048576); + + this.factory = AuthClientFactory.build(host, port, timeout, + clientAuth, null, null, trustStore, trustPass, + maxActive, maxIdle, evictPeriod, minIdleTime, adminToken); + + verifyRequiredParamsForAuthMethod(); + this.client = new TokenCache<>(timeToCacheToken, timeToCacheToken, map); + logger.info("Auth host (2-way SSL: " + clientAuth + "): " + host); + logger.info("Read Servlet Initialization Parameters "); + initialized = true; + } catch (Throwable t) { + logger.error("Failed to read Servlet Initialization Parameters ", + t.getMessage()); + throw new ServletException( + "Failed to read Servlet Initialization Parameters :: " + + t.getMessage(), t); + } + } + + public boolean isInitialized() { + return initialized; + } + + protected String getAdminProject() { + return adminProjectId; + } + + protected String getAdminAccessKey() { + if (context.getAttribute(ADMIN_ACCESS_KEY) != null) { + return (String) context.getAttribute(ADMIN_ACCESS_KEY); + } else { + return getValue(ADMIN_ACCESS_KEY, ""); + } + } + + protected String getAdminSecretKey() { + if (context.getAttribute(ADMIN_SECRET_KEY) != null) { + return (String) context.getAttribute(ADMIN_SECRET_KEY); + } else { + return getValue(ADMIN_SECRET_KEY, ""); + } + } + + protected String getAdminToken() { + return getValue(ADMIN_TOKEN, ""); + } + + protected String getAdminAuthMethod() { + return adminAuthMethod; + } + + protected String getAdminUser() { + if (context.getAttribute(ADMIN_USER) != null) { + return (String) context.getAttribute(ADMIN_USER); + } else { + return getValue(ADMIN_USER, ""); + } + } + + protected String getAdminPassword() { + if (context.getAttribute(ADMIN_PASSWORD) != null) { + String password = (String) context.getAttribute(ADMIN_PASSWORD); + return password; + } else { + return getValue(ADMIN_PASSWORD, ""); + } + } + + protected boolean isIncludeCatalog() { + return includeCatalog; + } + + + protected String getAuthVersion() { + return authVersion; + } + + protected ServletContext getConfig() { + return context; + } + + protected TokenCache getClient() { + return client; + } + + protected AuthClientFactory getFactory() { + return factory; + } + + protected String getServiceIds() { + return serviceIds; + } + + protected String getEndpointIds() { + return endpointIds; + } + + protected boolean isDelayAuthDecision() { + return delayAuthDecision; + } + + protected int getRetries() { + return retries; + } + + protected int getPauseTime() { + return pauseTime; + } + + public long getTimeToCacheToken() { + return timeToCacheToken; + } + + public void setTimeToCacheToken(long timeToCachedToken) { + this.timeToCacheToken = timeToCachedToken; + } + + public void setClient(TokenCache client) { + this.client = client; + } + + private T getValue(String paramName, T defaultValue) { + Class type = defaultValue.getClass(); + + String initparamValue = filterConfig.getInitParameter(paramName); + if (initparamValue != null && !initparamValue.isEmpty()) { + if (type.equals(Integer.class)) { + int paramValue = Integer.parseInt(initparamValue); + return (T) type.cast(paramValue); + } else if (type.equals(Long.class)) { + long paramValue = Long.parseLong(initparamValue); + return (T) type.cast(paramValue); + } else if (type.equals(Boolean.class)) { + boolean paramValue = Boolean.parseBoolean(initparamValue); + return (T) type.cast(paramValue); + } else if (type.equals(String.class)) { + return (T) type.cast(initparamValue); + } + } + return defaultValue; + } + + private void verifyRequiredParamsForAuthMethod() { + if (adminAuthMethod.equalsIgnoreCase(PASSWORD)) { + if (getAdminUser().isEmpty() || getAdminPassword().isEmpty()) { + String msg = String + .format("admin user and password must be specified if admin auth method is %s", + adminAuthMethod); + throw new AuthException(msg); + } + } else if (adminAuthMethod.equalsIgnoreCase(ACCESS_KEY)) { + if (getAdminAccessKey().isEmpty() || getAdminSecretKey().isEmpty()) { + String msg = String + .format("admin access and secret key must be specified if admin auth method is %s", + adminAuthMethod); + throw new AuthException(msg); + } + } + } +} diff --git a/java/mon-middleware/src/main/java/com/hpcloud/middleware/ExceptionHandlerUtil.java b/java/mon-middleware/src/main/java/com/hpcloud/middleware/ExceptionHandlerUtil.java new file mode 100644 index 00000000..00b88320 --- /dev/null +++ b/java/mon-middleware/src/main/java/com/hpcloud/middleware/ExceptionHandlerUtil.java @@ -0,0 +1,34 @@ +package com.hpcloud.middleware; + +public class ExceptionHandlerUtil { + + public final static String SERVICE_UNAVAILABLE = "Service Unavailable"; + public final static String UNAUTHORIZED_TOKEN = "Unauthorized Token"; + public final static String INTERNAL_SERVER_ERROR = "Internal Server Error"; + + private ExceptionHandlerUtil() { + } + + public static String getStatusText(int errorCode) { + if (errorCode == 401) { + return UNAUTHORIZED_TOKEN; + } + if (errorCode == 503) { + return SERVICE_UNAVAILABLE; + } + if (errorCode == 500) { + return INTERNAL_SERVER_ERROR; + } + return "Unknown Error"; + + } + + public static TokenExceptionHandler lookUpTokenException(Exception ex) { + try { + return TokenExceptionHandler.valueOf(ex.getClass().getSimpleName()); + } catch (IllegalArgumentException iae) { + return TokenExceptionHandler.valueOf("ResourceException"); + } + } + +} diff --git a/java/mon-middleware/src/main/java/com/hpcloud/middleware/FilterUtils.java b/java/mon-middleware/src/main/java/com/hpcloud/middleware/FilterUtils.java new file mode 100644 index 00000000..d922cab6 --- /dev/null +++ b/java/mon-middleware/src/main/java/com/hpcloud/middleware/FilterUtils.java @@ -0,0 +1,261 @@ +package com.hpcloud.middleware; + + +import static com.hpcloud.middleware.AuthConstants.AUTH_IDENTITY_STATUS; + +import static com.hpcloud.middleware.AuthConstants.AUTH_ROLES; +import static com.hpcloud.middleware.AuthConstants.AUTH_TENANT_NAME; + +import static com.hpcloud.middleware.AuthConstants.AUTH_USER_ID; +import static com.hpcloud.middleware.AuthConstants.AUTH_DOMAIN_ID; +import static com.hpcloud.middleware.AuthConstants.AUTH_DOMAIN_NAME; +import static com.hpcloud.middleware.AuthConstants.AUTH_PROJECT_ID; +import static com.hpcloud.middleware.AuthConstants.AUTH_PROJECT_NAME; +import static com.hpcloud.middleware.AuthConstants.AUTH_TENANT_ID; +import static com.hpcloud.middleware.AuthConstants.AUTH_USER_NAME; +import static com.hpcloud.middleware.AuthConstants.IdentityStatus; +import static com.hpcloud.middleware.AuthConstants.AUTH_PROJECT_DOMAIN_ID; +import static com.hpcloud.middleware.AuthConstants.AUTH_PROJECT_DOMAIN_NAME; +import static com.hpcloud.middleware.AuthConstants.AUTH_USER_DOMAIN_ID; +import static com.hpcloud.middleware.AuthConstants.AUTH_USER_DOMAIN_NAME; +import static com.hpcloud.middleware.AuthConstants.AUTH_HP_IDM_ROLES; +import static com.hpcloud.middleware.AuthConstants.AUTH_SERVICE_CATALOG; + +import java.io.IOException; +import java.lang.reflect.Modifier; +import java.util.Iterator; +import javax.servlet.ServletRequest; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; +import com.google.gson.JsonArray; +import com.google.gson.JsonElement; +import com.google.gson.JsonNull; +import com.google.gson.JsonObject; +import com.google.gson.JsonParser; + +public class FilterUtils { + + private FilterUtils() { + } + + private static final Config appConfig = Config.getInstance(); + + private static final Gson gson = new GsonBuilder() + .excludeFieldsWithModifiers(Modifier.PRIVATE, Modifier.FINAL) + .create(); + + // Thee faithful logger + private static final Logger logger = LoggerFactory + .getLogger(FilterUtils.class); + + public static void destroyFilter() { + + TokenCache client = appConfig.getClient(); + + if (client != null) + appConfig.setClient(null); + + AuthClientFactory factory = appConfig.getFactory(); + // Shutdown factory + if (factory != null) { + factory.shutdown(); + } + } + + public static ServletRequest wrapRequestFromHttpResponse( + ServletRequest req, String data) { + if (appConfig.getAuthVersion().equalsIgnoreCase("v2.0")) { + wrapRequestFromHttpV2Response(req, data); + + } else { + wrapRequestFromHttpV3Response(req, data); + } + return req; + } + + private static void wrapRequestFromHttpV3Response(ServletRequest req, + String data) { + StringBuilder tenants = new StringBuilder(); + StringBuilder nonTenants = new StringBuilder(); + JsonParser jp = new JsonParser(); + JsonObject token = jp.parse(data).getAsJsonObject().get("token") + .getAsJsonObject(); + // Domain Scoped Token + if (token.get("domain") != null) { + JsonObject domain = token.get("domain").getAsJsonObject(); + req.setAttribute(AUTH_DOMAIN_ID, domain.get("id").getAsString()); + if (domain.get("name") != null) { + req.setAttribute(AUTH_DOMAIN_NAME, domain.get("name") + .getAsString()); + } + } + // Project Scoped Token + if (token.get("project") != null) { + JsonObject project = token.get("project").getAsJsonObject(); + req.setAttribute(AUTH_PROJECT_ID, project.get("id").getAsString()); + req.setAttribute(AUTH_PROJECT_NAME, project.get("name") + .getAsString()); + + JsonObject projectDomain = project.get("domain").getAsJsonObject(); + // special case where the value of id is null and the + // projectDomain.get("id") != null + if (!projectDomain.get("id").equals(new JsonNull())) { + req.setAttribute(AUTH_PROJECT_DOMAIN_ID, projectDomain + .get("id").getAsString()); + } + if (projectDomain.get("name") != null) { + req.setAttribute(AUTH_PROJECT_DOMAIN_NAME, + projectDomain.get("name")); + } + } + // User info + if (token.get("user") != null) { + JsonObject user = token.get("user").getAsJsonObject(); + req.setAttribute(AUTH_USER_ID, user.get("id").getAsString()); + req.setAttribute(AUTH_USER_NAME, user.get("name").getAsString()); + + JsonObject userDomain = user.get("domain").getAsJsonObject(); + if (userDomain.get("id") != null) { + req.setAttribute(AUTH_USER_DOMAIN_ID, userDomain.get("id") + .getAsString()); + } + if (userDomain.get("name") != null) { + req.setAttribute(AUTH_USER_DOMAIN_NAME, userDomain.get("name") + .getAsString()); + } + + } + // Roles + JsonArray roles = token.getAsJsonArray("roles"); + if (roles != null) { + Iterator it = roles.iterator(); + StringBuilder roleBuilder = new StringBuilder(); + while (it.hasNext()) { + + //Changed to meet my purposes + JsonObject role = it.next().getAsJsonObject(); + String currentRole = role.get("name").getAsString(); + roleBuilder.append(currentRole).append(","); + } + //My changes to meet my needs + req.setAttribute(AUTH_ROLES, roleBuilder.toString()); + } + String tenantRoles = (tenants.length() > 0) ? tenants.substring(1) + : tenants.toString(); + String nonTenantRoles = (nonTenants.length() > 0) ? nonTenants + .substring(1) : nonTenants.toString(); + if (!tenantRoles.equals("")) { + req.setAttribute(AUTH_ROLES, tenantRoles); + } + if (!nonTenantRoles.equals("")) { + req.setAttribute(AUTH_HP_IDM_ROLES, nonTenantRoles); + } + // Catalog + if (token.get("catalog") != null && appConfig.isIncludeCatalog()) { + JsonArray catalog = token.get("catalog").getAsJsonArray(); + req.setAttribute(AUTH_SERVICE_CATALOG, catalog.toString()); + } + } + + private static void wrapRequestFromHttpV2Response(ServletRequest req, + String data) { + StringBuilder tenants = new StringBuilder(); + StringBuilder nonTenants = new StringBuilder(); + JsonParser jp = new JsonParser(); + JsonObject access = jp.parse(data).getAsJsonObject().get("access") + .getAsJsonObject(); + JsonObject token = access.get("token").getAsJsonObject(); + + // Tenant info + if (token.get("tenant") != null) { + JsonObject tenant = token.get("tenant").getAsJsonObject(); + + String id = tenant.get("id").getAsString(); + String name = tenant.get("name").getAsString(); + if (id != null) + req.setAttribute(AUTH_TENANT_ID, id); + if (name != null) + req.setAttribute(AUTH_TENANT_NAME, name); + } + // User info + if (access.get("user") != null) { + JsonObject user = access.get("user").getAsJsonObject(); + + String userId = user.get("id").getAsString(); + String username = user.get("name").getAsString(); + if (userId != null) + req.setAttribute(AUTH_USER_ID, userId); + if (username != null) + req.setAttribute(AUTH_USER_NAME, username); + // Roles + JsonArray roles = user.getAsJsonArray("roles"); + if (roles != null) { + Iterator it = roles.iterator(); + while (it.hasNext()) { + JsonObject role = it.next().getAsJsonObject(); + if (role.get("tenantId") != null) { + tenants.append(","); + tenants.append(role.get("name").getAsString()); + } else { + nonTenants.append(","); + nonTenants.append(role.get("name").getAsString()); + } + } + } + String tenantRoles = (tenants.length() > 0) ? tenants.substring(1) + : tenants.toString(); + if (!tenantRoles.equals("")) { + req.setAttribute(AUTH_ROLES, tenantRoles); + } + String nonTenantRoles = (nonTenants.length() > 0) ? nonTenants + .substring(1) : nonTenants.toString(); + if (!nonTenantRoles.equals("")) { + req.setAttribute(AUTH_HP_IDM_ROLES, nonTenantRoles); + } + } + // Service catalog + if (access.get("serviceCatalog") != null + && appConfig.isIncludeCatalog()) { + JsonArray serviceCatalog = access.get("serviceCatalog") + .getAsJsonArray(); + req.setAttribute(AUTH_SERVICE_CATALOG, serviceCatalog.toString()); + } + } + + public static ServletRequest wrapRequest(ServletRequest req, Object data) { + if (data == null) { + req.setAttribute(AUTH_IDENTITY_STATUS, + IdentityStatus.Invalid.toString()); + logger.debug("Failed Authentication. Setting identity status header to Invalid"); + } + req.setAttribute(AUTH_IDENTITY_STATUS, + IdentityStatus.Confirmed.toString()); + if (data instanceof String) { + wrapRequestFromHttpResponse(req, ((String) data)); + } + return req; + } + + // Insert token into cache + public static void cacheToken(String token, Object auth) { + appConfig.getClient().put(token, (String) auth); + } + + // Get token from cache + public static Object getCachedToken(String token) throws IOException { + return appConfig.getClient().getToken(token); + } + + public static void pause(long pauseTime) { + try { + Thread.currentThread().sleep(pauseTime); + } catch (InterruptedException e) { + logger.debug("Thread is interrupted while sleeping before " + + pauseTime + " seconds. "); + } + } +} diff --git a/java/mon-middleware/src/main/java/com/hpcloud/middleware/HttpAuthClient.java b/java/mon-middleware/src/main/java/com/hpcloud/middleware/HttpAuthClient.java new file mode 100644 index 00000000..f139ad03 --- /dev/null +++ b/java/mon-middleware/src/main/java/com/hpcloud/middleware/HttpAuthClient.java @@ -0,0 +1,304 @@ +package com.hpcloud.middleware; + +import static com.hpcloud.middleware.AuthConstants.TOKEN; +import static com.hpcloud.middleware.AuthConstants.AUTH_SUBJECT_TOKEN; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.io.UnsupportedEncodingException; +import java.net.ConnectException; +import java.net.URI; +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.Map; +import java.util.TimeZone; + +import org.apache.http.Header; +import org.apache.http.HttpEntity; +import org.apache.http.HttpResponse; +import org.apache.http.client.ClientProtocolException; +import org.apache.http.client.HttpClient; +import org.apache.http.client.methods.HttpGet; +import org.apache.http.client.methods.HttpPost; +import org.apache.http.entity.StringEntity; +import org.apache.http.message.BasicHeader; + +import com.google.gson.JsonObject; +import com.google.gson.JsonParser; + +public class HttpAuthClient implements AuthClient { + private static final String ACCESSKEY = "accesskey"; + private static final String PASSWORD = "password"; + private static final String SERVICE_IDS_PARAM = "serviceIds"; + private static final String ENDPOINT_IDS_PARAM = "endpointIds"; + private static final int DELTA_TIME_IN_SEC = 30; + private static SimpleDateFormat expiryFormat; + static { + expiryFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mmmmmm'Z'"); + expiryFormat.setTimeZone(TimeZone.getTimeZone("UTC")); + } + private final Config appConfig = Config.getInstance(); + + private HttpClient client; + private String adminToken; + private String adminTokenExpiry; + private URI uri; + + public HttpAuthClient(HttpClient client, URI uri) { + this.client = client; + this.uri = uri; + } + + @Override + public Object validateTokenForServiceEndpointV2(String token, + String serviceIds, String endpointIds, boolean includeCatalog) + throws ClientProtocolException { + String newUri = uri.toString() + "/v2.0/tokens/" + token; + return verifyUUIDToken(token, newUri, null, serviceIds, endpointIds); + } + + @Override + public Object validateTokenForServiceEndpointV3(String token, + Map inputParams) throws ClientProtocolException { + String newUri = uri.toString() + "/v3/auth/tokens/"; + Header[] header = new Header[1]; + header[0] = new BasicHeader(AUTH_SUBJECT_TOKEN, token); + String serviceIds = null; + String endpointIds = null; + if (inputParams.containsKey(SERVICE_IDS_PARAM)) + serviceIds = inputParams.get(SERVICE_IDS_PARAM); + if (inputParams.containsKey(ENDPOINT_IDS_PARAM)) + endpointIds = inputParams.get(ENDPOINT_IDS_PARAM); + return verifyUUIDToken(token, newUri, header, serviceIds, endpointIds); + } + + private Object verifyUUIDToken(String token, String newUri, + Header[] header, String serviceIds, String endpointIds) + throws ClientProtocolException { + HttpResponse response = sendGet(newUri, header, serviceIds, endpointIds); + + HttpEntity entity = response.getEntity(); + int code = response.getStatusLine().getStatusCode(); + + InputStream instream = null; + try { + if (code == 404) { + instream = entity.getContent(); + instream.close(); + throw new AuthException("Authorization failed for token: " + token); + } + + if (code != 200) { + adminToken = null; + instream = entity.getContent(); + instream.close(); + String reasonPhrase = response.getStatusLine().getReasonPhrase(); + + throw new AuthException("Failed to validate via HTTP " + code + + " " + reasonPhrase); + } + } catch(IOException e) { + throw new ClientProtocolException( + "IO Exception: problem closing stream ", e); + } + + + return parseResponse(response); + } + + private HttpResponse sendPost(String uri, StringEntity body) + throws ClientProtocolException { + HttpResponse response = null; + HttpPost post = new HttpPost(uri); + post.setHeader("Accept", "application/json"); + post.setHeader("Content-Type", "application/json"); + try { + post.setEntity(body); + response = client.execute(post); + int code = response.getStatusLine().getStatusCode(); + if (!(code == 201 || code == 200 || code == 203)) { + adminToken = null; + throw new AuthException( + "Failed to authenticate admin credentials " + code + + response.getStatusLine().getReasonPhrase()); + } + } catch (IOException e) { + post.abort(); + throw new ClientProtocolException( + "IO Exception during POST request ", e); + } + return response; + } + + private HttpResponse sendGet(String newUri, Header[] headers, + String serviceIds, String endpointIds) + throws ClientProtocolException { + HttpResponse response = null; + HttpGet get = null; + boolean hasServiceIds = false; + if (serviceIds != null && !serviceIds.isEmpty()) { + newUri += "?HP-IDM-serviceId=" + serviceIds; + hasServiceIds = true; + } + if (endpointIds != null && !endpointIds.isEmpty()) { + newUri += hasServiceIds ? "&HP-IDM-endpointTemplateId=" + + endpointIds : "?HP-IDM-endpointTemplateId=" + endpointIds; + } + + get = new HttpGet(newUri); + get.setHeader("Accept", "application/json"); + get.setHeader("Content-Type", "application/json"); + if (headers != null) { + for (Header header : headers) { + get.setHeader(header); + } + } + + if(!appConfig.getAdminToken().isEmpty()) { + get.setHeader(new BasicHeader(TOKEN, appConfig.getAdminToken())); + } + else if (!appConfig.getAdminAuthMethod().isEmpty()) { + get.setHeader(new BasicHeader(TOKEN, getAdminToken())); + } + + try { + response = client.execute(get); + + }catch(ConnectException c) { + get.abort(); + throw new UnavailableException(c.getMessage()); + } + catch (IOException e) { + get.abort(); + + throw new ClientProtocolException( + "IO Exception during GET request ", e); + } + return response; + } + + private String parseResponse(HttpResponse response) { + StringBuffer json = new StringBuffer(); + HttpEntity entity = response.getEntity(); + if (entity != null) { + InputStream instream; + try { + instream = entity.getContent(); + + BufferedReader reader = new BufferedReader( + new InputStreamReader(instream)); + String line = reader.readLine(); + while (line != null) { + json.append(line); + line = reader.readLine(); + } + instream.close(); + reader.close(); + } catch (Exception e) { + throw new AuthException("Failed to parse Http Response ", e); + } + } + + return json.toString(); + } + + private String getAdminToken() throws ClientProtocolException { + HttpResponse response; + String json; + JsonParser jp = new JsonParser(); + + if (adminTokenExpiry != null) { + if (isExpired(adminTokenExpiry)) { + adminToken = null; + } + } + if (adminToken == null) { + if (appConfig.getAuthVersion().equalsIgnoreCase("v2.0")) { + StringEntity params = getUnscopedV2AdminTokenRequest(); + String authUri = uri + "/v2.0/tokens"; + response = sendPost(authUri, params); + json = parseResponse(response); + JsonObject access = jp.parse(json).getAsJsonObject() + .get("access").getAsJsonObject(); + JsonObject token = access.get("token").getAsJsonObject(); + adminToken = token.get("id").getAsString(); + adminTokenExpiry = token.get("expires").getAsString(); + } else { + StringEntity params = getUnscopedV3AdminTokenRequest(); + String authUri = uri + "/v3/auth/tokens"; + response = sendPost(authUri, params); + adminToken = response.getFirstHeader(AUTH_SUBJECT_TOKEN) + .getValue(); + json = parseResponse(response); + JsonObject token = jp.parse(json).getAsJsonObject() + .get("token").getAsJsonObject(); + adminTokenExpiry = token.get("expires_at").getAsString(); + + } + } + return adminToken; + } + + private StringEntity getUnscopedV2AdminTokenRequest() { + StringBuffer bfr = new StringBuffer(); + if (appConfig.getAdminAuthMethod().equalsIgnoreCase(PASSWORD)) { + bfr.append("{\"auth\": {\"passwordCredentials\": {\"username\": \""); + bfr.append(appConfig.getAdminUser()); + bfr.append("\",\"password\": \""); + bfr.append(appConfig.getAdminPassword()); + if (appConfig.getAdminProject() != null && !appConfig.getAdminProject().isEmpty()) { + bfr.append("\"}, \"tenantId\": \""); + bfr.append(appConfig.getAdminProject()); + bfr.append("\"}}"); + } else { + bfr.append("\"}}}"); + } + try { + return new StringEntity(bfr.toString()); + } catch (UnsupportedEncodingException e) { + throw new AuthException("Invalid V2 authentication request " + + e); + } + } else { + String msg = String.format("Admin auth method %s not supported",appConfig.getAdminAuthMethod()); + throw new AuthException(msg); + } + } + + private StringEntity getUnscopedV3AdminTokenRequest() { + StringBuffer bfr = new StringBuffer(); + if (appConfig.getAdminAuthMethod().equalsIgnoreCase(PASSWORD)) { + bfr.append("{\"auth\": {\"identity\": {\"methods\": [\"password\"],\"password\": {\"user\": {\"name\": \""); + bfr.append(appConfig.getAdminUser()); + bfr.append("\",\"password\": \""); + bfr.append(appConfig.getAdminPassword()); + bfr.append("\",\"domain\": {\"id\": \"default\""); + bfr.append("}}}}}}"); + } else { + String msg = String.format("Admin auth method %s not supported",appConfig.getAdminAuthMethod()); + throw new AuthException(msg); + } + try { + return new StringEntity(bfr.toString()); + } catch (UnsupportedEncodingException e) { + throw new AuthException("Invalid V3 authentication request " + e); + } + } + + private boolean isExpired(String expires) { + Date tokenExpiryDate = null; + try { + tokenExpiryDate = expiryFormat.parse(expires); + } catch (ParseException e) { + return true; + } + Date current = new Date(); + return tokenExpiryDate.getTime() < (current.getTime() + DELTA_TIME_IN_SEC * 1000); + } + + public void reset() { } + +} diff --git a/java/mon-middleware/src/main/java/com/hpcloud/middleware/HttpClientFactory.java b/java/mon-middleware/src/main/java/com/hpcloud/middleware/HttpClientFactory.java new file mode 100644 index 00000000..79318302 --- /dev/null +++ b/java/mon-middleware/src/main/java/com/hpcloud/middleware/HttpClientFactory.java @@ -0,0 +1,29 @@ +package com.hpcloud.middleware; + +import org.apache.commons.pool.impl.GenericObjectPool; + +/** + * An HTTP factory. + * + * @author liemmn + */ +public class HttpClientFactory extends AuthClientFactory { + private HttpClientPoolFactory clientPool; + + HttpClientFactory(String host, int port, int timeout, boolean clientAuth, + String keyStore, String keyPass, String trustStore, + String trustPass, String adminToken, int maxActive, + long timeBetweenEvictionRunsMillis, long minEvictableIdleTimeMillis) { + clientPool = new HttpClientPoolFactory(host, port, timeout, clientAuth, + keyStore, keyPass, trustStore, trustPass, adminToken, + maxActive, timeBetweenEvictionRunsMillis, + minEvictableIdleTimeMillis); + pool = new GenericObjectPool(clientPool); + } + + @Override + public void shutdown() { + clientPool.shutDown(); + super.shutdown(); + } +} diff --git a/java/mon-middleware/src/main/java/com/hpcloud/middleware/HttpClientPoolFactory.java b/java/mon-middleware/src/main/java/com/hpcloud/middleware/HttpClientPoolFactory.java new file mode 100644 index 00000000..18609a17 --- /dev/null +++ b/java/mon-middleware/src/main/java/com/hpcloud/middleware/HttpClientPoolFactory.java @@ -0,0 +1,130 @@ +package com.hpcloud.middleware; + +import java.io.File; +import java.io.FileInputStream; +import java.net.URI; +import java.security.KeyStore; +import java.util.concurrent.TimeUnit; + +import org.apache.commons.pool.BasePoolableObjectFactory; +import org.apache.http.client.HttpClient; +import org.apache.http.conn.scheme.PlainSocketFactory; +import org.apache.http.conn.scheme.Scheme; +import org.apache.http.conn.scheme.SchemeRegistry; +import org.apache.http.conn.ssl.SSLSocketFactory; +import org.apache.http.impl.client.DefaultHttpClient; +import org.apache.http.impl.conn.PoolingClientConnectionManager; +import org.apache.http.params.BasicHttpParams; +import org.apache.http.params.CoreConnectionPNames; +import org.apache.http.params.HttpParams; + +/** + * A Http request pool factory. Based on Apache Commons Pool. Singleton. + * Note that the Apache HttpClient maintains its own connection pool and + * does not participate in Apache Commons pool' lifecycle other than creating + * HTTPRequests. + * + * @author liemmn + */ +public class HttpClientPoolFactory extends BasePoolableObjectFactory { + private URI uri; + private PoolingClientConnectionManager connMgr; + private HttpPoolCleaner cleaner; + private HttpClient client; + + HttpClientPoolFactory(String host, int port, int timeout, + boolean clientAuth, String keyStore, String keyPass, + String trustStore, String trustPass, String adminToken, + int maxActive, long timeBetweenEvictionRunsMillis, + long minEvictableIdleTimeMillis) { + // Setup auth URL + String protocol = (port == 35357) ? "https://" : "http://"; + String urlStr = protocol + host + ":" + port; + uri = URI.create(urlStr); + + // Setup connection pool + SchemeRegistry schemeRegistry = new SchemeRegistry(); + if (protocol.startsWith("https")) { + SSLSocketFactory sslf = sslFactory(keyStore, keyPass, trustStore, + trustPass, clientAuth); + schemeRegistry.register(new Scheme("https", port, sslf)); + } else { + schemeRegistry.register(new Scheme("http", port, PlainSocketFactory + .getSocketFactory())); + } + connMgr = new PoolingClientConnectionManager(schemeRegistry, + minEvictableIdleTimeMillis, TimeUnit.MILLISECONDS); + + connMgr.setMaxTotal(maxActive); + connMgr.setDefaultMaxPerRoute(maxActive); + + // Http connection timeout + HttpParams params = new BasicHttpParams(); + params.setParameter(CoreConnectionPNames.SO_TIMEOUT, timeout); + params.setParameter(CoreConnectionPNames.CONNECTION_TIMEOUT, timeout); + + // Create a single client + client = new DefaultHttpClient(connMgr, params); + + // Create and start the connection pool cleaner + cleaner = new HttpPoolCleaner(connMgr, timeBetweenEvictionRunsMillis, + minEvictableIdleTimeMillis); + new Thread(cleaner).start(); + + } + + @Override + public Object makeObject() throws Exception { + return new HttpAuthClient(client, uri); + } + + @Override + public void passivateObject(Object obj) throws Exception { + ((HttpAuthClient) obj).reset(); + } + + @Override + public void destroyObject(Object obj) throws Exception { + ((HttpAuthClient) obj).reset(); + obj = null; + } + + public void shutDown() { + // Shutdown all connections + connMgr.shutdown(); + // Shutdown connection pool cleaner + cleaner.shutdown(); + } + + // get a socket factory + private static SSLSocketFactory sslFactory(String keyStore, String keyPass, + String trustStore, String trustPass, boolean clientAuth) { + try { + // keystore + KeyStore ks = null; + if (clientAuth) { + ks = KeyStore.getInstance("jks"); + FileInputStream is1 = new FileInputStream(new File(keyStore)); + try { + ks.load(is1, keyPass.toCharArray()); + } finally { + is1.close(); + } + } + // truststore + KeyStore ts = KeyStore.getInstance("jks"); + FileInputStream is2 = new FileInputStream( + new File(trustStore)); + try { + ts.load(is2, trustPass.toCharArray()); + } finally { + is2.close(); + } + SSLSocketFactory sslf = new SSLSocketFactory(ks, keyPass, ts); + return sslf; + } catch (Exception e) { + throw new AuthConnectionException( + "Failed to create SSLSocketFactory", e); + } + } +} diff --git a/java/mon-middleware/src/main/java/com/hpcloud/middleware/HttpPoolCleaner.java b/java/mon-middleware/src/main/java/com/hpcloud/middleware/HttpPoolCleaner.java new file mode 100644 index 00000000..1d01bb57 --- /dev/null +++ b/java/mon-middleware/src/main/java/com/hpcloud/middleware/HttpPoolCleaner.java @@ -0,0 +1,56 @@ +package com.hpcloud.middleware; + +import java.util.concurrent.TimeUnit; + +import org.apache.http.conn.ClientConnectionManager; + +/** + * A runner to clean the connection pool! There should only be one! + * + * @author liemmn + * + */ +public class HttpPoolCleaner implements Runnable { + private final ClientConnectionManager connMgr; + private long timeBetweenEvictionRunsMillis, minEvictableIdleTimeMillis; + private volatile boolean shutdown; + + public HttpPoolCleaner(ClientConnectionManager connMgr, + long timeBetweenEvictionRunsMillis, long minEvictableIdleTimeMillis) { + this.connMgr = connMgr; + this.timeBetweenEvictionRunsMillis = timeBetweenEvictionRunsMillis; + this.minEvictableIdleTimeMillis = minEvictableIdleTimeMillis; + } + + /** + * Start the cleaner. + */ + @Override + public void run() { + try { + while (!shutdown) { + synchronized (this) { + wait(timeBetweenEvictionRunsMillis); + // Close expired connections + connMgr.closeExpiredConnections(); + // Close connections that have been idle longer than x sec + connMgr.closeIdleConnections(minEvictableIdleTimeMillis, + TimeUnit.MILLISECONDS); + } + } + } catch (InterruptedException ex) { + // terminate + } + } + + /** + * Shutdown the cleaner. + */ + public void shutdown() { + shutdown = true; + synchronized (this) { + notifyAll(); + } + } + +} diff --git a/java/mon-middleware/src/main/java/com/hpcloud/middleware/SignatureBuilderException.java b/java/mon-middleware/src/main/java/com/hpcloud/middleware/SignatureBuilderException.java new file mode 100644 index 00000000..b8c3b731 --- /dev/null +++ b/java/mon-middleware/src/main/java/com/hpcloud/middleware/SignatureBuilderException.java @@ -0,0 +1,15 @@ +package com.hpcloud.middleware; + +public class SignatureBuilderException extends RuntimeException { + + private static final long serialVersionUID = -2643382825421961020L; + + public SignatureBuilderException(String msg) { + super(msg); + } + public SignatureBuilderException(String msg, Exception e) { + super(msg, e); + } + + +} diff --git a/java/mon-middleware/src/main/java/com/hpcloud/middleware/SignatureExceptionHandler.java b/java/mon-middleware/src/main/java/com/hpcloud/middleware/SignatureExceptionHandler.java new file mode 100644 index 00000000..db5dc0d3 --- /dev/null +++ b/java/mon-middleware/src/main/java/com/hpcloud/middleware/SignatureExceptionHandler.java @@ -0,0 +1,79 @@ +package com.hpcloud.middleware; + +import java.io.IOException; + +import javax.servlet.ServletResponse; +import javax.servlet.http.HttpServletResponse; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + + +public enum SignatureExceptionHandler { + + AuthConnectionException { + @Override + public void onException(Exception e, ServletResponse resp) { + AuthConnectionException ae = (AuthConnectionException) e; + logger.error(ae.getMessage() + " " + ae); + try { + ((HttpServletResponse) resp).sendError( + HttpServletResponse.SC_UNAUTHORIZED, + ExceptionHandlerUtil.getStatusText(HttpServletResponse.SC_UNAUTHORIZED)); + } catch (IOException ie) { + logger.debug("Error in writing the HTTP response " + + ie.getMessage() + " " + ie); + } + } + }, + TException { + @Override + public void onException(Exception e, ServletResponse resp) { + // TException t = (TException) e; + //logger.error("Thrift Exception " + t.getMessage() + " " + t); + try { + ((HttpServletResponse) resp).sendError( + HttpServletResponse.SC_UNAUTHORIZED, + ExceptionHandlerUtil.getStatusText(HttpServletResponse.SC_UNAUTHORIZED)); + } catch (IOException ie) { + logger.debug("Error in writing the HTTP response " + + ie.getMessage() + " " + ie); + } + } + }, + SignatureBuilderException { + @Override + public void onException(Exception e, ServletResponse resp) { + SignatureBuilderException sbe = (SignatureBuilderException) e; + logger.error(sbe.getMessage() + " " + sbe); + try { + ((HttpServletResponse) resp).sendError( + HttpServletResponse.SC_UNAUTHORIZED, + ExceptionHandlerUtil.getStatusText(HttpServletResponse.SC_UNAUTHORIZED)); + } catch (IOException ie) { + logger.debug("Error in writing the HTTP response " + + ie.getMessage() + " " + ie); + } + } + }, + AuthException { + @Override + public void onException(Exception e, ServletResponse resp) { + AuthException ae = (AuthException) e; + logger.error(ae.getMessage() + " " + ae); + try { + ((HttpServletResponse) resp).sendError( + HttpServletResponse.SC_UNAUTHORIZED, + ExceptionHandlerUtil.getStatusText(HttpServletResponse.SC_UNAUTHORIZED)); + } catch (IOException ie) { + logger.debug("Error in writing the HTTP response " + + ie.getMessage() + " " + ie); + } + } + }; + + final Logger logger = LoggerFactory.getLogger(SignatureExceptionHandler.class); + + abstract void onException(Exception e, ServletResponse resp); + +} diff --git a/java/mon-middleware/src/main/java/com/hpcloud/middleware/TokenAuth.java b/java/mon-middleware/src/main/java/com/hpcloud/middleware/TokenAuth.java new file mode 100644 index 00000000..7dce0a62 --- /dev/null +++ b/java/mon-middleware/src/main/java/com/hpcloud/middleware/TokenAuth.java @@ -0,0 +1,144 @@ +package com.hpcloud.middleware; + +import java.io.IOException; +import org.apache.http.client.ClientProtocolException; +import java.util.HashMap; +import java.util.Map; + +import javax.servlet.Filter; +import javax.servlet.FilterChain; +import javax.servlet.FilterConfig; +import javax.servlet.ServletException; +import javax.servlet.ServletRequest; +import javax.servlet.ServletResponse; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * A token-based authentication filter. This filter uses Thrift protocol to + * communicate with the CS server. The token to validate is set via the header + * {@link #TOKEN}. + *

+ * A token is required to validate. However, if no token is presented, the + * filter will set the {@link #AUTH_IDENTITY_STATUS} request parameter to + * Invalid and let any other filter downstream to decide what to + * do. For instance, if a downstream filter knows how to deal with signature + * rather than tokens, then it will go ahead and validate with signatures. + *

+ * Upon successful validation, all the Auth request parameters will be + * populated, including information such as tenant, user and user roles, and + * passed down to the next filter downstream. + *

+ * Upon unsuccessful validation, this filter will terminate the request by + * returning a 401 (unauthorized). + * + * @author liemmn + * + */ +public class TokenAuth implements Filter, AuthConstants { + + private static final String TOKEN_NOTFOUND = "Bad Request: Token not found in the request"; + private static final String SERVICE_IDS_PARAM = "serviceIds"; + private static final String ENDPOINT_IDS_PARAM = "endpointIds"; + private static final String SERVICE_CATALOG_PARAM = "includeCatalog"; + private static final String API_VERSION_PARAM = "apiVersion"; + + private final Config appConfig = Config.getInstance(); + + private FilterConfig filterConfig; + + // Thee faithful logger + private static final Logger logger = LoggerFactory + .getLogger(TokenAuth.class); + + @Override + public void init(FilterConfig filterConfig) throws ServletException { + this.filterConfig = filterConfig; + } + + + /** + * {@inheritDoc} + */ + public void destroy() { + FilterUtils.destroyFilter(); + } + + /** + * {@inheritDoc} + */ + public void doFilter(ServletRequest req, ServletResponse resp, + FilterChain chain) throws IOException, ServletException { + Object auth = null; + int numberOfTries = 0; + if (!appConfig.isInitialized()) { + appConfig.initialize(filterConfig,req,getInputParams()); + } + int retries = appConfig.getRetries(); + long pauseTime = appConfig.getPauseTime(); + AuthClientFactory factory = appConfig.getFactory(); + + // Extract credential + String token = ((HttpServletRequest) req).getHeader(TOKEN); + + if (token == null) { + if (!appConfig.isDelayAuthDecision()) { + logger.error(HttpServletResponse.SC_UNAUTHORIZED + + " No token found."); + ((HttpServletResponse) resp).sendError( + HttpServletResponse.SC_UNAUTHORIZED, TOKEN_NOTFOUND); + return; + } else { + logger.info("No token found...Skipping"); + } + } else { + do { + try { + auth = FilterUtils.getCachedToken(token); + }catch(UnavailableException e) { + TokenExceptionHandler handler = TokenExceptionHandler + .valueOf("UnavailableException"); + handler.onException(e,resp,token); + } + catch(ClientProtocolException e) { + if (numberOfTries < retries) { + FilterUtils.pause(pauseTime); + logger.debug("Retrying connection after " + + pauseTime + " seconds."); + numberOfTries++; + continue; + } else { + logger.debug("Exhausted retries.."); + TokenExceptionHandler handler = TokenExceptionHandler + .valueOf("ClientProtocolException"); + handler.onException(e, resp, token); + } + return; + } + + }while(auth==null && numberOfTries<=retries); + } + req = FilterUtils.wrapRequest(req, auth); + logger.debug("TokenAuth: Forwarding down stream to next filter/servlet"); + // Forward downstream... + chain.doFilter(req, resp); + } + + private Map getInputParams() { + Map inputParams = new HashMap(); + if (appConfig.getServiceIds() != null) { + inputParams.put(SERVICE_IDS_PARAM, appConfig.getServiceIds()); + } + if (appConfig.getEndpointIds() != null) { + inputParams.put(ENDPOINT_IDS_PARAM, appConfig.getEndpointIds()); + } + inputParams.put(SERVICE_CATALOG_PARAM, String.valueOf(appConfig.isIncludeCatalog())); + inputParams.put(API_VERSION_PARAM, appConfig.getAuthVersion()); + return inputParams; + } + + +} diff --git a/java/mon-middleware/src/main/java/com/hpcloud/middleware/TokenCache.java b/java/mon-middleware/src/main/java/com/hpcloud/middleware/TokenCache.java new file mode 100644 index 00000000..473518ae --- /dev/null +++ b/java/mon-middleware/src/main/java/com/hpcloud/middleware/TokenCache.java @@ -0,0 +1,66 @@ +package com.hpcloud.middleware; + +import com.google.common.cache.*; +import org.apache.http.client.ClientProtocolException; +import org.apache.thrift.TException; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.Map; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.TimeUnit; + + +public class TokenCache { + + private final LoadingCache cache; + private final Config appConfig = Config.getInstance(); + private AuthClientFactory factory; + private AuthClient client; + private static final Logger logger = LoggerFactory + .getLogger(TokenCache.class); + + + public TokenCache(final long maxSize, final long timeToExpire, final Map map) { + factory = appConfig.getFactory(); + + cache = CacheBuilder.newBuilder().maximumSize(maxSize) + .expireAfterWrite(timeToExpire, TimeUnit.SECONDS) + .build(new CacheLoader() { + public V load(K key) throws TException, ClientProtocolException { + + V value = null; + AuthClient client = null; + + try { + client = factory.getClient(); + if (appConfig.getAuthVersion().equals("v2.0")) { + value = (V) client.validateTokenForServiceEndpointV2((String) key, appConfig.getServiceIds(), + appConfig.getEndpointIds(), appConfig.isIncludeCatalog()); + } else { + value = (V) client.validateTokenForServiceEndpointV3((String) key, map); + } + } finally { + if (client != null) + factory.recycle(client); + } + return value; + } + }); + } + + public V getToken(K key) throws ClientProtocolException { + V value = null; + try { + value = cache.get(key); + } catch (ExecutionException e) { + logger.debug("had problem caching token"); + } + return value; + } + + public void put(K key, V value) { + cache.put(key, value); + } + +} diff --git a/java/mon-middleware/src/main/java/com/hpcloud/middleware/TokenExceptionHandler.java b/java/mon-middleware/src/main/java/com/hpcloud/middleware/TokenExceptionHandler.java new file mode 100644 index 00000000..9ffac02e --- /dev/null +++ b/java/mon-middleware/src/main/java/com/hpcloud/middleware/TokenExceptionHandler.java @@ -0,0 +1,106 @@ +package com.hpcloud.middleware; + +import java.io.IOException; + +import org.apache.http.client.ClientProtocolException; + +import javax.servlet.ServletResponse; +import javax.servlet.http.HttpServletResponse; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import org.apache.thrift.TException; + +public enum TokenExceptionHandler { + + AuthConnectionException { + @Override + public void onException(Exception e, ServletResponse resp, String token) { + AuthConnectionException ae = (AuthConnectionException) e; + logger.error(ae.getMessage() + " " + ae); + try { + ((HttpServletResponse) resp).sendError( + HttpServletResponse.SC_UNAUTHORIZED, + ExceptionHandlerUtil.getStatusText(HttpServletResponse.SC_UNAUTHORIZED) + + " " + token); + } catch (IOException ie) { + logger.debug("Error in writing the HTTP response " + + ie.getMessage() + " " + ie); + } + } + }, + TException { + @Override + public void onException(Exception e, ServletResponse resp, String token) { + TException t = (TException) e; + logger.error("Thrift Exception " + t.getMessage() + " " + t); + try { + ((HttpServletResponse) resp).sendError( + HttpServletResponse.SC_UNAUTHORIZED, + ExceptionHandlerUtil.getStatusText(HttpServletResponse.SC_UNAUTHORIZED) + + " " + token); + } catch (IOException ie) { + logger.debug("Error in writing the HTTP response " + + ie.getMessage() + " " + ie); + } + } + }, + ClientProtocolException { + @Override + public void onException(Exception e, ServletResponse resp, String token) { + ClientProtocolException t = (ClientProtocolException) e; + logger.error("Http Client Exception " + t.getMessage() + " " + t); + try { + ((HttpServletResponse) resp).sendError( + HttpServletResponse.SC_UNAUTHORIZED, + ExceptionHandlerUtil.getStatusText(HttpServletResponse.SC_UNAUTHORIZED) + + " " + token); + } catch (IOException ie) { + logger.debug("Error in writing the HTTP response " + + ie.getMessage() + " " + ie); + } + } + }, + AuthException { + @Override + public void onException(Exception e, ServletResponse resp, String token) { + AuthException ae = (AuthException) e; + logger.error(ae.getMessage() + " " + ae); + String statusText = ae.getMessage(); + if (statusText == null || statusText.isEmpty()) { + statusText = ExceptionHandlerUtil.getStatusText(HttpServletResponse.SC_UNAUTHORIZED); + } + try { + ((HttpServletResponse) resp).sendError( + HttpServletResponse.SC_UNAUTHORIZED, + statusText + " " + token); + } catch (IOException ie) { + logger.debug("Error in writing the HTTP response " + + ie.getMessage() + " " + ie); + } + } + }, ServiceUnavailableException { + @Override + public void onException(Exception e, ServletResponse resp, String token) { + AuthException ae = (AuthException) e; + logger.error(ae.getMessage() + " " + ae); + String statusText = ae.getMessage(); + if (statusText == null || statusText.isEmpty()) { + statusText = ExceptionHandlerUtil.getStatusText(HttpServletResponse.SC_UNAUTHORIZED); + } + try { + ((HttpServletResponse) resp).sendError( + HttpServletResponse.SC_UNAUTHORIZED, + statusText + " " + token); + } catch (IOException ie) { + logger.debug("Error in writing the HTTP response " + + ie.getMessage() + " " + ie); + } + } + }; + + final Logger logger = LoggerFactory.getLogger(TokenExceptionHandler.class); + + abstract void onException(Exception e, ServletResponse resp, String token); +} diff --git a/java/mon-middleware/src/main/java/com/hpcloud/middleware/UnavailableException.java b/java/mon-middleware/src/main/java/com/hpcloud/middleware/UnavailableException.java new file mode 100644 index 00000000..c07cacac --- /dev/null +++ b/java/mon-middleware/src/main/java/com/hpcloud/middleware/UnavailableException.java @@ -0,0 +1,17 @@ +package com.hpcloud.middleware; + +/** + * Created by johnderr on 6/25/14. + */ +public class UnavailableException extends RuntimeException { + + private static final long serialVersionUID = -2353922744077869466L; + + public UnavailableException(String msg) { + super(msg); + } + + public UnavailableException(String msg, Exception e) { + super(msg, e); + } +}