You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ambari.apache.org by nc...@apache.org on 2017/12/21 14:36:27 UTC

[01/24] ambari git commit: AMBARI-22648: zeppelin server keytab missing from zeppelin-site.xml (Bikas Saha via jluniya)

Repository: ambari
Updated Branches:
  refs/heads/branch-feature-AMBARI-21674 37361fd3f -> 41c1e647c


AMBARI-22648: zeppelin server keytab missing from zeppelin-site.xml (Bikas Saha via jluniya)


Project: http://git-wip-us.apache.org/repos/asf/ambari/repo
Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/d95d3ebe
Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/d95d3ebe
Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/d95d3ebe

Branch: refs/heads/branch-feature-AMBARI-21674
Commit: d95d3ebeaf9e5334828ebc5d16fa223895f49f36
Parents: dc31e51
Author: Jayush Luniya <jl...@hortonworks.com>
Authored: Thu Dec 14 16:41:43 2017 -0800
Committer: Jayush Luniya <jl...@hortonworks.com>
Committed: Thu Dec 14 16:41:43 2017 -0800

----------------------------------------------------------------------
 .../common-services/ZEPPELIN/0.7.0/package/scripts/master.py | 8 +++++++-
 .../src/test/python/stacks/2.6/configs/default.json          | 2 ++
 2 files changed, 9 insertions(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ambari/blob/d95d3ebe/ambari-server/src/main/resources/common-services/ZEPPELIN/0.7.0/package/scripts/master.py
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/common-services/ZEPPELIN/0.7.0/package/scripts/master.py b/ambari-server/src/main/resources/common-services/ZEPPELIN/0.7.0/package/scripts/master.py
index ee264a4..df892f8 100644
--- a/ambari-server/src/main/resources/common-services/ZEPPELIN/0.7.0/package/scripts/master.py
+++ b/ambari-server/src/main/resources/common-services/ZEPPELIN/0.7.0/package/scripts/master.py
@@ -137,9 +137,15 @@ class Master(Script):
     self.chown_zeppelin_pid_dir(env)
 
     # write out zeppelin-site.xml
+    my_map = {}
+    for key, value in params.config['configurations']['zeppelin-config'].iteritems():
+      my_map[key]=value
+    my_map['zeppelin.server.kerberos.keytab']=params.zeppelin_kerberos_keytab
+    my_map['zeppelin.server.kerberos.principal']=params.zeppelin_kerberos_principal
+
     XmlConfig("zeppelin-site.xml",
               conf_dir=params.conf_dir,
-              configurations=params.config['configurations']['zeppelin-config'],
+              configurations=my_map,
               owner=params.zeppelin_user,
               group=params.zeppelin_group
               )

http://git-wip-us.apache.org/repos/asf/ambari/blob/d95d3ebe/ambari-server/src/test/python/stacks/2.6/configs/default.json
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/python/stacks/2.6/configs/default.json b/ambari-server/src/test/python/stacks/2.6/configs/default.json
index 10647fd..fb7cb49 100644
--- a/ambari-server/src/test/python/stacks/2.6/configs/default.json
+++ b/ambari-server/src/test/python/stacks/2.6/configs/default.json
@@ -362,6 +362,8 @@
       "zeppelin.notebook.s3.bucket": "zeppelin",
       "zeppelin.notebook.homescreen.hide": "false",
       "zeppelin.server.allowed.origins": "*",
+      "zeppelin.server.kerberos.keytab": "",
+      "zeppelin.server.kerberos.principal": "",
       "zeppelin.interpreter.config.upgrade": "true"
     },
     "zoo.cfg": {


[05/24] ambari git commit: AMBARI-22661 Storm service check fails with StormAtlasHook CNF after cluster deploy (dgrinenko)

Posted by nc...@apache.org.
AMBARI-22661 Storm service check fails with StormAtlasHook CNF after cluster deploy (dgrinenko)


Project: http://git-wip-us.apache.org/repos/asf/ambari/repo
Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/ab342d77
Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/ab342d77
Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/ab342d77

Branch: refs/heads/branch-feature-AMBARI-21674
Commit: ab342d77fab0baca7baabc23af8a6f86422c0642
Parents: 856d9a5
Author: Dmytro Grinenko <ha...@apache.org>
Authored: Sat Dec 16 19:26:43 2017 +0200
Committer: Dmytro Grinenko <ha...@apache.org>
Committed: Sat Dec 16 19:27:19 2017 +0200

----------------------------------------------------------------------
 .../libraries/functions/setup_atlas_hook.py              | 11 +++--------
 1 file changed, 3 insertions(+), 8 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ambari/blob/ab342d77/ambari-common/src/main/python/resource_management/libraries/functions/setup_atlas_hook.py
----------------------------------------------------------------------
diff --git a/ambari-common/src/main/python/resource_management/libraries/functions/setup_atlas_hook.py b/ambari-common/src/main/python/resource_management/libraries/functions/setup_atlas_hook.py
index 367afc8..985eb37 100644
--- a/ambari-common/src/main/python/resource_management/libraries/functions/setup_atlas_hook.py
+++ b/ambari-common/src/main/python/resource_management/libraries/functions/setup_atlas_hook.py
@@ -162,14 +162,9 @@ def setup_atlas_jar_symlinks(hook_name, jar_source_dir):
   import params
 
   stack_root = Script.get_stack_root()
-  atlas_home_dir = os.path.join(stack_root, "current", "atlas-server")
-
-  # if this is an upgrade/downagrade, then we must link in the correct version
-  # which may not be "current", so change the home directory location
-  upgrade_type = Script.get_upgrade_type(default("/commandParams/upgrade_type", ""))
-  if upgrade_type is not None:
-    version_dir_segment = stack_features.get_stack_feature_version(Script.get_config())
-    atlas_home_dir = os.path.join(stack_root, version_dir_segment, "atlas")
+  atlas_component_name = "atlas"
+  stack_version = stack_features.get_stack_feature_version(Script.get_config())
+  atlas_home_dir = os.path.join(stack_root, stack_version, atlas_component_name)
 
   # Will only exist if this host contains Atlas Server
   atlas_hook_dir = os.path.join(atlas_home_dir, "hook", hook_name)


[09/24] ambari git commit: AMBARI-22640 - HBase Cannot Find LZO Classes After Being Patched (jonathanhurley)

Posted by nc...@apache.org.
AMBARI-22640 - HBase Cannot Find LZO Classes After Being Patched (jonathanhurley)


Project: http://git-wip-us.apache.org/repos/asf/ambari/repo
Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/eab6722f
Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/eab6722f
Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/eab6722f

Branch: refs/heads/branch-feature-AMBARI-21674
Commit: eab6722f705f24a1d731fa39b5e220578e231478
Parents: 562795c
Author: Jonathan Hurley <jh...@hortonworks.com>
Authored: Tue Dec 12 16:18:47 2017 -0500
Committer: Jonathan Hurley <jh...@hortonworks.com>
Committed: Mon Dec 18 14:34:52 2017 -0500

----------------------------------------------------------------------
 .../HBASE/0.96.0.2.0/package/scripts/hbase.py   | 26 ++++++++-----
 .../HBASE/2.0.0.3.0/package/scripts/hbase.py    | 39 ++++++++++++--------
 2 files changed, 41 insertions(+), 24 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ambari/blob/eab6722f/ambari-server/src/main/resources/common-services/HBASE/0.96.0.2.0/package/scripts/hbase.py
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/common-services/HBASE/0.96.0.2.0/package/scripts/hbase.py b/ambari-server/src/main/resources/common-services/HBASE/0.96.0.2.0/package/scripts/hbase.py
index cec6b2a..6490b59 100644
--- a/ambari-server/src/main/resources/common-services/HBASE/0.96.0.2.0/package/scripts/hbase.py
+++ b/ambari-server/src/main/resources/common-services/HBASE/0.96.0.2.0/package/scripts/hbase.py
@@ -18,18 +18,23 @@ limitations under the License.
 
 """
 from urlparse import urlparse
+
 import os
-import sys
-from resource_management.libraries.script.script import Script
-from resource_management.libraries.resources.xml_config import XmlConfig
-from resource_management.libraries.resources.template_config import TemplateConfig
-from resource_management.libraries.functions.format import format
-from resource_management.core.source import Template, InlineTemplate
-from resource_management.core.resources import Package
-from resource_management.core.resources.service import ServiceConfig
-from resource_management.core.resources.system import Directory, Execute, File
+
 from ambari_commons.os_family_impl import OsFamilyFuncImpl, OsFamilyImpl
 from ambari_commons import OSConst
+from resource_management.core.resources import Directory
+from resource_management.core.resources import Execute
+from resource_management.core.resources import File
+from resource_management.core.resources import Package
+from resource_management.core.resources import ServiceConfig
+from resource_management.core.source import InlineTemplate
+from resource_management.core.source import Template
+from resource_management.libraries import Script
+from resource_management.libraries.functions import format
+from resource_management.libraries.functions import lzo_utils
+from resource_management.libraries.resources import TemplateConfig
+from resource_management.libraries.resources import XmlConfig
 from resource_management.libraries.functions.constants import StackFeature
 from resource_management.libraries.functions.stack_features import check_stack_feature
 
@@ -55,6 +60,9 @@ def hbase(name=None):
 def hbase(name=None):
   import params
 
+  # ensure that matching LZO libraries are installed for HBase
+  lzo_utils.install_lzo_if_needed()
+
   Directory( params.etc_prefix_dir,
       mode=0755
   )

http://git-wip-us.apache.org/repos/asf/ambari/blob/eab6722f/ambari-server/src/main/resources/common-services/HBASE/2.0.0.3.0/package/scripts/hbase.py
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/common-services/HBASE/2.0.0.3.0/package/scripts/hbase.py b/ambari-server/src/main/resources/common-services/HBASE/2.0.0.3.0/package/scripts/hbase.py
index fced4fc..1a25095 100644
--- a/ambari-server/src/main/resources/common-services/HBASE/2.0.0.3.0/package/scripts/hbase.py
+++ b/ambari-server/src/main/resources/common-services/HBASE/2.0.0.3.0/package/scripts/hbase.py
@@ -17,18 +17,24 @@ See the License for the specific language governing permissions and
 limitations under the License.
 
 """
+from urlparse import urlparse
+
 import os
-import sys
-from resource_management.libraries.script.script import Script
-from resource_management.libraries.resources.xml_config import XmlConfig
-from resource_management.libraries.resources.template_config import TemplateConfig
-from resource_management.libraries.functions.format import format
-from resource_management.core.source import Template, InlineTemplate
-from resource_management.core.resources import Package
-from resource_management.core.resources.service import ServiceConfig
-from resource_management.core.resources.system import Directory, Execute, File
+
 from ambari_commons.os_family_impl import OsFamilyFuncImpl, OsFamilyImpl
 from ambari_commons import OSConst
+from resource_management.core.resources import Directory
+from resource_management.core.resources import Execute
+from resource_management.core.resources import File
+from resource_management.core.resources import Package
+from resource_management.core.resources import ServiceConfig
+from resource_management.core.source import InlineTemplate
+from resource_management.core.source import Template
+from resource_management.libraries import Script
+from resource_management.libraries.functions import format
+from resource_management.libraries.functions import lzo_utils
+from resource_management.libraries.resources import TemplateConfig
+from resource_management.libraries.resources import XmlConfig
 from resource_management.libraries.functions.constants import StackFeature
 from resource_management.libraries.functions.stack_features import check_stack_feature
 
@@ -54,6 +60,9 @@ def hbase(name=None):
 def hbase(name=None):
   import params
 
+  # ensure that matching LZO libraries are installed for HBase
+  lzo_utils.install_lzo_if_needed()
+
   Directory( params.etc_prefix_dir,
       mode=0755
   )
@@ -63,7 +72,7 @@ def hbase(name=None):
       group = params.user_group,
       create_parents = True
   )
-   
+
   Directory(params.java_io_tmpdir,
       create_parents = True,
       mode=0777
@@ -83,7 +92,7 @@ def hbase(name=None):
           create_parents = True,
           mode = 0755
       )
-  
+
   parent_dir = os.path.dirname(params.tmp_dir)
   # In case if we have several placeholders in path
   while ("${" in parent_dir):
@@ -136,7 +145,7 @@ def hbase(name=None):
             group = params.user_group
     )
   # Manually overriding ownership of file installed by hadoop package
-  else: 
+  else:
     File( format("{params.hbase_conf_dir}/hbase-policy.xml"),
       owner = params.hbase_user,
       group = params.user_group
@@ -147,14 +156,14 @@ def hbase(name=None):
        content=InlineTemplate(params.hbase_env_sh_template),
        group = params.user_group,
   )
-  
+
   # On some OS this folder could be not exists, so we will create it before pushing there files
   Directory(params.limits_conf_dir,
             create_parents = True,
             owner='root',
             group='root'
             )
-  
+
   File(os.path.join(params.limits_conf_dir, 'hbase.conf'),
        owner='root',
        group='root',
@@ -174,7 +183,7 @@ def hbase(name=None):
       cd_access = "a",
       mode = 0755,
     )
-  
+
     Directory (params.log_dir,
       owner = params.hbase_user,
       create_parents = True,


[11/24] ambari git commit: AMBARI-22655 - Livy/Livy2 Unable To Start Due to Address Already In Use (jonathanhurley)

Posted by nc...@apache.org.
AMBARI-22655 - Livy/Livy2 Unable To Start Due to Address Already In Use (jonathanhurley)


Project: http://git-wip-us.apache.org/repos/asf/ambari/repo
Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/fded8228
Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/fded8228
Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/fded8228

Branch: refs/heads/branch-feature-AMBARI-21674
Commit: fded8228015231afcae0900502db27ddc863773a
Parents: 1d87b21
Author: Jonathan Hurley <jh...@hortonworks.com>
Authored: Thu Dec 14 21:59:19 2017 -0500
Committer: Jonathan Hurley <jh...@hortonworks.com>
Committed: Mon Dec 18 15:47:45 2017 -0500

----------------------------------------------------------------------
 .../SPARK/1.2.1/package/scripts/livy_service.py | 22 +++++++++------
 .../SPARK/2.2.0/package/scripts/livy_service.py | 29 +++++++++-----------
 .../2.0.0/package/scripts/livy2_service.py      | 27 ++++++++----------
 .../SPARK2/2.0.0/package/scripts/setup_livy2.py |  2 ++
 .../HDP/2.0.6/properties/stack_packages.json    |  8 +++++-
 .../HDP/3.0/properties/stack_packages.json      |  8 +++++-
 .../python/stacks/2.5/SPARK/test_spark_livy.py  |  3 +-
 .../stacks/2.6/SPARK2/test_spark_livy2.py       |  5 +++-
 8 files changed, 60 insertions(+), 44 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ambari/blob/fded8228/ambari-server/src/main/resources/common-services/SPARK/1.2.1/package/scripts/livy_service.py
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/common-services/SPARK/1.2.1/package/scripts/livy_service.py b/ambari-server/src/main/resources/common-services/SPARK/1.2.1/package/scripts/livy_service.py
index cce2148..add5a77 100644
--- a/ambari-server/src/main/resources/common-services/SPARK/1.2.1/package/scripts/livy_service.py
+++ b/ambari-server/src/main/resources/common-services/SPARK/1.2.1/package/scripts/livy_service.py
@@ -21,28 +21,32 @@ limitations under the License.
 from resource_management.libraries.functions import format
 from resource_management.core.resources.system import File, Execute
 from resource_management.libraries.functions import get_user_call_output
-import threading
 
 def livy_service(name, upgrade_type=None, action=None):
   import params
 
-  livyserver_no_op_test = format(
-    'ls {livy_server_pid_file} >/dev/null 2>&1 && ps -p `cat {livy_server_pid_file}` >/dev/null 2>&1')
+  # use the livy user to get the PID (it is protected on non-root systems)
+  livy_server_pid = get_user_call_output.get_user_call_output(format("cat {livy_server_pid_file}"),
+    user=params.livy_user, is_checked_call=False)[1]
+
+  livy_server_pid = livy_server_pid.replace("\n", " ")
+
+  process_id_exists_command = format("ls {livy_server_pid_file} >/dev/null 2>&1 && ps -p {livy_server_pid} >/dev/null 2>&1")
+
   if action == 'start':
     Execute(format('{livy_server_start}'),
             user=params.livy_user,
             environment={'JAVA_HOME': params.java_home},
-            not_if=livyserver_no_op_test)
+            not_if=process_id_exists_command
+    )
 
   elif action == 'stop':
-    pid = get_user_call_output.get_user_call_output(
-      format("! test -f {livy_server_pid_file} ||  cat {livy_server_pid_file}"), user=params.livy_user)[1]
-    pid = pid.replace("\n", " ")
     Execute(format('{livy_server_stop}'),
             user=params.livy_user,
-            only_if=livyserver_no_op_test,
+            only_if=process_id_exists_command,
             timeout=10,
-            on_timeout=format("! ( {livyserver_no_op_test} ) || {sudo} -H -E kill -9 {pid}"),
+            on_timeout=format("! ( {process_id_exists_command} ) || {sudo} -H -E kill -9 {livy_server_pid}"),
             environment={'JAVA_HOME': params.java_home}
             )
+
     File(params.livy_server_pid_file, action="delete")

http://git-wip-us.apache.org/repos/asf/ambari/blob/fded8228/ambari-server/src/main/resources/common-services/SPARK/2.2.0/package/scripts/livy_service.py
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/common-services/SPARK/2.2.0/package/scripts/livy_service.py b/ambari-server/src/main/resources/common-services/SPARK/2.2.0/package/scripts/livy_service.py
index 273b056..add5a77 100644
--- a/ambari-server/src/main/resources/common-services/SPARK/2.2.0/package/scripts/livy_service.py
+++ b/ambari-server/src/main/resources/common-services/SPARK/2.2.0/package/scripts/livy_service.py
@@ -21,35 +21,32 @@ limitations under the License.
 from resource_management.libraries.functions import format
 from resource_management.core.resources.system import File, Execute
 from resource_management.libraries.functions import get_user_call_output
-import threading
 
 def livy_service(name, upgrade_type=None, action=None):
   import params
 
-  livyserver_no_op_test = format(
-    'ls {livy_server_pid_file} >/dev/null 2>&1 && ps -p `cat {livy_server_pid_file}` >/dev/null 2>&1')
+  # use the livy user to get the PID (it is protected on non-root systems)
+  livy_server_pid = get_user_call_output.get_user_call_output(format("cat {livy_server_pid_file}"),
+    user=params.livy_user, is_checked_call=False)[1]
+
+  livy_server_pid = livy_server_pid.replace("\n", " ")
+
+  process_id_exists_command = format("ls {livy_server_pid_file} >/dev/null 2>&1 && ps -p {livy_server_pid} >/dev/null 2>&1")
+
   if action == 'start':
     Execute(format('{livy_server_start}'),
             user=params.livy_user,
             environment={'JAVA_HOME': params.java_home},
-            not_if=livyserver_no_op_test
-            )
+            not_if=process_id_exists_command
+    )
 
   elif action == 'stop':
-    pid = get_user_call_output.get_user_call_output(
-      format("! test -f {livy_server_pid_file} ||  cat {livy_server_pid_file}"), user=params.livy_user)[1]
-    pid = pid.replace("\n", " ")
     Execute(format('{livy_server_stop}'),
             user=params.livy_user,
-            only_if=livyserver_no_op_test,
+            only_if=process_id_exists_command,
             timeout=10,
-            on_timeout=format("! ( {livyserver_no_op_test} ) || {sudo} -H -E kill -9 {pid}"),
+            on_timeout=format("! ( {process_id_exists_command} ) || {sudo} -H -E kill -9 {livy_server_pid}"),
             environment={'JAVA_HOME': params.java_home}
             )
-    File(params.livy_server_pid_file,
-        action="delete"
-        )
-
-
-
 
+    File(params.livy_server_pid_file, action="delete")

http://git-wip-us.apache.org/repos/asf/ambari/blob/fded8228/ambari-server/src/main/resources/common-services/SPARK2/2.0.0/package/scripts/livy2_service.py
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/common-services/SPARK2/2.0.0/package/scripts/livy2_service.py b/ambari-server/src/main/resources/common-services/SPARK2/2.0.0/package/scripts/livy2_service.py
index dfadd84..0180a31 100644
--- a/ambari-server/src/main/resources/common-services/SPARK2/2.0.0/package/scripts/livy2_service.py
+++ b/ambari-server/src/main/resources/common-services/SPARK2/2.0.0/package/scripts/livy2_service.py
@@ -21,35 +21,32 @@ limitations under the License.
 from resource_management.libraries.functions import format
 from resource_management.core.resources.system import File, Execute
 from resource_management.libraries.functions import get_user_call_output
-import threading
 
 def livy2_service(name, upgrade_type=None, action=None):
   import params
 
-  livyserver_no_op_test = format(
-    'ls {livy2_server_pid_file} >/dev/null 2>&1 && ps -p `cat {livy2_server_pid_file}` >/dev/null 2>&1')
+  # use the livy2 user to get the PID (it is protected on non-root systems)
+  livy2_server_pid = get_user_call_output.get_user_call_output(format("cat {livy2_server_pid_file}"),
+    user=params.livy2_user, is_checked_call=False)[1]
+
+  livy2_server_pid = livy2_server_pid.replace("\n", " ")
+
+  process_id_exists_command = format("ls {livy2_server_pid_file} >/dev/null 2>&1 && ps -p {livy2_server_pid} >/dev/null 2>&1")
+
   if action == 'start':
     Execute(format('{livy2_server_start}'),
             user=params.livy2_user,
             environment={'JAVA_HOME': params.java_home},
-            not_if=livyserver_no_op_test
+            not_if=process_id_exists_command
     )
 
   elif action == 'stop':
-    pid = get_user_call_output.get_user_call_output(
-      format("! test -f {livy2_server_pid_file} ||  cat {livy2_server_pid_file}"), user=params.livy2_user)[1]
-    pid = pid.replace("\n", " ")
     Execute(format('{livy2_server_stop}'),
             user=params.livy2_user,
-            only_if=livyserver_no_op_test,
+            only_if=process_id_exists_command,
             timeout=10,
-            on_timeout=format("! ( {livyserver_no_op_test} ) || {sudo} -H -E kill -9 {pid}"),
+            on_timeout=format("! ( {process_id_exists_command} ) || {sudo} -H -E kill -9 {livy2_server_pid}"),
             environment={'JAVA_HOME': params.java_home}
             )
-    File(params.livy2_server_pid_file,
-        action="delete"
-        )
-
-
-
 
+    File(params.livy2_server_pid_file, action="delete")

http://git-wip-us.apache.org/repos/asf/ambari/blob/fded8228/ambari-server/src/main/resources/common-services/SPARK2/2.0.0/package/scripts/setup_livy2.py
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/common-services/SPARK2/2.0.0/package/scripts/setup_livy2.py b/ambari-server/src/main/resources/common-services/SPARK2/2.0.0/package/scripts/setup_livy2.py
index c428488..59ec190 100644
--- a/ambari-server/src/main/resources/common-services/SPARK2/2.0.0/package/scripts/setup_livy2.py
+++ b/ambari-server/src/main/resources/common-services/SPARK2/2.0.0/package/scripts/setup_livy2.py
@@ -29,8 +29,10 @@ def setup_livy(env, type, upgrade_type = None, action = None):
             owner=params.livy2_user,
             group=params.user_group,
             mode=0775,
+            cd_access = 'a',
             create_parents = True
   )
+
   if type == 'server' and action == 'config':
     params.HdfsResource(params.livy2_hdfs_user_dir,
                         type="directory",

http://git-wip-us.apache.org/repos/asf/ambari/blob/fded8228/ambari-server/src/main/resources/stacks/HDP/2.0.6/properties/stack_packages.json
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/stacks/HDP/2.0.6/properties/stack_packages.json b/ambari-server/src/main/resources/stacks/HDP/2.0.6/properties/stack_packages.json
index 01a30f3..6a0eadd 100644
--- a/ambari-server/src/main/resources/stacks/HDP/2.0.6/properties/stack_packages.json
+++ b/ambari-server/src/main/resources/stacks/HDP/2.0.6/properties/stack_packages.json
@@ -1067,6 +1067,12 @@
           "current_dir": "{0}/current/livy-client/conf"
         }
       ],
+      "livy2": [
+        {
+          "conf_dir": "/etc/livy2/conf",
+          "current_dir": "{0}/current/livy2-client/conf"
+        }
+      ],
       "mahout": [
         {
           "conf_dir": "/etc/mahout/conf",
@@ -1241,7 +1247,7 @@
         "packages": ["spark", "livy"]
       },
       "SPARK2": {
-        "packages": ["spark2", "livy"]
+        "packages": ["spark2", "livy2"]
       },
       "SQOOP": {
         "packages": ["sqoop"]

http://git-wip-us.apache.org/repos/asf/ambari/blob/fded8228/ambari-server/src/main/resources/stacks/HDP/3.0/properties/stack_packages.json
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/stacks/HDP/3.0/properties/stack_packages.json b/ambari-server/src/main/resources/stacks/HDP/3.0/properties/stack_packages.json
index 28efbfa..63fcf4b 100644
--- a/ambari-server/src/main/resources/stacks/HDP/3.0/properties/stack_packages.json
+++ b/ambari-server/src/main/resources/stacks/HDP/3.0/properties/stack_packages.json
@@ -944,6 +944,12 @@
           "current_dir": "{0}/current/livy-client/conf"
         }
       ],
+      "livy2": [
+        {
+          "conf_dir": "/etc/livy2/conf",
+          "current_dir": "{0}/current/livy2-client/conf"
+        }
+      ],
       "mahout": [
         {
           "conf_dir": "/etc/mahout/conf",
@@ -1118,7 +1124,7 @@
         "packages": ["spark", "livy"]
       },
       "SPARK2": {
-        "packages": ["spark2", "livy"]
+        "packages": ["spark2", "livy2"]
       },
       "SQOOP": {
         "packages": ["sqoop"]

http://git-wip-us.apache.org/repos/asf/ambari/blob/fded8228/ambari-server/src/test/python/stacks/2.5/SPARK/test_spark_livy.py
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/python/stacks/2.5/SPARK/test_spark_livy.py b/ambari-server/src/test/python/stacks/2.5/SPARK/test_spark_livy.py
index 4f1fb17..e37c6fa 100644
--- a/ambari-server/src/test/python/stacks/2.5/SPARK/test_spark_livy.py
+++ b/ambari-server/src/test/python/stacks/2.5/SPARK/test_spark_livy.py
@@ -25,6 +25,7 @@ from only_for_platform import not_for_platform, PLATFORM_WINDOWS
 
 @not_for_platform(PLATFORM_WINDOWS)
 @patch("resource_management.libraries.functions.get_stack_version", new=MagicMock(return_value="2.5.0.0-1597"))
+@patch("resource_management.libraries.functions.get_user_call_output.get_user_call_output", new=MagicMock(return_value=(0,'12345','')))
 class TestSparkClient(RMFTestCase):
     COMMON_SERVICES_PACKAGE_DIR = "SPARK/1.2.1/package"
     STACK_VERSION = "2.5"
@@ -146,6 +147,6 @@ class TestSparkClient(RMFTestCase):
                                   )
         self.assertResourceCalled('Execute', '/usr/hdp/current/livy-server/bin/livy-server start',
                                   environment = {'JAVA_HOME': '/usr/jdk64/jdk1.7.0_45'},
-                                  not_if = 'ls /var/run/livy/livy-livy-server.pid >/dev/null 2>&1 && ps -p `cat /var/run/livy/livy-livy-server.pid` >/dev/null 2>&1',
+                                  not_if = 'ls /var/run/livy/livy-livy-server.pid >/dev/null 2>&1 && ps -p 12345 >/dev/null 2>&1',
                                   user = 'livy'
                                   )

http://git-wip-us.apache.org/repos/asf/ambari/blob/fded8228/ambari-server/src/test/python/stacks/2.6/SPARK2/test_spark_livy2.py
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/python/stacks/2.6/SPARK2/test_spark_livy2.py b/ambari-server/src/test/python/stacks/2.6/SPARK2/test_spark_livy2.py
index 60e7fd2..f0a173b 100644
--- a/ambari-server/src/test/python/stacks/2.6/SPARK2/test_spark_livy2.py
+++ b/ambari-server/src/test/python/stacks/2.6/SPARK2/test_spark_livy2.py
@@ -25,6 +25,7 @@ from only_for_platform import not_for_platform, PLATFORM_WINDOWS
 
 @not_for_platform(PLATFORM_WINDOWS)
 @patch("resource_management.libraries.functions.get_stack_version", new=MagicMock(return_value="2.5.0.0-1597"))
+@patch("resource_management.libraries.functions.get_user_call_output.get_user_call_output", new=MagicMock(return_value=(0,'12345','')))
 class TestSparkClient(RMFTestCase):
     COMMON_SERVICES_PACKAGE_DIR = "SPARK2/2.0.0/package"
     STACK_VERSION = "2.6"
@@ -45,12 +46,14 @@ class TestSparkClient(RMFTestCase):
                                   owner = 'livy',
                                   group = 'hadoop',
                                   create_parents = True,
+                                  cd_access = 'a',
                                   mode = 0775
                                   )
         self.assertResourceCalled('Directory', '/var/log/livy2',
                                   owner = 'livy',
                                   group = 'hadoop',
                                   create_parents = True,
+                                  cd_access = 'a',
                                   mode = 0775
                                   )
         self.assertResourceCalled('HdfsResource', '/user/livy',
@@ -146,6 +149,6 @@ class TestSparkClient(RMFTestCase):
                                   )
         self.assertResourceCalled('Execute', '/usr/hdp/current/livy2-server/bin/livy-server start',
                                   environment = {'JAVA_HOME': '/usr/jdk64/jdk1.7.0_45'},
-                                  not_if = 'ls /var/run/livy2/livy-livy-server.pid >/dev/null 2>&1 && ps -p `cat /var/run/livy2/livy-livy-server.pid` >/dev/null 2>&1',
+                                  not_if = 'ls /var/run/livy2/livy-livy-server.pid >/dev/null 2>&1 && ps -p 12345 >/dev/null 2>&1',
                                   user = 'livy'
                                   )


[16/24] ambari git commit: Updating Ambari docs for Ambari 2.6.1 and Ambari 2.6.0

Posted by nc...@apache.org.
Updating Ambari docs for Ambari 2.6.1 and Ambari 2.6.0


Project: http://git-wip-us.apache.org/repos/asf/ambari/repo
Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/90554f38
Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/90554f38
Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/90554f38

Branch: refs/heads/branch-feature-AMBARI-21674
Commit: 90554f3810c140787cf4550358952c4438ca78e0
Parents: be0e87b
Author: Swapan Shridhar <ss...@hortonworks.com>
Authored: Mon Dec 18 22:39:17 2017 -0800
Committer: Swapan Shridhar <ss...@hortonworks.com>
Committed: Mon Dec 18 22:40:15 2017 -0800

----------------------------------------------------------------------
 docs/pom.xml                    |  2 +-
 docs/src/site/apt/index.apt     |  2 +-
 docs/src/site/apt/whats-new.apt | 14 +++++++++++++-
 docs/src/site/site.xml          |  4 ++++
 4 files changed, 19 insertions(+), 3 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ambari/blob/90554f38/docs/pom.xml
----------------------------------------------------------------------
diff --git a/docs/pom.xml b/docs/pom.xml
index f3de652..e24a340 100644
--- a/docs/pom.xml
+++ b/docs/pom.xml
@@ -28,7 +28,7 @@
     <modelVersion>4.0.0</modelVersion>
 
     <groupId>org.apache.ambari</groupId>
-    <version>2.5.2</version>
+    <version>2.6.1</version>
     <artifactId>ambari</artifactId>
     <packaging>pom</packaging>
 

http://git-wip-us.apache.org/repos/asf/ambari/blob/90554f38/docs/src/site/apt/index.apt
----------------------------------------------------------------------
diff --git a/docs/src/site/apt/index.apt b/docs/src/site/apt/index.apt
index d9bbe6d..3ffe78e 100644
--- a/docs/src/site/apt/index.apt
+++ b/docs/src/site/apt/index.apt
@@ -52,7 +52,7 @@ Introduction
 
 Getting Started with Ambari
 
-  Follow the {{{https://cwiki.apache.org/confluence/display/AMBARI/Installation+Guide+for+Ambari+2.5.2} installation guide for Ambari 2.5.2}}.
+  Follow the {{{https://cwiki.apache.org/confluence/display/AMBARI/Installation+Guide+for+Ambari+2.6.1} installation guide for Ambari 2.6.1}}.
 
   Note: Ambari currently supports the 64-bit version of the following Operating Systems:
 

http://git-wip-us.apache.org/repos/asf/ambari/blob/90554f38/docs/src/site/apt/whats-new.apt
----------------------------------------------------------------------
diff --git a/docs/src/site/apt/whats-new.apt b/docs/src/site/apt/whats-new.apt
index a1625ce..6ab75a1 100644
--- a/docs/src/site/apt/whats-new.apt
+++ b/docs/src/site/apt/whats-new.apt
@@ -16,7 +16,19 @@
 
 What's New with Ambari?
 
-  * The latest release of Ambari is Ambari 2.5.2.
+  * The latest release of Ambari is Ambari 2.6.1.
+
+  * Ambari 2.6.1 added the following feature:
+
+    * Conditionally Install LZO packages through Ambari (AMBARI-22457)
+
+  * Ambari 2.6.0 added the following features:
+
+    * Ambari Metrics System's (AMS) distributed mode with multiple Collectors (General Availability) (AMBARI-15901)
+
+    * Improvements in Host Recovery (Restart only), moving masters with minimum impact and scale testing (AMBARI-21898, AMBARI-21929, AMBARI-21834)
+
+    * Improvement in Data Archival & Purging in Ambari Infra (AMBARI-21810)
 
   * Ambari 2.5.2 added the following features:
   

http://git-wip-us.apache.org/repos/asf/ambari/blob/90554f38/docs/src/site/site.xml
----------------------------------------------------------------------
diff --git a/docs/src/site/site.xml b/docs/src/site/site.xml
index f2d0d07..66d7ad4 100644
--- a/docs/src/site/site.xml
+++ b/docs/src/site/site.xml
@@ -107,6 +107,8 @@
       <item name="Quick Start Guide" href="https://cwiki.apache.org/confluence/display/AMBARI/Quick+Start+Guide"/>
       <item name="Features + Roadmap" href="https://cwiki.apache.org/confluence/pages/viewpage.action?pageId=30755705"/>
       <item name="API Reference" href="https://github.com/apache/ambari/blob/trunk/ambari-server/docs/api/v1/index.md"/>
+      <item name="Install Guide for 2.6.1" href="https://cwiki.apache.org/confluence/display/AMBARI/Installation+Guide+for+Ambari+2.6.1"/>
+      <item name="Install Guide for 2.6.0" href="https://cwiki.apache.org/confluence/display/AMBARI/Installation+Guide+for+Ambari+2.6.0"/>
       <item name="Install Guide for 2.5.2" href="https://cwiki.apache.org/confluence/display/AMBARI/Installation+Guide+for+Ambari+2.5.2"/>
       <item name="Install Guide for 2.5.1" href="https://cwiki.apache.org/confluence/display/AMBARI/Installation+Guide+for+Ambari+2.5.1"/>
       <item name="Install Guide for 2.5.0" href="https://cwiki.apache.org/confluence/display/AMBARI/Installation+Guide+for+Ambari+2.5.0"/>
@@ -142,6 +144,8 @@
     </menu>
 
     <menu name="Releases">
+      <item name="2.6.1" href="http://www.apache.org/dyn/closer.cgi/ambari/ambari-2.6.1"/>
+      <item name="2.6.0" href="http://www.apache.org/dyn/closer.cgi/ambari/ambari-2.6.0"/>
       <item name="2.5.2" href="http://www.apache.org/dyn/closer.cgi/ambari/ambari-2.5.2"/>
       <item name="2.5.1" href="http://www.apache.org/dyn/closer.cgi/ambari/ambari-2.5.1"/>
       <item name="2.5.0" href="http://www.apache.org/dyn/closer.cgi/ambari/ambari-2.5.0"/>


[10/24] ambari git commit: AMBARI-22644 - Node Managers fail to start after Spark2 is patched due to CNF YarnShuffleService (jonathanhurley)

Posted by nc...@apache.org.
AMBARI-22644 - Node Managers fail to start after Spark2 is patched due to CNF YarnShuffleService (jonathanhurley)


Project: http://git-wip-us.apache.org/repos/asf/ambari/repo
Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/1d87b21c
Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/1d87b21c
Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/1d87b21c

Branch: refs/heads/branch-feature-AMBARI-21674
Commit: 1d87b21cf34c51bc19f80199e2b8641474fe098a
Parents: eab6722
Author: Jonathan Hurley <jh...@hortonworks.com>
Authored: Wed Dec 13 12:33:26 2017 -0500
Committer: Jonathan Hurley <jh...@hortonworks.com>
Committed: Mon Dec 18 15:10:43 2017 -0500

----------------------------------------------------------------------
 .../2.1.0.2.0/package/scripts/params_linux.py   | 19 ++++++++++++-------
 .../3.0.0.3.0/package/scripts/params_linux.py   | 20 ++++++++++++--------
 .../services/YARN/configuration/yarn-site.xml   |  4 ++--
 .../stacks/HDP/2.6/upgrades/config-upgrade.xml  |  2 --
 .../services/YARN/configuration/yarn-site.xml   |  4 ++--
 5 files changed, 28 insertions(+), 21 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ambari/blob/1d87b21c/ambari-server/src/main/resources/common-services/YARN/2.1.0.2.0/package/scripts/params_linux.py
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/common-services/YARN/2.1.0.2.0/package/scripts/params_linux.py b/ambari-server/src/main/resources/common-services/YARN/2.1.0.2.0/package/scripts/params_linux.py
index 9997779..4a49822 100644
--- a/ambari-server/src/main/resources/common-services/YARN/2.1.0.2.0/package/scripts/params_linux.py
+++ b/ambari-server/src/main/resources/common-services/YARN/2.1.0.2.0/package/scripts/params_linux.py
@@ -89,16 +89,20 @@ def get_spark_version(service_name, component_name, yarn_version):
   """
   Attempts to calculate the correct version placeholder value for spark or spark2 based on
   what is installed in the cluster. If Spark is not installed, then this value will need to be
-  that of YARN so it can still find the correct shuffle class.
+  that of YARN so it can still find the correct spark class.
 
   On cluster installs, we have not yet calcualted any versions and all known values could be None.
   This doesn't affect daemons, but it does affect client-only hosts where they will never receive
   a start command after install. Therefore, this function will attempt to use stack-select as a
   last resort to get a value value.
+
+  ATS needs this since it relies on packages installed by Spark. Some classes, like the shuffle
+  classes, are not provided by spark, but by a dependent RPM to YARN, so they do not use this
+  value.
   :param service_name:  the service name (SPARK, SPARK2, etc)
   :param component_name:  the component name (SPARK_CLIENT, etc)
   :param yarn_version:  the default version of Yarn to use if no spark is installed
-  :return:  a value for the version placeholder in shuffle classpath properties
+  :return:  a value for the version placeholder in spark classpath properties
   """
   # start off seeing if we need to populate a default value for YARN
   if yarn_version is None:
@@ -106,18 +110,19 @@ def get_spark_version(service_name, component_name, yarn_version):
       component_name = "YARN_CLIENT")
 
   # now try to get the version of spark/spark2, defaulting to the version if YARN
-  shuffle_classpath_version = component_version.get_component_repository_version(service_name = service_name,
+  spark_classpath_version = component_version.get_component_repository_version(service_name = service_name,
     component_name = component_name, default_value = yarn_version)
 
   # even with the default of using YARN's version, on an install this might be None since we haven't
   # calculated the version of YARN yet - use stack_select as a last ditch effort
-  if shuffle_classpath_version is None:
+  if spark_classpath_version is None:
     try:
-      shuffle_classpath_version = stack_select.get_role_component_current_stack_version()
+      spark_classpath_version = stack_select.get_role_component_current_stack_version()
     except:
-      Logger.exception("Unable to query for the correct shuffle classpath")
+      Logger.exception("Unable to query for the correct spark version to use when building classpaths")
+
+  return spark_classpath_version
 
-  return shuffle_classpath_version
 
 # these are used to render the classpath for picking up Spark classes
 # in the event that spark is not installed, then we must default to the vesrion of YARN installed

http://git-wip-us.apache.org/repos/asf/ambari/blob/1d87b21c/ambari-server/src/main/resources/common-services/YARN/3.0.0.3.0/package/scripts/params_linux.py
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/common-services/YARN/3.0.0.3.0/package/scripts/params_linux.py b/ambari-server/src/main/resources/common-services/YARN/3.0.0.3.0/package/scripts/params_linux.py
index 8e9632c..9afd112 100644
--- a/ambari-server/src/main/resources/common-services/YARN/3.0.0.3.0/package/scripts/params_linux.py
+++ b/ambari-server/src/main/resources/common-services/YARN/3.0.0.3.0/package/scripts/params_linux.py
@@ -89,16 +89,20 @@ def get_spark_version(service_name, component_name, yarn_version):
   """
   Attempts to calculate the correct version placeholder value for spark or spark2 based on
   what is installed in the cluster. If Spark is not installed, then this value will need to be
-  that of YARN so it can still find the correct shuffle class.
+  that of YARN so it can still find the correct spark class.
 
   On cluster installs, we have not yet calcualted any versions and all known values could be None.
   This doesn't affect daemons, but it does affect client-only hosts where they will never receive
   a start command after install. Therefore, this function will attempt to use stack-select as a
   last resort to get a value value.
+
+  ATS needs this since it relies on packages installed by Spark. Some classes, like the shuffle
+  classes, are not provided by spark, but by a dependent RPM to YARN, so they do not use this
+  value.
   :param service_name:  the service name (SPARK, SPARK2, etc)
   :param component_name:  the component name (SPARK_CLIENT, etc)
   :param yarn_version:  the default version of Yarn to use if no spark is installed
-  :return:  a value for the version placeholder in shuffle classpath properties
+  :return:  a value for the version placeholder in spark classpath properties
   """
   # start off seeing if we need to populate a default value for YARN
   if yarn_version is None:
@@ -106,18 +110,19 @@ def get_spark_version(service_name, component_name, yarn_version):
       component_name = "YARN_CLIENT")
 
   # now try to get the version of spark/spark2, defaulting to the version if YARN
-  shuffle_classpath_version = component_version.get_component_repository_version(service_name = service_name,
+  spark_classpath_version = component_version.get_component_repository_version(service_name = service_name,
     component_name = component_name, default_value = yarn_version)
 
   # even with the default of using YARN's version, on an install this might be None since we haven't
   # calculated the version of YARN yet - use stack_select as a last ditch effort
-  if shuffle_classpath_version is None:
+  if spark_classpath_version is None:
     try:
-      shuffle_classpath_version = stack_select.get_role_component_current_stack_version()
+      spark_classpath_version = stack_select.get_role_component_current_stack_version()
     except:
-      Logger.exception("Unable to query for the correct shuffle classpath")
+      Logger.exception("Unable to query for the correct spark version to use when building classpaths")
+
+  return spark_classpath_version
 
-  return shuffle_classpath_version
 
 # these are used to render the classpath for picking up Spark classes
 # in the event that spark is not installed, then we must default to the vesrion of YARN installed
@@ -317,7 +322,6 @@ if include_file_path and manage_include_files:
 ats_host = set(default("/clusterHostInfo/app_timeline_server_hosts", []))
 has_ats = not len(ats_host) == 0
 
-
 # don't using len(nm_hosts) here, because check can take too much time on large clusters
 number_of_nm = 1
 

http://git-wip-us.apache.org/repos/asf/ambari/blob/1d87b21c/ambari-server/src/main/resources/stacks/HDP/2.5/services/YARN/configuration/yarn-site.xml
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/stacks/HDP/2.5/services/YARN/configuration/yarn-site.xml b/ambari-server/src/main/resources/stacks/HDP/2.5/services/YARN/configuration/yarn-site.xml
index 29833fb..b6fadcb 100644
--- a/ambari-server/src/main/resources/stacks/HDP/2.5/services/YARN/configuration/yarn-site.xml
+++ b/ambari-server/src/main/resources/stacks/HDP/2.5/services/YARN/configuration/yarn-site.xml
@@ -31,13 +31,13 @@
   </property>
   <property>
     <name>yarn.nodemanager.aux-services.spark_shuffle.classpath</name>
-    <value>{{stack_root}}/{{spark_version}}/spark/aux/*</value>
+    <value>{{stack_root}}/${hdp.version}/spark/aux/*</value>
     <description>The auxiliary service classpath to use for Spark</description>
     <on-ambari-upgrade add="false"/>
   </property>
   <property>
     <name>yarn.nodemanager.aux-services.spark2_shuffle.classpath</name>
-    <value>{{stack_root}}/{{spark2_version}}/spark2/aux/*</value>
+    <value>{{stack_root}}/${hdp.version}/spark2/aux/*</value>
     <description>The auxiliary service classpath to use for Spark 2</description>
     <on-ambari-upgrade add="false"/>
   </property>

http://git-wip-us.apache.org/repos/asf/ambari/blob/1d87b21c/ambari-server/src/main/resources/stacks/HDP/2.6/upgrades/config-upgrade.xml
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/stacks/HDP/2.6/upgrades/config-upgrade.xml b/ambari-server/src/main/resources/stacks/HDP/2.6/upgrades/config-upgrade.xml
index 9c3d0dd..d8f71cd 100644
--- a/ambari-server/src/main/resources/stacks/HDP/2.6/upgrades/config-upgrade.xml
+++ b/ambari-server/src/main/resources/stacks/HDP/2.6/upgrades/config-upgrade.xml
@@ -183,8 +183,6 @@
         <changes>
           <definition xsi:type="configure" id="hdp_2_6_yarn_spark_versioned_classpaths">
             <type>yarn-site</type>
-            <set key="yarn.nodemanager.aux-services.spark_shuffle.classpath" value="{{stack_root}}/{{spark_version}}/spark/aux/*"/>
-            <set key="yarn.nodemanager.aux-services.spark2_shuffle.classpath" value="{{stack_root}}/{{spark2_version}}/spark2/aux/*"/>
             <replace key="yarn.timeline-service.entity-group-fs-store.group-id-plugin-classpath" find="${hdp.version}/spark/" replace-with="{{spark_version}}/spark/"/>
           </definition>
         </changes>

http://git-wip-us.apache.org/repos/asf/ambari/blob/1d87b21c/ambari-server/src/main/resources/stacks/HDP/3.0/services/YARN/configuration/yarn-site.xml
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/stacks/HDP/3.0/services/YARN/configuration/yarn-site.xml b/ambari-server/src/main/resources/stacks/HDP/3.0/services/YARN/configuration/yarn-site.xml
index d32e2de..01551c4 100644
--- a/ambari-server/src/main/resources/stacks/HDP/3.0/services/YARN/configuration/yarn-site.xml
+++ b/ambari-server/src/main/resources/stacks/HDP/3.0/services/YARN/configuration/yarn-site.xml
@@ -20,7 +20,7 @@
 
   <property>
     <name>yarn.nodemanager.aux-services.spark_shuffle.classpath</name>
-    <value>{{stack_root}}/{{spark_version}}/spark/aux/*</value>
+    <value>{{stack_root}}/${hdp.version}/spark/aux/*</value>
     <description>The auxiliary service classpath to use for Spark</description>
     <on-ambari-upgrade add="false"/>
   </property>
@@ -41,7 +41,7 @@
   <!-- These configs were inherited from HDP 2.5 -->
   <property>
     <name>yarn.nodemanager.aux-services.spark2_shuffle.classpath</name>
-    <value>{{stack_root}}/{{spark2_version}}/spark2/aux/*</value>
+    <value>{{stack_root}}/${hdp.version}/spark2/aux/*</value>
     <description>The auxiliary service classpath to use for Spark 2</description>
     <on-ambari-upgrade add="false"/>
   </property>


[19/24] ambari git commit: AMBARI-22675 LogSearch Title Bar Fixes. (Istvan Tobias via ababiichuk)

Posted by nc...@apache.org.
AMBARI-22675 LogSearch Title Bar Fixes. (Istvan Tobias via ababiichuk)


Project: http://git-wip-us.apache.org/repos/asf/ambari/repo
Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/f3dc1ca3
Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/f3dc1ca3
Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/f3dc1ca3

Branch: refs/heads/branch-feature-AMBARI-21674
Commit: f3dc1ca399c25c3f875bf52e75948839ce5d0b11
Parents: 9bb0980
Author: Istvan Tobias <to...@gmail.com>
Authored: Tue Dec 19 19:14:17 2017 +0200
Committer: ababiichuk <ab...@hortonworks.com>
Committed: Tue Dec 19 19:14:17 2017 +0200

----------------------------------------------------------------------
 .../src/app/components/app.component.html       | 11 ++----
 .../src/app/components/app.component.less       |  4 +--
 .../filters-panel/filters-panel.component.ts    |  8 +++--
 .../logs-container.component.html               |  6 ++--
 .../logs-container.component.less               | 17 ++++++++--
 .../logs-container/logs-container.component.ts  | 35 +++++++++++++++++++-
 .../main-container.component.html               |  1 -
 .../main-container.component.less               |  1 -
 .../main-container/main-container.component.ts  |  5 +--
 9 files changed, 63 insertions(+), 25 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ambari/blob/f3dc1ca3/ambari-logsearch/ambari-logsearch-web/src/app/components/app.component.html
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-web/src/app/components/app.component.html b/ambari-logsearch/ambari-logsearch-web/src/app/components/app.component.html
index 833f43f..495c8d9 100644
--- a/ambari-logsearch/ambari-logsearch-web/src/app/components/app.component.html
+++ b/ambari-logsearch/ambari-logsearch-web/src/app/components/app.component.html
@@ -16,7 +16,7 @@
 -->
 
 <header>
-  <nav class="navbar navbar-fixed-top">
+  <nav class="navbar">
     <div class="container-fluid">
       <h1 [ngClass]="{'full-flex-width': !isAuthorized, 'pull-left': true}">{{'common.title' | translate}}</h1>
       <top-menu *ngIf="isAuthorized"></top-menu>
@@ -24,11 +24,4 @@
   </nav>
 </header>
 
-<main-container>
-  <ng-template>
-    <!-- hidden element for moving the main bar outside the fixed header -->
-    <div class="navbar invisible">
-      <h1>&nbsp;</h1>
-    </div>
-  </ng-template>
-</main-container>
+<main-container></main-container>

http://git-wip-us.apache.org/repos/asf/ambari/blob/f3dc1ca3/ambari-logsearch/ambari-logsearch-web/src/app/components/app.component.less
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-web/src/app/components/app.component.less b/ambari-logsearch/ambari-logsearch-web/src/app/components/app.component.less
index f0fecfc..476465c 100644
--- a/ambari-logsearch/ambari-logsearch-web/src/app/components/app.component.less
+++ b/ambari-logsearch/ambari-logsearch-web/src/app/components/app.component.less
@@ -18,11 +18,11 @@
 @import 'mixins';
 
 :host {
-  .full-size;
+  background-color: @main-background-color; // TODO implement actual color
   display: flex;
   flex-direction: column;
-  background-color: @main-background-color; // TODO implement actual color
   line-height: @default-line-height;
+  min-height: 100vh;
 
   .navbar {
     margin-bottom: 0;

http://git-wip-us.apache.org/repos/asf/ambari/blob/f3dc1ca3/ambari-logsearch/ambari-logsearch-web/src/app/components/filters-panel/filters-panel.component.ts
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-web/src/app/components/filters-panel/filters-panel.component.ts b/ambari-logsearch/ambari-logsearch-web/src/app/components/filters-panel/filters-panel.component.ts
index f9fe94b..480706a 100644
--- a/ambari-logsearch/ambari-logsearch-web/src/app/components/filters-panel/filters-panel.component.ts
+++ b/ambari-logsearch/ambari-logsearch-web/src/app/components/filters-panel/filters-panel.component.ts
@@ -16,7 +16,7 @@
  * limitations under the License.
  */
 
-import {Component, OnChanges, SimpleChanges, Input} from '@angular/core';
+import {Component, OnChanges, SimpleChanges, Input, ViewContainerRef} from '@angular/core';
 import {FormGroup} from '@angular/forms';
 import {Observable} from 'rxjs/Observable';
 import {Subject} from 'rxjs/Subject';
@@ -33,7 +33,7 @@ import {LogsContainerService} from '@app/services/logs-container.service';
 })
 export class FiltersPanelComponent implements OnChanges {
 
-  constructor(private logsContainer: LogsContainerService) {
+  constructor(private logsContainer: LogsContainerService, public viewContainerRef: ViewContainerRef) {
   }
 
   ngOnChanges(changes: SimpleChanges): void {
@@ -62,6 +62,10 @@ export class FiltersPanelComponent implements OnChanges {
 
   searchBoxItems: Observable<ListItem[]>;
 
+  get containerEl(): Element {
+    return this.viewContainerRef.element.nativeElement;
+  }
+
   get filters(): {[key: string]: FilterCondition} {
     return this.logsContainer.filters;
   }

http://git-wip-us.apache.org/repos/asf/ambari/blob/f3dc1ca3/ambari-logsearch/ambari-logsearch-web/src/app/components/logs-container/logs-container.component.html
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-web/src/app/components/logs-container/logs-container.component.html b/ambari-logsearch/ambari-logsearch-web/src/app/components/logs-container/logs-container.component.html
index 5e401d8..d1b11e6 100644
--- a/ambari-logsearch/ambari-logsearch-web/src/app/components/logs-container/logs-container.component.html
+++ b/ambari-logsearch/ambari-logsearch-web/src/app/components/logs-container/logs-container.component.html
@@ -24,9 +24,9 @@
     </div>
   </div>
 </div>
-<div class="container-fluid">
-  <filters-panel class="row" [filtersForm]="filtersForm" [logsType]="logsType"></filters-panel>
-  <div class="row">
+<div #container [ngClass]="{'container-fluid': true, 'fixed-filterbar': isFilterPanelFixedPostioned}">
+  <filters-panel class="row" [filtersForm]="filtersForm" [logsType]="logsType" #filtersPanel></filters-panel>
+  <div class="row events-count">
     <div *ngIf="autoRefreshRemainingSeconds" class="col-md-12">
       <div class="auto-refresh-message pull-right">
         {{'filter.capture.triggeringRefresh' | translate: autoRefreshMessageParams}}

http://git-wip-us.apache.org/repos/asf/ambari/blob/f3dc1ca3/ambari-logsearch/ambari-logsearch-web/src/app/components/logs-container/logs-container.component.less
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-web/src/app/components/logs-container/logs-container.component.less b/ambari-logsearch/ambari-logsearch-web/src/app/components/logs-container/logs-container.component.less
index b4d44fb..243bb5b 100644
--- a/ambari-logsearch/ambari-logsearch-web/src/app/components/logs-container/logs-container.component.less
+++ b/ambari-logsearch/ambari-logsearch-web/src/app/components/logs-container/logs-container.component.less
@@ -32,7 +32,20 @@
     }
   }
 
-  filters-panel {
-    margin-bottom: @block-margin-top;
+  .fixed-filterbar {
+    filters-panel {
+      background-color: fadeout(@filters-panel-background-color, 35%);
+      left: 0;
+      margin: 0;
+      position: fixed;
+      top: 0;
+      width: 100%;
+      z-index: 1;
+    }
+  }
+
+  .events-count {
+    margin-top: @block-margin-top;
   }
+
 }

http://git-wip-us.apache.org/repos/asf/ambari/blob/f3dc1ca3/ambari-logsearch/ambari-logsearch-web/src/app/components/logs-container/logs-container.component.ts
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-web/src/app/components/logs-container/logs-container.component.ts b/ambari-logsearch/ambari-logsearch-web/src/app/components/logs-container/logs-container.component.ts
index 86709fb..cf28a8b 100644
--- a/ambari-logsearch/ambari-logsearch-web/src/app/components/logs-container/logs-container.component.ts
+++ b/ambari-logsearch/ambari-logsearch-web/src/app/components/logs-container/logs-container.component.ts
@@ -16,7 +16,7 @@
  * limitations under the License.
  */
 
-import {Component} from '@angular/core';
+import {Component, ElementRef, ViewChild, HostListener} from '@angular/core';
 import {FormGroup} from '@angular/forms';
 import {Observable} from 'rxjs/Observable';
 import {LogsContainerService} from '@app/services/logs-container.service';
@@ -31,6 +31,7 @@ import {ActiveServiceLogEntry} from '@app/classes/active-service-log-entry';
 import {HistogramOptions} from '@app/classes/histogram-options';
 import {ListItem} from '@app/classes/list-item';
 import {LogsType} from '@app/classes/string';
+import {FiltersPanelComponent} from "@app/components/filters-panel/filters-panel.component";
 
 @Component({
   selector: 'logs-container',
@@ -51,6 +52,16 @@ export class LogsContainerComponent {
     appState.getParameter('isServiceLogContextView').subscribe((value: boolean) => this.isServiceLogContextView = value);
   }
 
+  @ViewChild('container') containerRef: ElementRef;
+  @ViewChild('filtersPanel') filtersPanelRef: FiltersPanelComponent;
+
+  @HostListener("window:scroll", ['$event'])
+  onWindowScroll(): void {
+    this.setFixedPositionValue();
+  }
+
+  private isFilterPanelFixedPostioned: boolean = false;
+
   tabs: Observable<Tab[]> = this.tabsStorage.getAll();
 
   get filtersForm(): FormGroup {
@@ -115,6 +126,28 @@ export class LogsContainerComponent {
     return this.logsContainer.serviceLogsColumns;
   }
 
+  /**
+   * The goal is to set the fixed position of the filter panel when it is scrolled to the top. So that the panel
+   * can be always visible for the user.
+   */
+  private setFixedPositionValue(): void {
+    const el:Element = this.containerRef.nativeElement;
+    const top:number = el.getBoundingClientRect().top;
+    const valueBefore: boolean = this.isFilterPanelFixedPostioned;
+    if (valueBefore != (top <= 0)) {
+      const fpEl:Element = this.filtersPanelRef.containerEl;
+      this.isFilterPanelFixedPostioned = top <= 0;
+      const filtersPanelHeight: number = fpEl.getBoundingClientRect().height;
+      const containerPaddingTop: number = parseFloat(window.getComputedStyle(el).paddingTop);
+      const htmlEl:HTMLElement = this.containerRef.nativeElement;
+      if (this.isFilterPanelFixedPostioned) {
+        htmlEl.style.paddingTop = (containerPaddingTop + filtersPanelHeight) + 'px';
+      } else {
+        htmlEl.style.paddingTop = (containerPaddingTop - filtersPanelHeight) + 'px';
+      }
+    }
+  }
+
   setCustomTimeRange(startTime: number, endTime: number): void {
     this.logsContainer.setCustomTimeRange(startTime, endTime);
   }

http://git-wip-us.apache.org/repos/asf/ambari/blob/f3dc1ca3/ambari-logsearch/ambari-logsearch-web/src/app/components/main-container/main-container.component.html
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-web/src/app/components/main-container/main-container.component.html b/ambari-logsearch/ambari-logsearch-web/src/app/components/main-container/main-container.component.html
index 95dd238..b85cd87 100644
--- a/ambari-logsearch/ambari-logsearch-web/src/app/components/main-container/main-container.component.html
+++ b/ambari-logsearch/ambari-logsearch-web/src/app/components/main-container/main-container.component.html
@@ -15,7 +15,6 @@
   limitations under the License.
 -->
 
-<ng-template [ngTemplateOutlet]="template"></ng-template>
 <div *ngIf="isInitialLoading" class="text-center">
   <span class="fa fa-spinner fa-spin"></span>
 </div>

http://git-wip-us.apache.org/repos/asf/ambari/blob/f3dc1ca3/ambari-logsearch/ambari-logsearch-web/src/app/components/main-container/main-container.component.less
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-web/src/app/components/main-container/main-container.component.less b/ambari-logsearch/ambari-logsearch-web/src/app/components/main-container/main-container.component.less
index bca668d..115f822 100644
--- a/ambari-logsearch/ambari-logsearch-web/src/app/components/main-container/main-container.component.less
+++ b/ambari-logsearch/ambari-logsearch-web/src/app/components/main-container/main-container.component.less
@@ -19,6 +19,5 @@
 @import '../mixins';
 
 :host {
-  .full-size;
   overflow-x: hidden;
 }

http://git-wip-us.apache.org/repos/asf/ambari/blob/f3dc1ca3/ambari-logsearch/ambari-logsearch-web/src/app/components/main-container/main-container.component.ts
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-web/src/app/components/main-container/main-container.component.ts b/ambari-logsearch/ambari-logsearch-web/src/app/components/main-container/main-container.component.ts
index 6747a0c..f83d22b 100644
--- a/ambari-logsearch/ambari-logsearch-web/src/app/components/main-container/main-container.component.ts
+++ b/ambari-logsearch/ambari-logsearch-web/src/app/components/main-container/main-container.component.ts
@@ -16,7 +16,7 @@
  * limitations under the License.
  */
 
-import {Component, ContentChild, TemplateRef} from '@angular/core';
+import {Component} from '@angular/core';
 import {AppStateService} from '@app/services/storage/app-state.service';
 
 @Component({
@@ -31,9 +31,6 @@ export class MainContainerComponent {
     appState.getParameter('isInitialLoading').subscribe((value: boolean) => this.isInitialLoading = value);
   }
 
-  @ContentChild(TemplateRef)
-  template;
-
   isAuthorized: boolean = false;
 
   isInitialLoading: boolean = false;


[12/24] ambari git commit: AMBARI-22522 - Livy server fails to start during downgrade due to absence of 'conf' directory (Dmitro Lisnichenko via jonathanhurley)

Posted by nc...@apache.org.
AMBARI-22522 - Livy server fails to start during downgrade due to absence of 'conf' directory  (Dmitro Lisnichenko via jonathanhurley)


Project: http://git-wip-us.apache.org/repos/asf/ambari/repo
Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/2817ad48
Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/2817ad48
Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/2817ad48

Branch: refs/heads/branch-feature-AMBARI-21674
Commit: 2817ad481507033bccd1732943c305108585dc4b
Parents: fded822
Author: Jonathan Hurley <jh...@hortonworks.com>
Authored: Sun Dec 17 20:48:31 2017 -0500
Committer: Jonathan Hurley <jh...@hortonworks.com>
Committed: Mon Dec 18 15:53:16 2017 -0500

----------------------------------------------------------------------
 .../custom_actions/scripts/install_packages.py  | 37 +++++++++++++++++++-
 1 file changed, 36 insertions(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ambari/blob/2817ad48/ambari-server/src/main/resources/custom_actions/scripts/install_packages.py
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/custom_actions/scripts/install_packages.py b/ambari-server/src/main/resources/custom_actions/scripts/install_packages.py
index 862f205..c3fbc48 100644
--- a/ambari-server/src/main/resources/custom_actions/scripts/install_packages.py
+++ b/ambari-server/src/main/resources/custom_actions/scripts/install_packages.py
@@ -31,7 +31,6 @@ from resource_management.core.resources import Package
 from resource_management.libraries.functions import conf_select
 from resource_management.libraries.functions import stack_tools
 from resource_management.libraries.functions.stack_select import get_stack_versions
-from resource_management.libraries.functions.version import format_stack_version
 from resource_management.libraries.functions.repo_version_history \
     import read_actual_version_from_history_file, write_actual_version_to_history_file, REPO_VERSION_HISTORY_FILE
 from resource_management.core.providers import get_provider
@@ -155,11 +154,47 @@ class InstallPackages(Script):
     if num_errors > 0:
       raise Fail("Failed to distribute repositories/install packages")
 
+    self._fix_default_links("livy", "livy-server")
+    self._fix_default_links("livy2", "livy2-server")
+
     # if installing a version of HDP that needs some symlink love, then create them
     if is_package_install_successful and 'actual_version' in self.structured_output:
       self._relink_configurations_with_conf_select(stack_id, self.structured_output['actual_version'])
 
 
+  def _fix_default_links(self, package_name, component_name):
+    """
+    If a prior version of Ambari did not correctly reverse the conf symlinks, then they would
+    be put into a bad state when distributing a new stack. For example:
+
+    /etc/component/conf (directory)
+    <stack-root>/v1/component/conf -> /etc/component/conf
+
+    When distributing v2, we'd detect the /etc/component/conf problems and would try to adjust it:
+    /etc/component/conf -> <stack-root>/current/component/conf
+    <stack-root>/v2/component/conf -> /etc/component/v2/0
+
+    The problem is that v1 never gets changed (since the stack being distributed is v2), and
+    we end up with a circular link:
+    /etc/component/conf -> <stack-root>/current/component/conf
+    <stack-root>/v1/component/conf -> /etc/component/conf
+
+    :return: None
+    """
+    from resource_management.libraries.functions import stack_select
+    package_dirs = conf_select.get_package_dirs()
+    if package_name in package_dirs:
+      Logger.info("Attempting to fix the default conf links for {0}".format(package_name))
+
+      directories = package_dirs[package_name]
+      Logger.info("The following directories will be fixed for {0}: {1}".format(package_name,
+        str(directories)))
+
+      stack_version = stack_select.get_stack_version_before_install(component_name)
+      if stack_version:
+        conf_select.convert_conf_directories_to_symlinks(package_name, stack_version, directories)
+
+
   def _relink_configurations_with_conf_select(self, stack_id, stack_version):
     """
     Sets up the required structure for /etc/<component>/conf symlinks and <stack-root>/current


[23/24] ambari git commit: AMBARI-22682 Ambari 3.0 Admin View: Add visual-search box to all pages. (atkach)

Posted by nc...@apache.org.
AMBARI-22682 Ambari 3.0 Admin View: Add visual-search box to all pages. (atkach)


Project: http://git-wip-us.apache.org/repos/asf/ambari/repo
Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/81c04545
Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/81c04545
Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/81c04545

Branch: refs/heads/branch-feature-AMBARI-21674
Commit: 81c045452e37adc6e68379a125026ac98f8ed103
Parents: 9ea3fa1
Author: Andrii Tkach <at...@apache.org>
Authored: Thu Dec 21 15:24:55 2017 +0200
Committer: Andrii Tkach <at...@apache.org>
Committed: Thu Dec 21 15:24:55 2017 +0200

----------------------------------------------------------------------
 .../main/resources/ui/admin-web/app/index.html  |   2 +
 .../app/scripts/controllers/SideNavCtrl.js      |   6 +-
 .../controllers/ambariViews/ViewsListCtrl.js    | 184 +++++------
 .../remoteClusters/RemoteClustersListCtrl.js    | 109 +++----
 .../stackVersions/StackVersionsEditCtrl.js      |   2 +-
 .../stackVersions/StackVersionsListCtrl.js      | 191 +++++-------
 .../userManagement/GroupsListCtrl.js            |  86 ++----
 .../controllers/userManagement/UsersListCtrl.js | 132 ++++----
 .../app/scripts/directives/comboSearch.js       |  39 ++-
 .../admin-web/app/scripts/services/Cluster.js   |   3 +-
 .../admin-web/app/scripts/services/Filters.js   |  84 +++++
 .../ui/admin-web/app/scripts/services/Group.js  |  11 +-
 .../app/scripts/services/Pagination.js          |  59 ++++
 .../app/scripts/services/RemoteCluster.js       |  10 +-
 .../ui/admin-web/app/scripts/services/Stack.js  |  32 +-
 .../ui/admin-web/app/scripts/services/User.js   |  13 +-
 .../ui/admin-web/app/styles/user-management.css |   4 +
 .../app/views/ambariViews/viewsList.html        |   5 +-
 .../app/views/remoteClusters/list.html          |  33 +-
 .../admin-web/app/views/stackVersions/list.html |  34 +--
 .../app/views/userManagement/groupsList.html    |  51 ++--
 .../app/views/userManagement/usersList.html     |  61 ++--
 .../ambariViews/ViewsListCtrl_test.js           |  66 +---
 .../userManagement/GroupsListCtrl_test.js       | 100 +-----
 .../userManagement/UsersListCtrl_test.js        | 306 -------------------
 .../test/unit/directives/comboSearch_test.js    |  13 -
 .../test/unit/services/Filters_test.js          | 161 ++++++++++
 .../test/unit/services/Pagination_test.js       |  72 +++++
 28 files changed, 805 insertions(+), 1064 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ambari/blob/81c04545/ambari-admin/src/main/resources/ui/admin-web/app/index.html
----------------------------------------------------------------------
diff --git a/ambari-admin/src/main/resources/ui/admin-web/app/index.html b/ambari-admin/src/main/resources/ui/admin-web/app/index.html
index a1346ed..a9c6984 100644
--- a/ambari-admin/src/main/resources/ui/admin-web/app/index.html
+++ b/ambari-admin/src/main/resources/ui/admin-web/app/index.html
@@ -170,6 +170,8 @@
 <script src="scripts/services/AddRepositoryModal.js"></script>
 <script src="scripts/services/AddVersionModal.js"></script>
 <script src="scripts/services/RoleDetailsModal.js"></script>
+<script src="scripts/services/Pagination.js"></script>
+<script src="scripts/services/Filters.js"></script>
 <!-- endbuild -->
 </body>
 </html>

http://git-wip-us.apache.org/repos/asf/ambari/blob/81c04545/ambari-admin/src/main/resources/ui/admin-web/app/scripts/controllers/SideNavCtrl.js
----------------------------------------------------------------------
diff --git a/ambari-admin/src/main/resources/ui/admin-web/app/scripts/controllers/SideNavCtrl.js b/ambari-admin/src/main/resources/ui/admin-web/app/scripts/controllers/SideNavCtrl.js
index 558d110..6bf356d 100644
--- a/ambari-admin/src/main/resources/ui/admin-web/app/scripts/controllers/SideNavCtrl.js
+++ b/ambari-admin/src/main/resources/ui/admin-web/app/scripts/controllers/SideNavCtrl.js
@@ -29,11 +29,7 @@ angular.module('ambariAdminConsole')
   }, true);
 
   function loadRepos() {
-    Stack.allRepos({version: '',
-      cluster: {
-        options: [],
-        current: null
-      }}, {}).then(function (repos) {
+    Stack.allRepos().then(function (repos) {
       $scope.totalRepos = repos.itemTotal;
     });
   }

http://git-wip-us.apache.org/repos/asf/ambari/blob/81c04545/ambari-admin/src/main/resources/ui/admin-web/app/scripts/controllers/ambariViews/ViewsListCtrl.js
----------------------------------------------------------------------
diff --git a/ambari-admin/src/main/resources/ui/admin-web/app/scripts/controllers/ambariViews/ViewsListCtrl.js b/ambari-admin/src/main/resources/ui/admin-web/app/scripts/controllers/ambariViews/ViewsListCtrl.js
index 8c61a25..f536e50 100644
--- a/ambari-admin/src/main/resources/ui/admin-web/app/scripts/controllers/ambariViews/ViewsListCtrl.js
+++ b/ambari-admin/src/main/resources/ui/admin-web/app/scripts/controllers/ambariViews/ViewsListCtrl.js
@@ -18,7 +18,9 @@
 'use strict';
 
 angular.module('ambariAdminConsole')
-.controller('ViewsListCtrl',['$scope', 'View','$modal', 'Alert', 'ConfirmationModal', '$translate', 'Settings', function($scope, View, $modal, Alert, ConfirmationModal, $translate, Settings) {
+.controller('ViewsListCtrl',
+['$scope', 'View','$modal', 'Alert', 'ConfirmationModal', '$translate', 'Settings', 'Pagination', 'Filters',
+function($scope, View, $modal, Alert, ConfirmationModal, $translate, Settings, Pagination, Filters) {
   var $t = $translate.instant;
   var VIEWS_VERSION_STATUS_TIMEOUT = 5000;
   $scope.isLoading = false;
@@ -33,6 +35,9 @@ angular.module('ambariAdminConsole')
     {
       key: 'url',
       label: $t('urls.url'),
+      customValueConverter: function(item) {
+        return '/main/view/' + item.view_name + '/' + item.short_url;
+      },
       options: []
     },
     {
@@ -46,136 +51,32 @@ angular.module('ambariAdminConsole')
       options: []
     }
   ];
-
-  function checkViewVersionStatus(view, versionObj, versionNumber) {
-    var deferred = View.checkViewVersionStatus(view.view_name, versionNumber);
-
-    deferred.promise.then(function (status) {
-      if (versionNeedStatusUpdate(status)) {
-        setTimeout(function() {
-          checkViewVersionStatus(view, versionObj, versionNumber);
-        }, VIEWS_VERSION_STATUS_TIMEOUT);
-      } else {
-        versionObj.status = status;
-        angular.forEach(view.versions, function (version) {
-          if (version.status === 'DEPLOYED') {
-            view.canCreateInstance = true;
-          }
-        })
-      }
-    });
-  }
-
-  function versionNeedStatusUpdate(status) {
-    return status !== 'DEPLOYED' && status !== 'ERROR';
-  }
-
-  function loadViews() {
-    $scope.isLoading = true;
-    View.all().then(function (views) {
-      $scope.isLoading = false;
-      $scope.views = views;
-      $scope.instances = [];
-      angular.forEach(views, function (view) {
-        angular.forEach(view.versions, function (versionObj, versionNumber) {
-          if (versionNeedStatusUpdate(versionObj.status)) {
-            checkViewVersionStatus(view, versionObj, versionNumber);
-          }
-        });
-        angular.forEach(view.instances, function (instance) {
-          instance.ViewInstanceInfo.short_url_name = instance.ViewInstanceInfo.short_url_name || '';
-          instance.ViewInstanceInfo.short_url = instance.ViewInstanceInfo.short_url || '';
-          instance.ViewInstanceInfo.versionObj = view.versions[instance.ViewInstanceInfo.version] || {};
-          $scope.instances.push(instance.ViewInstanceInfo);
-        });
-      });
-      $scope.initFilterOptions();
-      $scope.filterInstances();
-    }).catch(function (data) {
-      Alert.error($t('views.alerts.cannotLoadViews'), data.data.message);
-    });
-  }
-
-  function showInstancesOnPage() {
-    var startIndex = ($scope.currentPage - 1) * $scope.instancesPerPage + 1;
-    var endIndex = $scope.currentPage * $scope.instancesPerPage;
-    var showedCount = 0;
-    var filteredCount = 0;
-
-    angular.forEach($scope.instances, function(instance) {
-      instance.isShowed = false;
-      if (instance.isFiltered) {
-        filteredCount++;
-        if (filteredCount >= startIndex && filteredCount <= endIndex) {
-          instance.isShowed = true;
-          showedCount++;
-        }
-      }
-    });
-    $scope.tableInfo.showed = showedCount;
-  }
-
   $scope.views = [];
   $scope.instances = [];
-  $scope.instancesPerPage = 10;
-  $scope.currentPage = 1;
-  $scope.maxVisiblePages = 10;
   $scope.tableInfo = {
     filtered: 0,
-    showed: 0
+    showed: 0,
+    total: 0
   };
+  $scope.pagination = Pagination.create();
 
-  loadViews();
+  $scope.resetPagination = function() {
+    $scope.pagination.resetPagination($scope.instances, $scope.tableInfo);
+  };
 
-  $scope.initFilterOptions = function() {
-    $scope.filters.forEach(function(filter) {
-      filter.options = $.unique($scope.instances.map(function(instance) {
-        if (filter.key === 'url') {
-          return '/main/view/' + instance.view_name + '/' + instance.short_url;
-        }
-        return instance[filter.key];
-      })).map(function(item) {
-        return {
-          key: item,
-          label: item
-        }
-      });
-    });
+  $scope.pageChanged = function() {
+    $scope.pagination.pageChanged($scope.instances, $scope.tableInfo);
   };
 
   $scope.filterInstances = function(appliedFilters) {
-    var filteredCount = 0;
-    angular.forEach($scope.instances, function(instance) {
-      instance.isFiltered = !(appliedFilters && appliedFilters.length > 0 && appliedFilters.some(function(filter) {
-        if (filter.key === 'url') {
-          return filter.values.every(function(value) {
-            return ('/main/view/' + instance.view_name + '/' + instance.short_url).indexOf(value) === -1;
-          });
-        }
-        return filter.values.every(function(value) {
-          return instance[filter.key].indexOf(value) === -1;
-        });
-      }));
-
-      filteredCount += ~~instance.isFiltered;
-    });
-    $scope.tableInfo.filtered = filteredCount;
-    $scope.resetPagination();
+    $scope.tableInfo.filtered = Filters.filterItems(appliedFilters, $scope.instances, $scope.filters);
+    $scope.pagination.resetPagination($scope.instances, $scope.tableInfo);
   };
 
   $scope.toggleSearchBox = function() {
     $('.search-box-button .popup-arrow-up, .search-box-row').toggleClass('hide');
   };
 
-  $scope.pageChanged = function() {
-    showInstancesOnPage();
-  };
-
-  $scope.resetPagination = function() {
-    $scope.currentPage = 1;
-    showInstancesOnPage();
-  };
-
   $scope.cloneInstance = function(instanceClone) {
     $scope.createInstance(instanceClone);
   };
@@ -217,4 +118,57 @@ angular.module('ambariAdminConsole')
         });
     });
   };
+
+  loadViews();
+
+  function checkViewVersionStatus(view, versionObj, versionNumber) {
+    var deferred = View.checkViewVersionStatus(view.view_name, versionNumber);
+
+    deferred.promise.then(function (status) {
+      if (versionNeedStatusUpdate(status)) {
+        setTimeout(function() {
+          checkViewVersionStatus(view, versionObj, versionNumber);
+        }, VIEWS_VERSION_STATUS_TIMEOUT);
+      } else {
+        versionObj.status = status;
+        angular.forEach(view.versions, function (version) {
+          if (version.status === 'DEPLOYED') {
+            view.canCreateInstance = true;
+          }
+        })
+      }
+    });
+  }
+
+  function versionNeedStatusUpdate(status) {
+    return status !== 'DEPLOYED' && status !== 'ERROR';
+  }
+
+  function loadViews() {
+    $scope.isLoading = true;
+    View.all().then(function (views) {
+      $scope.isLoading = false;
+      $scope.views = views;
+      $scope.instances = [];
+      angular.forEach(views, function (view) {
+        angular.forEach(view.versions, function (versionObj, versionNumber) {
+          if (versionNeedStatusUpdate(versionObj.status)) {
+            checkViewVersionStatus(view, versionObj, versionNumber);
+          }
+        });
+        angular.forEach(view.instances, function (instance) {
+          instance.ViewInstanceInfo.short_url_name = instance.ViewInstanceInfo.short_url_name || '';
+          instance.ViewInstanceInfo.short_url = instance.ViewInstanceInfo.short_url || '';
+          instance.ViewInstanceInfo.versionObj = view.versions[instance.ViewInstanceInfo.version] || {};
+          $scope.instances.push(instance.ViewInstanceInfo);
+        });
+      });
+      $scope.tableInfo.total = $scope.instances.length;
+      Filters.initFilterOptions($scope.filters, $scope.instances);
+      $scope.filterInstances();
+    }).catch(function (data) {
+      Alert.error($t('views.alerts.cannotLoadViews'), data.data.message);
+    });
+  }
+
 }]);

http://git-wip-us.apache.org/repos/asf/ambari/blob/81c04545/ambari-admin/src/main/resources/ui/admin-web/app/scripts/controllers/remoteClusters/RemoteClustersListCtrl.js
----------------------------------------------------------------------
diff --git a/ambari-admin/src/main/resources/ui/admin-web/app/scripts/controllers/remoteClusters/RemoteClustersListCtrl.js b/ambari-admin/src/main/resources/ui/admin-web/app/scripts/controllers/remoteClusters/RemoteClustersListCtrl.js
index 4726357..5944d20 100644
--- a/ambari-admin/src/main/resources/ui/admin-web/app/scripts/controllers/remoteClusters/RemoteClustersListCtrl.js
+++ b/ambari-admin/src/main/resources/ui/admin-web/app/scripts/controllers/remoteClusters/RemoteClustersListCtrl.js
@@ -18,93 +18,74 @@
 'use strict';
 
 angular.module('ambariAdminConsole')
-.controller('RemoteClustersListCtrl', ['$scope', '$routeParams', '$translate', 'RemoteCluster', 'Settings', function ($scope, $routeParams, $translate, RemoteCluster, Settings) {
+.controller('RemoteClustersListCtrl',
+['$scope', '$routeParams', '$translate', 'RemoteCluster', 'Settings', 'Pagination', 'Filters',
+function ($scope, $routeParams, $translate, RemoteCluster, Settings, Pagination, Filters) {
   var $t = $translate.instant;
 
   $scope.minInstanceForPagination = Settings.minRowsToShowPagination;
   $scope.clusterName = $routeParams.clusterName;
   $scope.isLoading = false;
-
   $scope.constants = {
     groups: $t('common.clusters').toLowerCase()
   };
-
-  $scope.groupsPerPage = 10;
-  $scope.currentPage = 1;
-  $scope.totalGroups = 1;
-  $scope.currentNameFilter = '';
-  $scope.maxVisiblePages=20;
   $scope.tableInfo = {
+    filtered: 0,
     total: 0,
     showed: 0
   };
+  $scope.pagination = Pagination.create();
+  $scope.filters = [
+    {
+      key: 'clusterName',
+      label: $t('views.clusterName'),
+      options: []
+    },
+    {
+      key: 'service',
+      label: $t('common.services'),
+      customValueConverter: function (item) {
+        return item.ClusterInfo.services;
+      },
+      isMultiple: true,
+      options: []
+    }
+  ];
 
-  $scope.isNotEmptyFilter = true;
-
-  $scope.pageChanged = function() {
-    loadRemoteClusters();
-  };
-  $scope.groupsPerPageChanges = function() {
-    loadRemoteClusters();
+  $scope.toggleSearchBox = function () {
+    $('.search-box-button .popup-arrow-up, .search-box-row').toggleClass('hide');
   };
 
-  $scope.resetPagination = function() {
-    $scope.currentPage = 1;
-    loadRemoteClusters();
+  $scope.filterClusters = function (appliedFilters) {
+    $scope.tableInfo.filtered = Filters.filterItems(appliedFilters, $scope.remoteClusters, $scope.filters);
+    $scope.pagination.resetPagination($scope.remoteClusters, $scope.tableInfo);
   };
 
-  $scope.typeFilterOptions = [
-    $t('common.any')
-  ];
-
-  $scope.currentTypeFilter = $scope.typeFilterOptions[0];
-
-  $scope.clearFilters = function () {
-    $scope.currentNameFilter = '';
-    $scope.currentTypeFilter = $scope.typeFilterOptions[0];
-    $scope.resetPagination();
+  $scope.pageChanged = function () {
+    $scope.pagination.pageChanged($scope.remoteClusters, $scope.tableInfo);
   };
 
-  function loadRemoteClusters(){
-      $scope.isLoading = true;
-      RemoteCluster.all({
-        currentPage: $scope.currentPage,
-        groupsPerPage: $scope.groupsPerPage,
-        searchString: $scope.currentNameFilter,
-        service: $scope.currentTypeFilter
-      }).then(function(remoteclusters) {
-        $scope.isLoading = false;
-
-        $scope.totalGroups = remoteclusters.itemTotal;
-        $scope.tableInfo.total = remoteclusters.itemTotal;
-        $scope.tableInfo.showed = remoteclusters.items.length;
-
-        $scope.remoteClusters = remoteclusters.items;
-
-        remoteclusters.items.map(function(clusteritem){
-          clusteritem.ClusterInfo.services.map(function(service){
-            var serviceIndex = $scope.typeFilterOptions.indexOf(service);
-            if(serviceIndex == -1){
-              $scope.typeFilterOptions.push(service);
-            }
-          })
-        })
+  $scope.resetPagination = function () {
+    $scope.pagination.resetPagination($scope.remoteClusters, $scope.tableInfo);
+  };
 
-      })
-      .catch(function(data) {
+  function loadRemoteClusters() {
+    $scope.isLoading = true;
+    RemoteCluster.all().then(function (remoteclusters) {
+      $scope.isLoading = false;
+      $scope.remoteClusters = remoteclusters.items.map(function (item) {
+        item.clusterName = item.ClusterInfo.name;
+        return item;
+      });
+      $scope.tableInfo.total = $scope.remoteClusters.length;
+      $scope.filterClusters();
+      Filters.initFilterOptions($scope.filters, $scope.remoteClusters);
+    })
+      .catch(function (data) {
         console.error($t('remoteClusters.alerts.fetchError'), data);
       });
-  };
+  }
 
   loadRemoteClusters();
 
-  $scope.$watch(
-    function (scope) {
-      return Boolean(scope.currentNameFilter || (scope.currentTypeFilter));
-    },
-    function (newValue, oldValue, scope) {
-      scope.isNotEmptyFilter = newValue;
-    }
-  );
-
 }]);

http://git-wip-us.apache.org/repos/asf/ambari/blob/81c04545/ambari-admin/src/main/resources/ui/admin-web/app/scripts/controllers/stackVersions/StackVersionsEditCtrl.js
----------------------------------------------------------------------
diff --git a/ambari-admin/src/main/resources/ui/admin-web/app/scripts/controllers/stackVersions/StackVersionsEditCtrl.js b/ambari-admin/src/main/resources/ui/admin-web/app/scripts/controllers/stackVersions/StackVersionsEditCtrl.js
index a4b121c..3edaf07 100644
--- a/ambari-admin/src/main/resources/ui/admin-web/app/scripts/controllers/stackVersions/StackVersionsEditCtrl.js
+++ b/ambari-admin/src/main/resources/ui/admin-web/app/scripts/controllers/stackVersions/StackVersionsEditCtrl.js
@@ -136,7 +136,7 @@ angular.module('ambariAdminConsole')
   };
 
   $scope.isDeletable = function() {
-    return !($scope.repoStatus == 'current' || $scope.repoStatus == 'installed');
+    return !($scope.repoStatus === 'CURRENT' || $scope.repoStatus === 'INSTALLED');
   };
 
   $scope.disableUnusedOS = function() {

http://git-wip-us.apache.org/repos/asf/ambari/blob/81c04545/ambari-admin/src/main/resources/ui/admin-web/app/scripts/controllers/stackVersions/StackVersionsListCtrl.js
----------------------------------------------------------------------
diff --git a/ambari-admin/src/main/resources/ui/admin-web/app/scripts/controllers/stackVersions/StackVersionsListCtrl.js b/ambari-admin/src/main/resources/ui/admin-web/app/scripts/controllers/stackVersions/StackVersionsListCtrl.js
index ae00978..ea7a480 100644
--- a/ambari-admin/src/main/resources/ui/admin-web/app/scripts/controllers/stackVersions/StackVersionsListCtrl.js
+++ b/ambari-admin/src/main/resources/ui/admin-web/app/scripts/controllers/stackVersions/StackVersionsListCtrl.js
@@ -18,7 +18,9 @@
 'use strict';
 
 angular.module('ambariAdminConsole')
-  .controller('StackVersionsListCtrl', ['$scope', 'Cluster', 'Stack', '$routeParams', '$translate', 'Settings', function ($scope, Cluster, Stack, $routeParams, $translate, Settings) {
+  .controller('StackVersionsListCtrl',
+  ['$scope', 'Cluster', 'Stack', '$routeParams', '$translate', 'Settings', 'Pagination', '$q', 'Filters',
+  function ($scope, Cluster, Stack, $routeParams, $translate, Settings, Pagination, $q, Filters) {
     var $t = $translate.instant;
     $scope.getConstant = function (key) {
       return $t(key).toLowerCase();
@@ -26,86 +28,86 @@ angular.module('ambariAdminConsole')
     $scope.minInstanceForPagination = Settings.minRowsToShowPagination;
     $scope.isLoading = false;
     $scope.clusterName = $routeParams.clusterName;
-    $scope.filter = {
-      name: '',
-      version: '',
-      type: '',
-      cluster: {
-        options: [],
-        current: null
-      },
-      stack: {
-        options: [],
-        current: null
-      }
-    };
-    $scope.isNotEmptyFilter = true;
-
-    $scope.pagination = {
-      totalRepos: 10,
-      maxVisiblePages: 20,
-      itemsPerPage: 10,
-      currentPage: 1
-    };
-
     $scope.tableInfo = {
       total: 0,
       showed: 0,
       filtered: 0
     };
-
     $scope.repos = [];
     $scope.dropDownClusters = [];
     $scope.selectedCluster = $scope.dropDownClusters[0];
+    $scope.filters = [
+      {
+        key: 'stack',
+        label: $t('common.stack'),
+        customValueConverter: function(item) {
+          return item.stack_name + '-' + item.stack_version;
+        },
+        options: []
+      },
+      {
+        key: 'display_name',
+        label: $t('common.name'),
+        options: []
+      },
+      {
+        key: 'type',
+        label: $t('common.type'),
+        options: []
+      },
+      {
+        key: 'repository_version',
+        label: $t('common.version'),
+        options: []
+      },
+      {
+        key: 'cluster',
+        label: $t('common.cluster'),
+        options: []
+      }
+    ];
+    $scope.pagination = Pagination.create();
 
-    $scope.resetPagination = function () {
-      $scope.pagination.currentPage = 1;
-      $scope.loadAllData();
+    $scope.resetPagination = function() {
+      $scope.pagination.resetPagination($scope.repos, $scope.tableInfo);
     };
 
-    $scope.pageChanged = function () {
-      $scope.loadAllData();
+    $scope.pageChanged = function() {
+      $scope.pagination.pageChanged($scope.repos, $scope.tableInfo);
     };
 
-    $scope.goToCluster = function() {
-      window.location.replace(Settings.siteRoot + '#/main/admin/stack/versions');
+    $scope.filterRepos = function (appliedFilters) {
+      $scope.tableInfo.filtered = Filters.filterItems(appliedFilters, $scope.repos, $scope.filters);
+      $scope.pagination.resetPagination($scope.repos, $scope.tableInfo);
+    };
+
+    $scope.toggleSearchBox = function() {
+      $('.search-box-button .popup-arrow-up, .search-box-row').toggleClass('hide');
     };
 
-    $scope.clearFilters = function () {
-      $scope.filter.name = '';
-      $scope.filter.version = '';
-      $scope.filter.cluster.current = $scope.filter.cluster.options[0];
-      $scope.filter.stack.current = $scope.filter.stack.options[0];
-      $scope.resetPagination();
+    $scope.goToCluster = function() {
+      window.location.replace(Settings.siteRoot + '#/main/admin/stack/versions');
     };
 
     $scope.fetchRepoClusterStatus = function (allRepos) {
+      var calls = [];
       if (allRepos && allRepos.length) {
-        var clusterName = ($scope.clusters && $scope.clusters.length > 0) ? $scope.clusters[0].Clusters.cluster_name : null, // only support one cluster at the moment
-          repos = [],
-          processedRepos = 0;
+        // only support one cluster at the moment
+        var clusterName = $scope.cluster && $scope.cluster.Clusters.cluster_name;
         if (clusterName) {
-          angular.forEach(allRepos, function (repo) {
-            Cluster.getRepoVersionStatus(clusterName, repo.id).then(function (response) {
-              repo.cluster = (response.status == 'current' || response.status == 'installed') ? clusterName : '';
-              if (!$scope.filter.cluster.current.value || repo.cluster) {
+          $scope.repos = allRepos;
+          $scope.tableInfo.total = allRepos.length;
+          angular.forEach($scope.repos, function (repo) {
+            calls.push(Cluster.getRepoVersionStatus(clusterName, repo.id).then(function (response) {
+              repo.cluster = (response.status === 'CURRENT' || response.status === 'INSTALLED') ? clusterName : '';
+              if (repo.cluster) {
                 repo.status = response.status;
                 repo.totalHosts = response.totalHosts;
                 repo.currentHosts = response.currentHosts;
                 repo.installedHosts = response.installedHosts;
                 repo.stackVersionId = response.stackVersionId;
-                repos.push(repo);
               }
-              processedRepos++;
-              if (processedRepos === allRepos.length) {
-                var from = ($scope.pagination.currentPage - 1) * $scope.pagination.itemsPerPage;
-                var to = (repos.length - from > $scope.pagination.itemsPerPage) ? from + $scope.pagination.itemsPerPage : repos.length;
-                $scope.repos = repos.slice(from, to);
-                $scope.tableInfo.total = repos.length;
-                $scope.pagination.totalRepos = repos.length;
-                $scope.tableInfo.showed = to - from;
-              }
-            });
+            }));
           });
         }
       } else {
@@ -114,101 +116,52 @@ angular.module('ambariAdminConsole')
         $scope.pagination.totalRepos = 0;
         $scope.tableInfo.showed = 0;
       }
+      $scope.tableInfo.total = $scope.repos.length;
+      return $q.all(calls);
     };
 
     $scope.fetchRepos = function () {
-      return Stack.allRepos($scope.filter).then(function (repos) {
+      return Stack.allRepos().then(function (repos) {
         $scope.isLoading = false;
         return repos.items;
       });
     };
 
-    $scope.fillClusters = function (clusters) {
-      $scope.dropDownClusters = [].concat(clusters);
-      var options = [{label: $t('common.all'), value: ''}];
-      angular.forEach(clusters, function (cluster) {
-        options.push({
-          label: cluster.Clusters.cluster_name,
-          value: cluster.Clusters.cluster_name
-        });
-      });
-      $scope.filter.cluster.options = options;
-      if (!$scope.filter.cluster.current) {
-        $scope.filter.cluster.current = options[0];
-      }
-    };
-
     $scope.fetchClusters = function () {
       return Cluster.getAllClusters().then(function (clusters) {
         if (clusters && clusters.length > 0) {
-          $scope.clusters = clusters;
-          $scope.fillClusters(clusters);
-        }
-      });
-    };
-
-    $scope.fetchStacks = function () {
-      return Stack.allStackVersions().then(function (clusters) {
-        if (clusters && clusters.length > 0) {
-          $scope.stacks = clusters;
-          $scope.fillStacks(clusters);
-        }
-      });
-    };
-
-    $scope.fillStacks = function() {
-      var options = [{label: $t('common.all'), value: ''}];
-      angular.forEach($scope.stacks, function (stack) {
-        if (stack.active) {
-          options.push({
-            label: stack.displayName,
-            value: stack.displayName
-          });
+          $scope.dropDownClusters = clusters;
         }
       });
-      $scope.filter.stack.options = options;
-      if (!$scope.filter.stack.current) {
-        $scope.filter.stack.current = options[0];
-      }
     };
 
     $scope.loadAllData = function () {
       $scope.isLoading = true;
-      $scope.fetchStacks()
-        .then(function () {
-          return $scope.fetchClusters();
-        })
-        .then(function () {
-          return $scope.fetchRepos();
-        })
+      $scope.fetchRepos()
         .then(function (repos) {
-          $scope.fetchRepoClusterStatus(repos);
+          $scope.fetchClusters();
+          $scope.fetchRepoClusterStatus(repos).then(function() {
+            Filters.initFilterOptions($scope.filters, $scope.repos);
+          });
+          $scope.filterRepos();
         });
     };
 
     $scope.loadAllData();
 
-    $scope.$watch('filter', function (filter) {
-      $scope.isNotEmptyFilter = Boolean(filter.name
-        || filter.version
-        || filter.type
-        || (filter.cluster.current && filter.cluster.current.value)
-        || (filter.stack.current && filter.stack.current.value));
-    }, true);
-
     $scope.toggleVisibility = function (repo) {
       repo.isProccessing = true;
       var payload = {
-        RepositoryVersions:{
+        RepositoryVersions: {
           hidden: repo.hidden
         }
-      }
-      Stack.updateRepo(repo.stack_name, repo.stack_version, repo.id, payload).then( null, function () {
+      };
+      Stack.updateRepo(repo.stack_name, repo.stack_version, repo.id, payload).then(null, function () {
         repo.hidden = !repo.hidden;
-      }).finally( function () {
+      }).finally(function () {
         delete repo.isProccessing;
       });
-    }
+    };
 
     $scope.isHideCheckBoxEnabled = function ( repo ) {
       return !repo.isProccessing && ( !repo.cluster || repo.isPatch && ( repo.status === 'installed' || repo.status === 'install_failed') );

http://git-wip-us.apache.org/repos/asf/ambari/blob/81c04545/ambari-admin/src/main/resources/ui/admin-web/app/scripts/controllers/userManagement/GroupsListCtrl.js
----------------------------------------------------------------------
diff --git a/ambari-admin/src/main/resources/ui/admin-web/app/scripts/controllers/userManagement/GroupsListCtrl.js b/ambari-admin/src/main/resources/ui/admin-web/app/scripts/controllers/userManagement/GroupsListCtrl.js
index 61b5282..f2a6f67 100644
--- a/ambari-admin/src/main/resources/ui/admin-web/app/scripts/controllers/userManagement/GroupsListCtrl.js
+++ b/ambari-admin/src/main/resources/ui/admin-web/app/scripts/controllers/userManagement/GroupsListCtrl.js
@@ -19,8 +19,8 @@
 
 angular.module('ambariAdminConsole')
 .controller('GroupsListCtrl',
-['$scope', 'Group', '$modal', 'ConfirmationModal', '$rootScope', '$translate', 'Settings', 'Cluster', 'View', 'Alert',
-function($scope, Group, $modal, ConfirmationModal, $rootScope, $translate, Settings, Cluster, View, Alert) {
+['$scope', 'Group', '$modal', 'ConfirmationModal', '$rootScope', '$translate', 'Settings', 'Cluster', 'View', 'Alert', 'Pagination', 'Filters',
+function($scope, Group, $modal, ConfirmationModal, $rootScope, $translate, Settings, Cluster, View, Alert, Pagination, Filters) {
   var $t = $translate.instant;
   $scope.constants = {
     groups: $t('common.groups').toLowerCase()
@@ -28,77 +28,57 @@ function($scope, Group, $modal, ConfirmationModal, $rootScope, $translate, Setti
   $scope.minRowsToShowPagination = Settings.minRowsToShowPagination;
   $scope.isLoading = false;
   $scope.groups = [];
-
-  $scope.groupsPerPage = 10;
-  $scope.currentPage = 1;
-  $scope.totalGroups = 0;
-  $scope.filter = {
-    name: '',
-    type: null
-  };
-  $scope.maxVisiblePages=20;
   $scope.tableInfo = {
+    filtered: 0,
     total: 0,
     showed: 0
   };
-  $scope.isNotEmptyFilter = true;
+  $scope.pagination = Pagination.create();
+  $scope.filters = [
+    {
+      key: 'group_name',
+      label: $t('groups.name'),
+      options: []
+    },
+    {
+      key: 'groupTypeName',
+      label: $t('common.type'),
+      options: []
+    }
+  ];
+
+  $scope.resetPagination = function() {
+    $scope.pagination.resetPagination($scope.groups, $scope.tableInfo);
+  };
 
   $scope.pageChanged = function() {
-    loadGroups();
+    $scope.pagination.pageChanged($scope.groups, $scope.tableInfo);
   };
-  $scope.groupsPerPageChanges = function() {
-    loadGroups();
+
+  $scope.filterGroups = function(appliedFilters) {
+    $scope.tableInfo.filtered = Filters.filterItems(appliedFilters, $scope.groups, $scope.filters);
+    $scope.pagination.resetPagination($scope.groups, $scope.tableInfo);
   };
 
-  $scope.resetPagination = function() {
-    $scope.currentPage = 1;
-    loadGroups();
+  $scope.toggleSearchBox = function() {
+    $('.search-box-button .popup-arrow-up, .search-box-row').toggleClass('hide');
   };
 
-  function loadGroups(){
+  $scope.loadGroups = function() {
     $scope.isLoading = true;
-    Group.all({
-      currentPage: $scope.currentPage, 
-      groupsPerPage: $scope.groupsPerPage, 
-      searchString: $scope.filter.name,
-      group_type: $scope.filter.type.value
-    }).then(function(groups) {
+    Group.all().then(function(groups) {
       $scope.isLoading = false;
-      $scope.totalGroups = groups.itemTotal;
       $scope.groups = groups.map(Group.makeGroup);
-      $scope.tableInfo.total = groups.itemTotal;
-      $scope.tableInfo.showed = groups.length;
+      $scope.tableInfo.total = $scope.groups.length;
+      Filters.initFilterOptions($scope.filters, $scope.groups);
+      $scope.filterGroups();
     })
     .catch(function(data) {
       Alert.error($t('groups.alerts.getGroupsListError'), data.data.message);
     });
-  }
-
-  $scope.typeFilterOptions = [{ label: $t('common.all'), value: '*'}]
-    .concat(Object.keys(Group.getTypes()).map(function(key) {
-      return {
-        label: $t(Group.getTypes()[key].LABEL_KEY),
-        value: Group.getTypes()[key].VALUE
-      };
-  }));
-  $scope.filter.type = $scope.typeFilterOptions[0];
-
-  $scope.clearFilters = function () {
-    $scope.filter.name = '';
-    $scope.filter.type = $scope.typeFilterOptions[0];
-    $scope.resetPagination();
   };
-  
-  loadGroups();
 
-  $scope.$watch(
-    function (scope) {
-      return Boolean(scope.filter.name || (scope.filter.type && scope.filter.type.value !== '*'));
-    },
-    function (newValue, oldValue, scope) {
-      scope.isNotEmptyFilter = newValue;
-    }
-  );
+  $scope.loadGroups();
 
   $rootScope.$watch(function(scope) {
     return scope.LDAPSynced;

http://git-wip-us.apache.org/repos/asf/ambari/blob/81c04545/ambari-admin/src/main/resources/ui/admin-web/app/scripts/controllers/userManagement/UsersListCtrl.js
----------------------------------------------------------------------
diff --git a/ambari-admin/src/main/resources/ui/admin-web/app/scripts/controllers/userManagement/UsersListCtrl.js b/ambari-admin/src/main/resources/ui/admin-web/app/scripts/controllers/userManagement/UsersListCtrl.js
index 00bf9c3..7982f0b 100644
--- a/ambari-admin/src/main/resources/ui/admin-web/app/scripts/controllers/userManagement/UsersListCtrl.js
+++ b/ambari-admin/src/main/resources/ui/admin-web/app/scripts/controllers/userManagement/UsersListCtrl.js
@@ -19,95 +19,105 @@
 
 angular.module('ambariAdminConsole')
 .controller('UsersListCtrl',
-['$scope', 'User', '$modal', '$rootScope', 'UserConstants', '$translate', 'Cluster', 'View', 'ConfirmationModal', 'Settings',
-function($scope, User, $modal, $rootScope, UserConstants, $translate, Cluster, View, ConfirmationModal, Settings) {
+['$scope', 'User', '$modal', '$rootScope', 'UserConstants', '$translate', 'Cluster', 'View', 'ConfirmationModal', 'Settings', 'Pagination', 'Filters',
+function($scope, User, $modal, $rootScope, UserConstants, $translate, Cluster, View, ConfirmationModal, Settings, Pagination, Filters) {
   var $t = $translate.instant;
   $scope.constants = {
     admin: $t('users.ambariAdmin'),
     users: $t('common.users').toLowerCase()
   };
+  $scope.users = [];
   $scope.minRowsToShowPagination = Settings.minRowsToShowPagination;
   $scope.isLoading = false;
-  $scope.users = [];
-  $scope.usersPerPage = 10;
-  $scope.currentPage = 1;
-  $scope.totalUsers = 0;
-  $scope.filters = {
-    name: '',
-    status: null,
-    type: null
-  };
-  $scope.maxVisiblePages = 20;
+  $scope.pagination = Pagination.create();
   $scope.tableInfo = {
+    filtered: 0,
     total: 0,
     showed: 0
   };
-  $scope.isNotEmptyFilter = true;
+  $scope.filters = [
+    {
+      key: 'user_name',
+      label: $t('users.username'),
+      customValueConverter: function(item) {
+        return item.Users.user_name;
+      },
+      options: []
+    },
+    {
+      key: 'role',
+      label: $t('clusters.role'),
+      customValueConverter: function(item) {
+        return item.Users.roles[0] ? item.Users.roles[0].permission_label : '';
+      },
+      options: []
+    },
+    {
+      key: 'status',
+      label: $t('users.status'),
+      isStatic: true,
+      customValueConverter: function(item) {
+        return item.Users.active ? $t('users.active') : $t('users.inactive');
+      },
+      options: [
+        {
+          key: $t('users.active'),
+          label: $t('users.active')
+        },
+        {
+          key: $t('users.inactive'),
+          label: $t('users.inactive')
+        }
+      ]
+    },
+    {
+      key: 'type',
+      label: $t('common.type'),
+      customValueConverter: function(item) {
+        return item.Users.userTypeName;
+      },
+      options: []
+    },
+    {
+      key: 'group',
+      label: $t('common.group'),
+      isMultiple: true,
+      customValueConverter: function(item) {
+        return item.Users.groups;
+      },
+      options: []
+    }
+  ];
 
   function loadUsers() {
     $scope.isLoading = true;
-    User.list({
-      currentPage: $scope.currentPage,
-      usersPerPage: $scope.usersPerPage,
-      searchString: $scope.filters.name,
-      user_type: $scope.filters.type.value,
-      active: $scope.filters.status.value
-    }).then(function (data) {
-      $scope.totalUsers = data.data.itemTotal;
+    User.list().then(function (data) {
       $scope.users = data.data.items.map(User.makeUser);
-      $scope.tableInfo.showed = data.data.items.length;
-      $scope.tableInfo.total = data.data.itemTotal;
+      $scope.tableInfo.total = $scope.users.length;
+      $scope.filterUsers();
+      Filters.initFilterOptions($scope.filters, $scope.users);
     }).finally(function () {
       $scope.isLoading = false;
     });
   }
 
-  $scope.pageChanged = function () {
-    loadUsers();
+  $scope.toggleSearchBox = function() {
+    $('.search-box-button .popup-arrow-up, .search-box-row').toggleClass('hide');
   };
-  $scope.usersPerPageChanges = function () {
-    $scope.resetPagination();
+
+  $scope.pageChanged = function () {
+    $scope.pagination.pageChanged($scope.users, $scope.tableInfo);
   };
 
   $scope.resetPagination = function () {
-    $scope.currentPage = 1;
-    loadUsers();
+    $scope.pagination.resetPagination($scope.users, $scope.tableInfo);
   };
 
-  $scope.activeFilterOptions = [
-    {label: $t('common.all'), value: '*'},
-    {label: $t('users.active'), value: true},
-    {label: $t('users.inactive'), value: false}
-  ];
-  $scope.filters.status = $scope.activeFilterOptions[0];
-
-  $scope.typeFilterOptions = [{label: $t('common.all'), value: '*'}]
-    .concat(Object.keys(UserConstants.TYPES).map(function (key) {
-      return {
-        label: $t(UserConstants.TYPES[key].LABEL_KEY),
-        value: UserConstants.TYPES[key].VALUE
-      };
-    }));
-
-  $scope.filters.type = $scope.typeFilterOptions[0];
-
-  $scope.clearFilters = function () {
-    $scope.filters.name = '';
-    $scope.filters.type = $scope.typeFilterOptions[0];
-    $scope.filters.status = $scope.activeFilterOptions[0];
-    $scope.resetPagination();
+  $scope.filterUsers = function(appliedFilters) {
+    $scope.tableInfo.filtered = Filters.filterItems(appliedFilters, $scope.users, $scope.filters);
+    $scope.pagination.resetPagination($scope.users, $scope.tableInfo);
   };
 
-  $scope.$watch(
-    function (scope) {
-      return Boolean(scope.filters.name || (scope.filters.status && scope.filters.status.value !== '*')
-        || (scope.filters.type && scope.filters.type.value !== '*'));
-    },
-    function (newValue, oldValue, scope) {
-      scope.isNotEmptyFilter = newValue;
-    }
-  );
-
   $rootScope.$watch(function (scope) {
     return scope.LDAPSynced;
   }, function (LDAPSynced) {

http://git-wip-us.apache.org/repos/asf/ambari/blob/81c04545/ambari-admin/src/main/resources/ui/admin-web/app/scripts/directives/comboSearch.js
----------------------------------------------------------------------
diff --git a/ambari-admin/src/main/resources/ui/admin-web/app/scripts/directives/comboSearch.js b/ambari-admin/src/main/resources/ui/admin-web/app/scripts/directives/comboSearch.js
index af25167..fc58eae 100644
--- a/ambari-admin/src/main/resources/ui/admin-web/app/scripts/directives/comboSearch.js
+++ b/ambari-admin/src/main/resources/ui/admin-web/app/scripts/directives/comboSearch.js
@@ -169,10 +169,8 @@ angular.module('ambariAdminConsole')
           return !(option.key === '' || option.key === undefined || appliedOptions[option.key])
             && (!filter.searchOptionInput || option.label.toLowerCase().indexOf(filter.searchOptionInput.toLowerCase()) !== -1);
         });
+        resetActive(filter.filteredOptions);
         filter.showAutoComplete = filter.filteredOptions.length > 0;
-        if (filter.filteredOptions.length > 0) {
-          $scope.makeActive(filter.filteredOptions[0], filter.filteredOptions);
-        }
       };
 
       $scope.extractFilters = function(filters) {
@@ -247,7 +245,13 @@ angular.module('ambariAdminConsole')
             return i;
           }
         }
-        return 0;
+        return -1;
+      }
+
+      function resetActive(array) {
+        array.forEach(function(item) {
+          item.active = false;
+        });
       }
 
       function focusInput(filter) {
@@ -282,6 +286,10 @@ angular.module('ambariAdminConsole')
             leftArrowKeyHandler();
             $scope.$apply();
           }
+          if (event.which === 27) { // "Escape" key
+            $scope.showAutoComplete = false;
+            $scope.$apply();
+          }
         });
       }
 
@@ -341,7 +349,14 @@ angular.module('ambariAdminConsole')
           if (activeAppliedFilters.length > 0) {
             var filteredOptions = activeAppliedFilters[0].filteredOptions;
             activeIndex = findActiveByProperty(filteredOptions);
-            nextIndex = (activeIndex < filteredOptions.length - 1) ? activeIndex + 1 : 0;
+            if (activeIndex < filteredOptions.length - 1) {
+              nextIndex = activeIndex + 1;
+            } else {
+              //switch to input of option
+              nextIndex = null;
+              resetActive(filteredOptions);
+              focusInput(activeAppliedFilters[0]);
+            }
           }
           if (nextIndex !== null) {
             $scope.makeActive(filteredOptions[nextIndex], filteredOptions);
@@ -374,7 +389,16 @@ angular.module('ambariAdminConsole')
           if (activeAppliedFilters.length > 0) {
             var filteredOptions = activeAppliedFilters[0].filteredOptions;
             activeIndex = findActiveByProperty(filteredOptions);
-            nextIndex = (activeIndex > 0) ?  activeIndex - 1 : filteredOptions.length - 1;
+            if (activeIndex > 0) {
+              nextIndex = activeIndex - 1;
+            } else if (activeIndex === 0) {
+              //switch to input of option
+              nextIndex = null;
+              resetActive(filteredOptions);
+              focusInput(activeAppliedFilters[0]);
+            } else {
+              nextIndex = filteredOptions.length - 1;
+            }
           }
           if (nextIndex !== null) {
             $scope.makeActive(filteredOptions[nextIndex], filteredOptions);
@@ -401,7 +425,8 @@ angular.module('ambariAdminConsole')
             if (activeOptions.length > 0) {
               $scope.selectOption(null, activeOptions[0], activeAppliedFilters[0]);
             }
-          } else {
+          }
+          if (activeAppliedFilters.length === 0 || activeOptions.length === 0) {
             $scope.appliedFilters.filter(function(item) {
               return !item.currentOption;
             }).forEach(function(item) {

http://git-wip-us.apache.org/repos/asf/ambari/blob/81c04545/ambari-admin/src/main/resources/ui/admin-web/app/scripts/services/Cluster.js
----------------------------------------------------------------------
diff --git a/ambari-admin/src/main/resources/ui/admin-web/app/scripts/services/Cluster.js b/ambari-admin/src/main/resources/ui/admin-web/app/scripts/services/Cluster.js
index 30ef91a..1a99a65 100644
--- a/ambari-admin/src/main/resources/ui/admin-web/app/scripts/services/Cluster.js
+++ b/ambari-admin/src/main/resources/ui/admin-web/app/scripts/services/Cluster.js
@@ -292,8 +292,7 @@ angular.module('ambariAdminConsole')
           angular.forEach(hostStatus, function(status) {
             totalHosts += status.length;
           });
-          response.status = currentHosts > 0? 'current' :
-                            installedHosts > 0? 'installed' : '';
+          response.status = data[0].ClusterStackVersions.state;
           response.currentHosts = currentHosts;
           response.installedHosts = installedHosts;
           response.totalHosts = totalHosts;

http://git-wip-us.apache.org/repos/asf/ambari/blob/81c04545/ambari-admin/src/main/resources/ui/admin-web/app/scripts/services/Filters.js
----------------------------------------------------------------------
diff --git a/ambari-admin/src/main/resources/ui/admin-web/app/scripts/services/Filters.js b/ambari-admin/src/main/resources/ui/admin-web/app/scripts/services/Filters.js
new file mode 100644
index 0000000..7c6815f
--- /dev/null
+++ b/ambari-admin/src/main/resources/ui/admin-web/app/scripts/services/Filters.js
@@ -0,0 +1,84 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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.
+ */
+'use strict';
+
+angular.module('ambariAdminConsole')
+.factory('Filters', function() {
+
+  function initFilterOptions(filters, items) {
+    filters.filter(function(filter) {
+      return !filter.isStatic;
+    }).forEach(function(filter) {
+      var preOptions = [];
+      if (filter.isMultiple) {
+        items.forEach(function(item) {
+          if (typeof filter.customValueConverter === 'function') {
+            preOptions = preOptions.concat(filter.customValueConverter(item));
+          } else {
+            preOptions = preOptions.concat(item[filter.key]);
+          }
+        });
+      } else {
+        preOptions = items.map(function(item) {
+          if (typeof filter.customValueConverter === 'function') {
+            return filter.customValueConverter(item);
+          }
+          return item[filter.key];
+        });
+      }
+      filter.options = $.unique(preOptions).filter(function(item) {
+        return item !== undefined && item !== null;
+      }).map(function(item) {
+        return {
+          key: item,
+          label: item
+        }
+      });
+    });
+  }
+
+  function filterItems(appliedFilters, items, filterDefinitions) {
+    var filteredCount = 0;
+    angular.forEach(items, function(item) {
+      item.isFiltered = !(appliedFilters && appliedFilters.length > 0 && appliedFilters.some(function(filter) {
+        var customValueFilter = filterDefinitions.filter(function(filterDefinition) {
+          return filterDefinition.key === filter.key && typeof filterDefinition.customValueConverter === 'function';
+        })[0];
+        if (customValueFilter) {
+          return filter.values.every(function(value) {
+            var itemValue = customValueFilter.customValueConverter(item);
+            return String(Array.isArray(itemValue) ? itemValue.join() : itemValue).indexOf(value) === -1;
+          });
+        }
+        return filter.values.every(function(value) {
+          var itemValue = item[filter.key];
+          return String(Array.isArray(itemValue) ? itemValue.join() : itemValue).indexOf(value) === -1;
+
+        });
+      }));
+
+      filteredCount += ~~item.isFiltered;
+    });
+    return filteredCount;
+  }
+
+  return {
+    initFilterOptions: initFilterOptions,
+    filterItems: filterItems
+  };
+});

http://git-wip-us.apache.org/repos/asf/ambari/blob/81c04545/ambari-admin/src/main/resources/ui/admin-web/app/scripts/services/Group.js
----------------------------------------------------------------------
diff --git a/ambari-admin/src/main/resources/ui/admin-web/app/scripts/services/Group.js b/ambari-admin/src/main/resources/ui/admin-web/app/scripts/services/Group.js
index 0509e11..dc6d351 100644
--- a/ambari-admin/src/main/resources/ui/admin-web/app/scripts/services/Group.js
+++ b/ambari-admin/src/main/resources/ui/admin-web/app/scripts/services/Group.js
@@ -100,18 +100,11 @@ angular.module('ambariAdminConsole')
     return $http.post(Settings.baseUrl + '/groups/' + groupName + '/members/'+memberName);
   };
 
-  Group.all = function(params) {
+  Group.all = function() {
     var deferred = $q.defer();
 
-    $http.get(Settings.baseUrl + '/groups?'
-      + 'Groups/group_name.matches(.*'+params.searchString+'.*)'
-      + '&fields=*'
-      + '&from='+ (params.currentPage-1)*params.groupsPerPage
-      + '&page_size=' + params.groupsPerPage
-      + (params.group_type === '*' ? '' : '&Groups/group_type=' + params.group_type)
-    )
+    $http.get(Settings.baseUrl + '/groups?fields=*')
     .success(function(data) {
-      data.items.itemTotal = data.itemTotal;
       deferred.resolve(data.items);
     })
     .error(function(data) {

http://git-wip-us.apache.org/repos/asf/ambari/blob/81c04545/ambari-admin/src/main/resources/ui/admin-web/app/scripts/services/Pagination.js
----------------------------------------------------------------------
diff --git a/ambari-admin/src/main/resources/ui/admin-web/app/scripts/services/Pagination.js b/ambari-admin/src/main/resources/ui/admin-web/app/scripts/services/Pagination.js
new file mode 100644
index 0000000..ac0a8bc
--- /dev/null
+++ b/ambari-admin/src/main/resources/ui/admin-web/app/scripts/services/Pagination.js
@@ -0,0 +1,59 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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.
+ */
+'use strict';
+
+angular.module('ambariAdminConsole')
+.factory('Pagination', function() {
+
+  function showItemsOnPage(items, tableInfo) {
+    var startIndex = (this.currentPage - 1) * this.itemsPerPage + 1;
+    var endIndex = this.currentPage * this.itemsPerPage;
+    var showedCount = 0;
+    var filteredCount = 0;
+
+    angular.forEach(items, function (item) {
+      item.isShowed = false;
+      if (item.isFiltered) {
+        filteredCount++;
+        if (filteredCount >= startIndex && filteredCount <= endIndex) {
+          item.isShowed = true;
+          showedCount++;
+        }
+      }
+    });
+    tableInfo.showed = showedCount;
+  }
+
+  return {
+    create: function(options) {
+      options = options || {};
+      return {
+        itemsPerPage: options.itemsPerPage || 10,
+        currentPage: options.currentPage || 1,
+        maxVisiblePages: options.maxVisiblePages || 10,
+        pageChanged: function(items, tableInfo) {
+          showItemsOnPage.call(this, items, tableInfo);
+        },
+        resetPagination: function(items, tableInfo) {
+          this.currentPage = 1;
+          showItemsOnPage.call(this, items, tableInfo);
+        }
+      }
+    }
+  };
+});

http://git-wip-us.apache.org/repos/asf/ambari/blob/81c04545/ambari-admin/src/main/resources/ui/admin-web/app/scripts/services/RemoteCluster.js
----------------------------------------------------------------------
diff --git a/ambari-admin/src/main/resources/ui/admin-web/app/scripts/services/RemoteCluster.js b/ambari-admin/src/main/resources/ui/admin-web/app/scripts/services/RemoteCluster.js
index 49c6abc..86407fd 100644
--- a/ambari-admin/src/main/resources/ui/admin-web/app/scripts/services/RemoteCluster.js
+++ b/ambari-admin/src/main/resources/ui/admin-web/app/scripts/services/RemoteCluster.js
@@ -80,16 +80,10 @@ angular.module('ambariAdminConsole')
         return deferred.promise;
     }
 
-    RemoteCluster.all = function(params) {
+    RemoteCluster.all = function() {
       var deferred = $q.defer();
 
-      $http.get(Settings.baseUrl + "/remoteclusters?"
-          + 'ClusterInfo/name.matches(.*'+params.searchString+'.*)'
-          + '&fields=*'
-          + '&from='+ (params.currentPage-1)*params.groupsPerPage
-          + '&page_size=' + params.groupsPerPage
-          + (params.service === 'Any' ? '' : '&ClusterInfo/services.matches(.*'+params.service+'.*)')
-        )
+      $http.get(Settings.baseUrl + "/remoteclusters")
         .success(function(response) {
           deferred.resolve(response);
         })

http://git-wip-us.apache.org/repos/asf/ambari/blob/81c04545/ambari-admin/src/main/resources/ui/admin-web/app/scripts/services/Stack.js
----------------------------------------------------------------------
diff --git a/ambari-admin/src/main/resources/ui/admin-web/app/scripts/services/Stack.js b/ambari-admin/src/main/resources/ui/admin-web/app/scripts/services/Stack.js
index f52e687..4f111fe 100644
--- a/ambari-admin/src/main/resources/ui/admin-web/app/scripts/services/Stack.js
+++ b/ambari-admin/src/main/resources/ui/admin-web/app/scripts/services/Stack.js
@@ -189,28 +189,8 @@ angular.module('ambariAdminConsole')
       }
     },
 
-    allRepos: function (filter, pagination) {
-      var versionFilter = filter.version;
-      var nameFilter = filter.name;
-      var typeFilter = filter.type;
-      var stackFilter = filter.stack && filter.stack.current && filter.stack.current.value;
+    allRepos: function () {
       var url = '/stacks?fields=versions/repository_versions/RepositoryVersions';
-      if (versionFilter) {
-        url += '&versions/repository_versions/RepositoryVersions/repository_version.matches(.*' + versionFilter + '.*)';
-      }
-      if (nameFilter) {
-        url += '&versions/repository_versions/RepositoryVersions/display_name.matches(.*' + nameFilter + '.*)';
-      }
-      if (typeFilter){
-        url += '&versions/repository_versions/RepositoryVersions/type.matches(.*' + typeFilter.toUpperCase() + '.*)';
-      }
-      if (stackFilter) {
-        var stack = filter.stack.current.value.split('-'),
-          stackNameFilter = stack[0],
-          stackVersionFilter = stack[1];
-        url += '&versions/repository_versions/RepositoryVersions/stack_name=' + stackNameFilter;
-        url += '&versions/repository_versions/RepositoryVersions/stack_version=' + stackVersionFilter;
-      }
       var deferred = $q.defer();
       $http.get(Settings.baseUrl + url, {mock: 'version/versions.json'})
       .success(function (data) {
@@ -230,16 +210,8 @@ angular.module('ambariAdminConsole')
         });
         // prepare response data with client side pagination
         var response = {};
+        response.items = repos;
         response.itemTotal = repos.length;
-        if (pagination) {
-          var from = (pagination.currentPage - 1) * pagination.itemsPerPage;
-          var to = (repos.length - from > pagination.itemsPerPage)? from + pagination.itemsPerPage : repos.length;
-          response.items = repos.slice(from, to);
-          response.showed = to - from;
-        } else {
-          response.items = repos;
-          response.showed = repos.length;
-        }
         deferred.resolve(response);
       })
       .error(function (data) {

http://git-wip-us.apache.org/repos/asf/ambari/blob/81c04545/ambari-admin/src/main/resources/ui/admin-web/app/scripts/services/User.js
----------------------------------------------------------------------
diff --git a/ambari-admin/src/main/resources/ui/admin-web/app/scripts/services/User.js b/ambari-admin/src/main/resources/ui/admin-web/app/scripts/services/User.js
index 7932d9b..5ed692a 100644
--- a/ambari-admin/src/main/resources/ui/admin-web/app/scripts/services/User.js
+++ b/ambari-admin/src/main/resources/ui/admin-web/app/scripts/services/User.js
@@ -33,17 +33,8 @@ angular.module('ambariAdminConsole')
   var $t = $translate.instant;
 
   return {
-    list: function(params) {
-      return $http.get(
-        Settings.baseUrl + '/users/?'
-        + 'Users/user_name.matches(.*'+params.searchString+'.*)'
-        + '&fields=privileges/PrivilegeInfo/*,Users'
-        + '&from=' + (params.currentPage-1)*params.usersPerPage
-        + '&page_size=' + params.usersPerPage
-        + (params.user_type === '*' ? '' : '&Users/user_type=' + params.user_type)
-        + (params.active === '*' ? '' : '&Users/active=' + params.active)
-        + (params.admin ? '&Users/admin=true' : '')
-      );
+    list: function() {
+      return $http.get(Settings.baseUrl + '/users?fields=Users/*,privileges/*');
     },
     listByName: function(name) {
       return $http.get(

http://git-wip-us.apache.org/repos/asf/ambari/blob/81c04545/ambari-admin/src/main/resources/ui/admin-web/app/styles/user-management.css
----------------------------------------------------------------------
diff --git a/ambari-admin/src/main/resources/ui/admin-web/app/styles/user-management.css b/ambari-admin/src/main/resources/ui/admin-web/app/styles/user-management.css
index 3c9756e..bca53ca 100644
--- a/ambari-admin/src/main/resources/ui/admin-web/app/styles/user-management.css
+++ b/ambari-admin/src/main/resources/ui/admin-web/app/styles/user-management.css
@@ -20,6 +20,10 @@
   vertical-align: baseline;
 }
 
+#user-management .search-box-row {
+  margin-top: -1px;
+}
+
 #user-management .nav.nav-tabs {
   margin-bottom: 0;
 }

http://git-wip-us.apache.org/repos/asf/ambari/blob/81c04545/ambari-admin/src/main/resources/ui/admin-web/app/views/ambariViews/viewsList.html
----------------------------------------------------------------------
diff --git a/ambari-admin/src/main/resources/ui/admin-web/app/views/ambariViews/viewsList.html b/ambari-admin/src/main/resources/ui/admin-web/app/views/ambariViews/viewsList.html
index 9e9cb55..48f445b 100644
--- a/ambari-admin/src/main/resources/ui/admin-web/app/views/ambariViews/viewsList.html
+++ b/ambari-admin/src/main/resources/ui/admin-web/app/views/ambariViews/viewsList.html
@@ -115,13 +115,12 @@
     <div class="col-sm-12 table-bar" ng-show="instances.length >= minInstanceForPagination">
         <div class="pull-left filtered-info">
             <span>{{'common.filterInfo' | translate:{showed: tableInfo.showed, total: tableInfo.filtered, term: urs.urls} }}</span>
-            <span ng-show="isNotEmptyFilter">- <a href ng-click="clearFilters()">{{'common.controls.clearFilters' | translate}}</a></span>
         </div>
         <div class="pull-right left-margin">
-            <pagination class="paginator" total-items="tableInfo.filtered" max-size="maxVisiblePages" items-per-page="instancesPerPage" ng-model="currentPage" ng-change="pageChanged()"></pagination>
+            <pagination class="paginator" total-items="tableInfo.filtered" max-size="pagination.maxVisiblePages" items-per-page="pagination.itemsPerPage" ng-model="pagination.currentPage" ng-change="pageChanged()"></pagination>
         </div>
         <div class="pull-right">
-            <select class="form-control" ng-model="instancesPerPage" ng-change="resetPagination()" ng-options="currOption for currOption in [10, 25, 50, 100]"></select>
+            <select class="form-control" ng-model="pagination.itemsPerPage" ng-change="resetPagination()" ng-options="currOption for currOption in [10, 25, 50, 100]"></select>
         </div>
     </div>
 

http://git-wip-us.apache.org/repos/asf/ambari/blob/81c04545/ambari-admin/src/main/resources/ui/admin-web/app/views/remoteClusters/list.html
----------------------------------------------------------------------
diff --git a/ambari-admin/src/main/resources/ui/admin-web/app/views/remoteClusters/list.html b/ambari-admin/src/main/resources/ui/admin-web/app/views/remoteClusters/list.html
index 7a8e6f4..5f8a0be 100644
--- a/ambari-admin/src/main/resources/ui/admin-web/app/views/remoteClusters/list.html
+++ b/ambari-admin/src/main/resources/ui/admin-web/app/views/remoteClusters/list.html
@@ -23,30 +23,34 @@
         {{'views.registerRemoteCluster' | translate}}
       </a>
     </div>
+    <div class="search-box-button pull-right">
+      <button class="btn btn-default" ng-click="toggleSearchBox()">
+        <i class="fa fa-filter" aria-hidden="true"></i>
+      </button>
+      <div class="popup-arrow-up hide"></div>
+    </div>
+  </div>
+
+  <div class="search-box-row hide">
+    <combo-search suggestions="filters" filter-change="filterClusters" placeholder="Search"></combo-search>
   </div>
+
   <table class="table table-striped table-hover">
     <thead>
       <tr>
         <th class="col-sm-3">
           <div class="search-container">
-            <label for="">{{'views.clusterName' | translate}}</label>
-            <input type="text" class="form-control namefilter" placeholder="{{'common.any' | translate}}" ng-model="currentNameFilter" ng-change="resetPagination()">
-            <button type="button" class="close" ng-show="currentNameFilter" ng-click="currentNameFilter=''; resetPagination()"><span aria-hidden="true">&times;</span><span class="sr-only">{{'common.controls.close' | translate}}</span></button>
+            <label>{{'views.clusterName' | translate}}</label>
           </div>
         </th>
         <th class="col-sm-9">
-          <label for="">{{'common.services' | translate}}</label>
-          <select class="form-control typefilter"
-                  ng-model="currentTypeFilter"
-                  ng-options="item for item in typeFilterOptions"
-                  ng-change="resetPagination();">
-          </select>
+          <label>{{'common.services' | translate}}</label>
         </th>
       </tr>
     </thead>
     <tbody>
-    <tr ng-repeat="remoteCluster in remoteClusters" >
-      <td class="col-sm-3"><a href="#/remoteClusters/{{remoteCluster.ClusterInfo.name}}/edit">{{ remoteCluster.ClusterInfo.name }}</a></td>
+    <tr ng-repeat="remoteCluster in remoteClusters  | filter : { isShowed: true }">
+      <td class="col-sm-3"><a href="#/remoteClusters/{{remoteCluster.ClusterInfo.name}}/edit">{{ remoteCluster.clusterName }}</a></td>
       <td class="col-sm-9">
         <span ng-repeat="service in remoteCluster.ClusterInfo.services" ng-if="remoteCluster.ClusterInfo.services.length > 0">{{ service }}{{$last ? '' : ','}} </span>
         <span ng-if="remoteCluster.ClusterInfo.services.length == 0">--</span>
@@ -58,19 +62,18 @@
   <div ng-if="isLoading" class="spinner-container">
     <i class="fa fa-2x fa-spinner fa-spin" aria-hidden="true"></i>
   </div>
-  <div class="alert empty-table-alert col-sm-12" ng-show="!remoteClusters.length && !isLoading">
+  <div class="alert empty-table-alert col-sm-12" ng-show="!tableInfo.showed && !isLoading">
     {{'common.alerts.noRemoteClusterDisplay' | translate}}
   </div>
   <div class="col-sm-12 table-bar" ng-show="tableInfo.total >= minInstanceForPagination">
     <div class="pull-left filtered-info">
       <span>{{'common.filterInfo' | translate:{showed: tableInfo.showed, total: tableInfo.total, term: constants.groups} }}</span>
-      <span ng-show="isNotEmptyFilter">- <a href ng-click="clearFilters()">{{'common.controls.clearFilters' | translate}}</a></span>
     </div>
     <div class="pull-right left-margin">
-      <pagination class="paginator" total-items="totalGroups" max-size="maxVisiblePages" items-per-page="groupsPerPage" ng-model="currentPage" ng-change="pageChanged()"></pagination>
+      <pagination class="paginator" total-items="tableInfo.filtered" max-size="pagination.maxVisiblePages" items-per-page="groupsPerPage" ng-model="pagination.currentPage" ng-change="pageChanged()"></pagination>
     </div>
     <div class="pull-right">
-      <select class="form-control" ng-model="groupsPerPage" ng-change="groupsPerPageChanges()" ng-options="currOption for currOption in [10, 25, 50, 100]"></select>
+      <select class="form-control" ng-model="pagination.itemsPerPage" ng-change="resetPagination()" ng-options="currOption for currOption in [10, 25, 50, 100]"></select>
     </div>
   </div>
 

http://git-wip-us.apache.org/repos/asf/ambari/blob/81c04545/ambari-admin/src/main/resources/ui/admin-web/app/views/stackVersions/list.html
----------------------------------------------------------------------
diff --git a/ambari-admin/src/main/resources/ui/admin-web/app/views/stackVersions/list.html b/ambari-admin/src/main/resources/ui/admin-web/app/views/stackVersions/list.html
index 9d81543..697b3b2 100644
--- a/ambari-admin/src/main/resources/ui/admin-web/app/views/stackVersions/list.html
+++ b/ambari-admin/src/main/resources/ui/admin-web/app/views/stackVersions/list.html
@@ -23,47 +23,42 @@
         {{'versions.register.title' | translate}}
       </a>
     </div>
+    <div class="search-box-button pull-right">
+      <button class="btn btn-default" ng-click="toggleSearchBox()">
+        <i class="fa fa-filter" aria-hidden="true"></i>
+      </button>
+      <div class="popup-arrow-up hide"></div>
+    </div>
+  </div>
+
+  <div class="search-box-row hide">
+    <combo-search suggestions="filters" filter-change="filterRepos" placeholder="Search"></combo-search>
   </div>
+
   <table class="table table-striped table-hover">
     <thead>
     <tr>
       <th class="col-small">
         <label>{{'common.stack' | translate}}</label>
-        <select class="form-control"
-                ng-change="resetPagination()"
-                ng-model="filter.stack.current"
-                ng-options="item.label for item in filter.stack.options track by item.value"
-          ></select>
       </th>
       <th class="col-medium text-search-container">
         <label>{{'common.name' | translate}}</label>
-        <input type="text" class="form-control" ng-change="resetPagination()" ng-model="filter.name" placeholder="{{'common.any' | translate}}">
-        <button type="button" class="close clearfilter" ng-show="filter.name" ng-click="filter.name=''; resetPagination()"><span aria-hidden="true">&times;</span><span class="sr-only">{{'common.controls.close' | translate}}</span></button>
       </th>
       <th class="col-medium text-search-container">
         <label>{{'common.type' | translate}}</label>
-        <input type="text" class="form-control" ng-change="resetPagination()" ng-model="filter.type" placeholder="{{'common.any' | translate}}">
-        <button type="button" class="close clearfilter" ng-show="filter.type" ng-click="filter.type=''; resetPagination()"><span aria-hidden="true">&times;</span><span class="sr-only">{{'common.controls.close' | translate}}</span></button>
       </th>
       <th class="col-medium text-search-container">
         <label>{{'common.version' | translate}}</label>
-        <input type="text" class="form-control" ng-change="resetPagination()" ng-model="filter.version" placeholder="{{'common.any' | translate}}">
-        <button type="button" class="close clearfilter" ng-show="filter.version" ng-click="filter.version=''; resetPagination()"><span aria-hidden="true">&times;</span><span class="sr-only">{{'common.controls.close' | translate}}</span></button>
       </th>
       <th class="col-small">
         <label>{{'common.cluster' | translate}}</label>
-        <select class="form-control"
-                ng-change="resetPagination()"
-                ng-model="filter.cluster.current"
-                ng-options="item.label for item in filter.cluster.options track by item.value"
-          ></select>
       </th>
       <th class="col-small"></th>
       <th class="col-small text-center vertical-top">{{'common.hidden' | translate}}</th>
     </tr>
     </thead>
     <tbody>
-    <tr ng-repeat="repo in repos">
+    <tr ng-repeat="repo in repos | filter : { isShowed: true }">
       <td class="col-small">
         <span>{{repo.stack_name}}-{{repo.stack_version}}</span>
       </td>
@@ -120,17 +115,16 @@
   <div ng-if="isLoading" class="spinner-container">
     <i class="fa fa-2x fa-spinner fa-spin" aria-hidden="true"></i>
   </div>
-  <div class="alert empty-table-alert col-sm-12" ng-show="!repos.length && !isLoading">
+  <div class="alert empty-table-alert col-sm-12" ng-show="!tableInfo.showed && !isLoading">
     {{'common.alerts.nothingToDisplay' | translate:{term: getConstant("common.version")} }}
   </div>
   <div class="col-sm-12 table-bar" ng-show="tableInfo.total >= minInstanceForPagination">
     <div class="pull-left filtered-info">
       <span>{{'common.filterInfo' | translate:{showed: tableInfo.showed, total: tableInfo.total, term: getConstant("common.versions")} }}</span>
-      <span ng-show="isNotEmptyFilter">- <a href ng-click="clearFilters()">{{'common.controls.clearFilters' | translate}}</a></span>
     </div>
     <div class="pull-right left-margin">
       <pagination class="paginator"
-                  total-items="pagination.totalRepos"
+                  total-items="tableInfo.total"
                   max-size="pagination.maxVisiblePages"
                   items-per-page="pagination.itemsPerPage"
                   ng-model="pagination.currentPage"

http://git-wip-us.apache.org/repos/asf/ambari/blob/81c04545/ambari-admin/src/main/resources/ui/admin-web/app/views/userManagement/groupsList.html
----------------------------------------------------------------------
diff --git a/ambari-admin/src/main/resources/ui/admin-web/app/views/userManagement/groupsList.html b/ambari-admin/src/main/resources/ui/admin-web/app/views/userManagement/groupsList.html
index af8303d..4218a65 100644
--- a/ambari-admin/src/main/resources/ui/admin-web/app/views/userManagement/groupsList.html
+++ b/ambari-admin/src/main/resources/ui/admin-web/app/views/userManagement/groupsList.html
@@ -16,11 +16,24 @@
 * limitations under the License.
 -->
 <div class="groups-pane">
-  <div class="clearfix panel">
-    <button class="btn btn-default creategroup-btn pull-right" ng-click="createGroup()">
-      {{'groups.createLocal' | translate}}
-    </button>
+  <div class="clearfix">
+    <div class="pull-right">
+      <button class="btn btn-default creategroup-btn pull-right" ng-click="createGroup()">
+        {{'groups.createLocal' | translate}}
+      </button>
+    </div>
+    <div class="search-box-button pull-right">
+      <button class="btn btn-default" ng-click="toggleSearchBox()">
+        <i class="fa fa-filter" aria-hidden="true"></i>
+      </button>
+      <div class="popup-arrow-up hide"></div>
+    </div>
   </div>
+
+  <div class="search-box-row hide">
+    <combo-search suggestions="filters" filter-change="filterGroups" placeholder="Search"></combo-search>
+  </div>
+
   <table class="table table-striped table-hover col-sm-12">
     <thead>
       <tr>
@@ -37,26 +50,9 @@
           <span>{{'common.actions' | translate}}</span>
         </th>
       </tr>
-      <tr>
-        <th class="col-sm-6">
-          <div class="search-container">
-            <input type="text" class="form-control namefilter" placeholder="{{'common.any' | translate}}" ng-model="filter.name" ng-change="resetPagination()">
-            <button type="button" class="close" ng-show="filter.name" ng-click="filter.name=''; resetPagination()"><span aria-hidden="true">&times;</span><span class="sr-only">{{'common.controls.close' | translate}}</span></button>
-          </div>
-        </th>
-        <th class="col-sm-2">
-          <select class="form-control typefilter"
-                  ng-model="filter.type"
-                  ng-options="item.label for item in typeFilterOptions"
-                  ng-change="resetPagination();">
-          </select>
-        </th>
-        <th class="col-sm-2"></th>
-        <th class="col-sm-2"></th>
-      </tr>
     </thead>
     <tbody>
-      <tr ng-repeat="group in groups">
+      <tr ng-repeat="group in groups | filter : { isShowed: true }">
         <td class="col-sm-8">
           <span>{{group.group_name}}</span>
         </td>
@@ -76,19 +72,18 @@
   <div ng-if="isLoading" class="spinner-container">
     <i class="fa fa-2x fa-spinner fa-spin" aria-hidden="true"></i>
   </div>
-  <div class="alert empty-table-alert col-sm-12" ng-show="!groups.length && !isLoading">
+  <div class="alert empty-table-alert col-sm-12" ng-show="!tableInfo.showed && !isLoading">
     {{'common.alerts.nothingToDisplay' | translate:{term: constants.groups} }}
   </div>
-  <div class="col-sm-12 table-bar" ng-show="totalGroups > minRowsToShowPagination">
+  <div class="col-sm-12 table-bar" ng-show="tableInfo.total > minRowsToShowPagination">
     <div class="pull-left filtered-info">
-      <span>{{'common.filterInfo' | translate:{showed: tableInfo.showed, total: tableInfo.total, term: constants.groups} }}</span>
-      <span ng-show="isNotEmptyFilter">- <a href ng-click="clearFilters()">{{'common.controls.clearFilters' | translate}}</a></span>
+      <span>{{'common.filterInfo' | translate:{showed: tableInfo.showed, total: tableInfo.filtered, term: constants.groups} }}</span>
     </div>
     <div class="pull-right left-margin">
-      <pagination class="paginator" total-items="totalGroups" max-size="maxVisiblePages" items-per-page="groupsPerPage" ng-model="currentPage" ng-change="pageChanged()"></pagination>
+      <pagination class="paginator" total-items="tableInfo.filtered" max-size="pagination.maxVisiblePages" items-per-page="pagination.itemsPerPage" ng-model="pagination.currentPage" ng-change="pageChanged()"></pagination>
     </div>
     <div class="pull-right">
-      <select class="form-control" ng-model="groupsPerPage" ng-change="groupsPerPageChanges()" ng-options="currOption for currOption in [10, 25, 50, 100]"></select>
+      <select class="form-control" ng-model="pagination.itemsPerPage" ng-change="resetPagination()" ng-options="currOption for currOption in [10, 25, 50, 100]"></select>
     </div>
   </div>
 </div>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/ambari/blob/81c04545/ambari-admin/src/main/resources/ui/admin-web/app/views/userManagement/usersList.html
----------------------------------------------------------------------
diff --git a/ambari-admin/src/main/resources/ui/admin-web/app/views/userManagement/usersList.html b/ambari-admin/src/main/resources/ui/admin-web/app/views/userManagement/usersList.html
index 23e9ddb..2348dad 100644
--- a/ambari-admin/src/main/resources/ui/admin-web/app/views/userManagement/usersList.html
+++ b/ambari-admin/src/main/resources/ui/admin-web/app/views/userManagement/usersList.html
@@ -17,14 +17,27 @@
 -->
 
 <div class="users-pane">
-  <div class="clearfix panel">
-    <button class="btn btn-default createuser-btn pull-right" ng-click="createUser();">
-      {{'users.create' | translate}}
-    </button>
+  <div class="clearfix">
+    <div class="pull-right">
+      <button class="btn btn-default createuser-btn pull-right" ng-click="createUser();">
+        {{'users.create' | translate}}
+      </button>
+    </div>
+    <div class="search-box-button pull-right">
+      <button class="btn btn-default" ng-click="toggleSearchBox()">
+        <i class="fa fa-filter" aria-hidden="true"></i>
+      </button>
+      <div class="popup-arrow-up hide"></div>
+    </div>
   </div>
+
+  <div class="search-box-row hide">
+    <combo-search suggestions="filters" filter-change="filterUsers" placeholder="Search"></combo-search>
+  </div>
+
   <table class="table table-striped table-hover">
     <thead>
-      <tr class="fix-bottom">
+      <tr>
         <th>
           <span>{{'users.username' | translate}}</span>
         </th>
@@ -44,36 +57,9 @@
           <span>{{'common.actions' | translate}}</span>
         </th>
       </tr>
-      <tr class="fix-top">
-        <th>
-          <div class="search-container">
-            <input type="text" class="form-control namefilter" placeholder="{{'common.any' | translate}}" ng-model="filters.name" ng-change="resetPagination()">
-            <button type="button" class="close clearfilter" ng-show="filters.name" ng-click="filters.name=''; resetPagination()">
-              <span aria-hidden="true">&times;</span><span class="sr-only">{{'common.controls.close' | translate}}</span>
-            </button>
-          </div>
-        </th>
-        <th></th>
-        <th>
-          <select class="form-control statusfilter"
-                  ng-model="filters.status"
-                  ng-options="item.label for item in activeFilterOptions"
-                  ng-change="resetPagination()">
-          </select>
-        </th>
-        <th>
-          <select class="form-control typefilter"
-                  ng-model="filters.type"
-                  ng-options="item.label for item in typeFilterOptions"
-                  ng-change="resetPagination()">
-          </select>
-        </th>
-        <th></th>
-        <th></th>
-      </tr>
     </thead>
     <tbody>
-      <tr ng-repeat="user in users">
+      <tr ng-repeat="user in users | filter : { isShowed: true }">
         <td>
           <span>{{user.Users.user_name}}</span>
         </td>
@@ -101,19 +87,18 @@
   <div ng-if="isLoading" class="spinner-container">
     <i class="fa fa-2x fa-spinner fa-spin" aria-hidden="true"></i>
   </div>
-  <div class="alert empty-table-alert col-sm-12" ng-show="!users.length && !isLoading">
+  <div class="alert empty-table-alert col-sm-12" ng-show="!tableInfo.showed && !isLoading">
     {{'common.alerts.nothingToDisplay' | translate:{term: constants.users} }}
   </div>
-  <div class="col-sm-12 table-bar" ng-show="totalUsers > minRowsToShowPagination">
+  <div class="col-sm-12 table-bar" ng-show="users.length > minRowsToShowPagination">
     <div class="pull-left filtered-info">
       <span>{{'common.filterInfo' | translate:{showed: tableInfo.showed, total: tableInfo.total, term: constants.users} }}</span>
-      <span ng-show="isNotEmptyFilter">- <a href ng-click="clearFilters()">{{'common.controls.clearFilters' | translate}}</a></span>
     </div>
     <div class="pull-right left-margin">
-      <pagination class="paginator" total-items="totalUsers" max-size="maxVisiblePages" items-per-page="usersPerPage" ng-model="currentPage" ng-change="pageChanged()"></pagination>
+      <pagination class="paginator" total-items="tableInfo.filtered" max-size="pagination.maxVisiblePages" items-per-page="pagination.itemsPerPage" ng-model="pagination.currentPage" ng-change="pageChanged()"></pagination>
     </div>
     <div class="pull-right">
-      <select class="form-control" ng-model="usersPerPage" ng-change="usersPerPageChanges()" ng-options="currOption for currOption in [10, 25, 50, 100]"></select>
+      <select class="form-control" ng-model="pagination.itemsPerPage" ng-change="resetPagination()" ng-options="currOption for currOption in [10, 25, 50, 100]"></select>
     </div>
   </div>
 </div>

http://git-wip-us.apache.org/repos/asf/ambari/blob/81c04545/ambari-admin/src/main/resources/ui/admin-web/test/unit/controllers/ambariViews/ViewsListCtrl_test.js
----------------------------------------------------------------------
diff --git a/ambari-admin/src/main/resources/ui/admin-web/test/unit/controllers/ambariViews/ViewsListCtrl_test.js b/ambari-admin/src/main/resources/ui/admin-web/test/unit/controllers/ambariViews/ViewsListCtrl_test.js
index 362b94a..ca8205c 100644
--- a/ambari-admin/src/main/resources/ui/admin-web/test/unit/controllers/ambariViews/ViewsListCtrl_test.js
+++ b/ambari-admin/src/main/resources/ui/admin-web/test/unit/controllers/ambariViews/ViewsListCtrl_test.js
@@ -24,6 +24,9 @@ describe('#Cluster', function () {
       module('ambariAdminConsole');
       inject(function($rootScope, $controller) {
         scope = $rootScope.$new();
+        scope.pagination = {
+          resetPagination: angular.noop
+        };
         ctrl = $controller('ViewsListCtrl', {$scope: scope});
       });
       scope.instances = [
@@ -44,68 +47,9 @@ describe('#Cluster', function () {
       ];
     });
 
-    describe('#initFilterOptions()', function () {
-      beforeEach(function() {
-        scope.initFilterOptions();
-      });
-
-      it('should fill short_url_name options', function() {
-        expect(scope.filters[0].options).toEqual([
-          {
-            key: 'sun1',
-            label: 'sun1'
-          },
-          {
-            key: 'sun2',
-            label: 'sun2'
-          }
-        ]);
-      });
-
-      it('should fill url options', function() {
-        expect(scope.filters[1].options).toEqual([
-          {
-            key: '/main/view/vn1/su1',
-            label: '/main/view/vn1/su1'
-          },
-          {
-            key: '/main/view/vn2/su2',
-            label: '/main/view/vn2/su2'
-          }
-        ]);
-      });
-
-      it('should fill view_name options', function() {
-        expect(scope.filters[2].options).toEqual([
-          {
-            key: 'vn1',
-            label: 'vn1'
-          },
-          {
-            key: 'vn2',
-            label: 'vn2'
-          }
-        ]);
-      });
-
-      it('should fill instance_name options', function() {
-        expect(scope.filters[3].options).toEqual([
-          {
-            key: 'in1',
-            label: 'in1'
-          },
-          {
-            key: 'in2',
-            label: 'in2'
-          }
-        ]);
-      });
-    });
-
-
     describe('#filterInstances', function() {
       beforeEach(function() {
-        spyOn(scope, 'resetPagination');
+        spyOn(scope.pagination, 'resetPagination');
       });
 
       it('all should be filtered when filters not applied', function() {
@@ -117,7 +61,7 @@ describe('#Cluster', function () {
 
       it('resetPagination should be called', function() {
         scope.filterInstances();
-        expect(scope.resetPagination).toHaveBeenCalled();
+        expect(scope.pagination.resetPagination).toHaveBeenCalled();
       });
 
       it('one view should be filtered', function() {

http://git-wip-us.apache.org/repos/asf/ambari/blob/81c04545/ambari-admin/src/main/resources/ui/admin-web/test/unit/controllers/userManagement/GroupsListCtrl_test.js
----------------------------------------------------------------------
diff --git a/ambari-admin/src/main/resources/ui/admin-web/test/unit/controllers/userManagement/GroupsListCtrl_test.js b/ambari-admin/src/main/resources/ui/admin-web/test/unit/controllers/userManagement/GroupsListCtrl_test.js
index 8d04757..1e76aec 100644
--- a/ambari-admin/src/main/resources/ui/admin-web/test/unit/controllers/userManagement/GroupsListCtrl_test.js
+++ b/ambari-admin/src/main/resources/ui/admin-web/test/unit/controllers/userManagement/GroupsListCtrl_test.js
@@ -20,110 +20,20 @@ describe('#Cluster', function () {
 
   describe('GroupsListCtrl', function() {
 
-    var scope, ctrl, $t, $httpBackend;
+    var $scope, ctrl, $t, $httpBackend, $group;
 
     beforeEach(module('ambariAdminConsole', function () {}));
 
-    beforeEach(inject(function($rootScope, $controller, _$translate_, _$httpBackend_) {
-      scope = $rootScope.$new();
+    beforeEach(inject(function($rootScope, $controller, _$translate_, _$httpBackend_, _Group_) {
+      $scope = $rootScope.$new();
       $t = _$translate_.instant;
       $httpBackend = _$httpBackend_;
+      $group = _Group_;
       ctrl = $controller('GroupsListCtrl', {
-        $scope: scope
+        $scope: $scope
       });
     }));
 
-    describe('#clearFilters()', function () {
-
-      it('should clear filters and reset pagination', function () {
-        scope.currentPage = 2;
-        scope.filter.name = 'a';
-        scope.filter.type = {
-          label: $t('common.local'),
-          value: false
-        };
-        scope.clearFilters();
-        expect(scope.filter.name).toEqual('');
-        expect(scope.filter.type).toEqual({
-          label: $t('common.all'),
-          value: '*'
-        });
-        expect(scope.currentPage).toEqual(1);
-      });
-
-    });
-
-    describe('#isNotEmptyFilter', function () {
-
-      var cases = [
-        {
-          currentNameFilter: '',
-          currentTypeFilter: null,
-          isNotEmptyFilter: false,
-          title: 'no filters'
-        },
-        {
-          currentNameFilter: '',
-          currentTypeFilter: {
-            value: '*'
-          },
-          isNotEmptyFilter: false,
-          title: 'empty filters'
-        },
-        {
-          currentNameFilter: 'a',
-          currentTypeFilter: {
-            value: '*'
-          },
-          isNotEmptyFilter: true,
-          title: 'name filter'
-        },
-        {
-          currentNameFilter: '0',
-          currentTypeFilter: {
-            value: '*'
-          },
-          isNotEmptyFilter: true,
-          title: 'name filter with "0" as string'
-        },
-        {
-          currentNameFilter: '',
-          currentTypeFilter: {
-            value: false
-          },
-          isNotEmptyFilter: true,
-          title: 'type filter'
-        },
-        {
-          currentNameFilter: 'a',
-          currentTypeFilter: {
-            value: false
-          },
-          isNotEmptyFilter: true,
-          title: 'both filters'
-        },
-        {
-          currentNameFilter: '0',
-          currentTypeFilter: {
-            value: false
-          },
-          isNotEmptyFilter: true,
-          title: 'both filters with "0" as string'
-        }
-      ];
-
-      cases.forEach(function (item) {
-        it(item.title, function () {
-          $httpBackend.expectGET(/\/api\/v1\/groups/).respond(200);
-          scope.filter.name = item.currentNameFilter;
-          scope.filter.type = item.currentTypeFilter;
-          scope.$digest();
-          expect(scope.isNotEmptyFilter).toEqual(item.isNotEmptyFilter);
-        });
-      });
-
-    });
-
   });
 
 });


[20/24] ambari git commit: AMBARI-22677. Don't call pprint.pformat unnecessarily in Ambari agent (amagyar)

Posted by nc...@apache.org.
AMBARI-22677. Don't call pprint.pformat unnecessarily in Ambari agent (amagyar)


Project: http://git-wip-us.apache.org/repos/asf/ambari/repo
Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/4e731d31
Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/4e731d31
Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/4e731d31

Branch: refs/heads/branch-feature-AMBARI-21674
Commit: 4e731d31f7c59bceab3c91565686384645251546
Parents: f3dc1ca
Author: Attila Magyar <am...@hortonworks.com>
Authored: Wed Dec 20 14:16:36 2017 +0100
Committer: Attila Magyar <am...@hortonworks.com>
Committed: Wed Dec 20 14:16:36 2017 +0100

----------------------------------------------------------------------
 .../src/main/python/ambari_agent/ActionQueue.py | 21 ++++++++++----------
 .../python/ambari_agent/CommandStatusDict.py    |  2 +-
 .../src/main/python/ambari_agent/Controller.py  | 17 ++++++++--------
 .../ambari_agent/CustomServiceOrchestrator.py   |  4 ++--
 .../src/main/python/ambari_agent/DataCleaner.py |  4 ++--
 .../src/main/python/ambari_agent/Heartbeat.py   | 17 ++++++++--------
 .../src/main/python/ambari_agent/LiveStatus.py  |  3 +--
 .../main/python/ambari_agent/PythonExecutor.py  | 15 +++++++-------
 .../ambari_agent/PythonReflectiveExecutor.py    |  3 ++-
 .../main/python/ambari_agent/RecoveryManager.py | 17 ++++++++--------
 .../ambari_agent/StatusCommandsExecutor.py      |  3 ++-
 .../python/ambari_agent/alerts/ams_alert.py     |  8 +++++---
 .../python/ambari_agent/alerts/metric_alert.py  |  3 ++-
 .../src/main/python/ambari_agent/security.py    |  8 ++++----
 14 files changed, 66 insertions(+), 59 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ambari/blob/4e731d31/ambari-agent/src/main/python/ambari_agent/ActionQueue.py
----------------------------------------------------------------------
diff --git a/ambari-agent/src/main/python/ambari_agent/ActionQueue.py b/ambari-agent/src/main/python/ambari_agent/ActionQueue.py
index f1b3a42..da4dc4c 100644
--- a/ambari-agent/src/main/python/ambari_agent/ActionQueue.py
+++ b/ambari-agent/src/main/python/ambari_agent/ActionQueue.py
@@ -121,7 +121,8 @@ class ActionQueue(threading.Thread):
     for command in commands:
 
       logger.info("Canceling command with taskId = {tid}".format(tid = str(command['target_task_id'])))
-      logger.debug(pprint.pformat(command))
+      if logger.isEnabledFor(logging.DEBUG):
+        logger.debug(pprint.pformat(command))
 
       task_id = command['target_task_id']
       reason = command['reason']
@@ -200,7 +201,7 @@ class ActionQueue(threading.Thread):
   def process_command(self, command):
     # make sure we log failures
     commandType = command['commandType']
-    logger.debug("Took an element of Queue (command type = %s)." % commandType)
+    logger.debug("Took an element of Queue (command type = %s).", commandType)
     try:
       if commandType in [self.EXECUTION_COMMAND, self.BACKGROUND_EXECUTION_COMMAND, self.AUTO_EXECUTION_COMMAND]:
         try:
@@ -211,7 +212,7 @@ class ActionQueue(threading.Thread):
           if self.controller.recovery_manager.enabled():
             self.controller.recovery_manager.stop_execution_command()
       else:
-        logger.error("Unrecognized command " + pprint.pformat(command))
+        logger.error("Unrecognized command %s", pprint.pformat(command))
     except Exception:
       logger.exception("Exception while processing {0} command".format(commandType))
 
@@ -475,14 +476,14 @@ class ActionQueue(threading.Thread):
     self.customServiceOrchestrator
 
   def on_background_command_complete_callback(self, process_condensed_result, handle):
-    logger.debug('Start callback: %s' % process_condensed_result)
-    logger.debug('The handle is: %s' % handle)
+    logger.debug('Start callback: %s', process_condensed_result)
+    logger.debug('The handle is: %s', handle)
     status = self.COMPLETED_STATUS if handle.exitCode == 0 else self.FAILED_STATUS
 
     aborted_postfix = self.customServiceOrchestrator.command_canceled_reason(handle.command['taskId'])
     if aborted_postfix:
       status = self.FAILED_STATUS
-      logger.debug('Set status to: %s , reason = %s' % (status, aborted_postfix))
+      logger.debug('Set status to: %s , reason = %s', status, aborted_postfix)
     else:
       aborted_postfix = ''
 
@@ -556,11 +557,9 @@ class ActionQueue(threading.Thread):
 
         result['extra'] = component_extra
 
-      logger.debug("Got live status for component " + component + \
-                   " of service " + str(service) + \
-                   " of cluster " + str(cluster))
-
-      logger.debug(pprint.pformat(result))
+      if logger.isEnabledFor(logging.DEBUG):
+        logger.debug("Got live status for component %s of service %s of cluster %s", component, service, cluster)
+        logger.debug(pprint.pformat(result))
       if result is not None:
         self.commandStatuses.put_command_status(command, result)
     except Exception, err:

http://git-wip-us.apache.org/repos/asf/ambari/blob/4e731d31/ambari-agent/src/main/python/ambari_agent/CommandStatusDict.py
----------------------------------------------------------------------
diff --git a/ambari-agent/src/main/python/ambari_agent/CommandStatusDict.py b/ambari-agent/src/main/python/ambari_agent/CommandStatusDict.py
index 7a97f3f..8ff5818 100644
--- a/ambari-agent/src/main/python/ambari_agent/CommandStatusDict.py
+++ b/ambari-agent/src/main/python/ambari_agent/CommandStatusDict.py
@@ -105,7 +105,7 @@ class CommandStatusDict():
           # Component status is useful once, removing it
           del self.current_state[key]
         elif command ['commandType'] in [ActionQueue.AUTO_EXECUTION_COMMAND]:
-          logger.debug("AUTO_EXECUTION_COMMAND task deleted " + str(command['commandId']))
+          logger.debug("AUTO_EXECUTION_COMMAND task deleted %s", command['commandId'])
           del self.current_state[key]
           pass
       result = {

http://git-wip-us.apache.org/repos/asf/ambari/blob/4e731d31/ambari-agent/src/main/python/ambari_agent/Controller.py
----------------------------------------------------------------------
diff --git a/ambari-agent/src/main/python/ambari_agent/Controller.py b/ambari-agent/src/main/python/ambari_agent/Controller.py
index bc923c3..ef50440 100644
--- a/ambari-agent/src/main/python/ambari_agent/Controller.py
+++ b/ambari-agent/src/main/python/ambari_agent/Controller.py
@@ -174,8 +174,9 @@ class Controller(threading.Thread):
                       self.hostname, prettyData)
 
         ret = self.sendRequest(self.registerUrl, data)
-        prettyData = pprint.pformat(ret)
-        logger.debug("Registration response is %s", prettyData)
+
+        if logger.isEnabledFor(logging.DEBUG):
+          logger.debug("Registration response is %s", pprint.pformat(ret))
 
         # exitstatus is a code of error which was raised on server side.
         # exitstatus = 0 (OK - Default)
@@ -203,7 +204,7 @@ class Controller(threading.Thread):
         self.cluster_configuration.update_configurations_from_heartbeat(ret)
         self.recovery_manager.update_configuration_from_registration(ret)
         self.config.update_configuration_from_registration(ret)
-        logger.debug("Updated config:" + str(self.config))
+        logger.debug("Updated config: %s", self.config)
 
         # Start StatusCommandExecutor child process or restart it if already running
         # in order to receive up to date agent config.
@@ -557,11 +558,11 @@ class Controller(threading.Thread):
     if LiveStatus.SERVICES:
       return
 
-    logger.debug("Updating components map of cluster " + cluster_name)
+    logger.debug("Updating components map of cluster %s", cluster_name)
 
     # May throw IOError on server connection error
     response = self.sendRequest(self.componentsUrl + cluster_name, None)
-    logger.debug("Response from %s was %s", self.serverHostname, str(response))
+    logger.debug("Response from %s was %s", self.serverHostname, response)
 
     services, client_components, server_components = [], [], []
     for service, components in response['components'].items():
@@ -578,9 +579,9 @@ class Controller(threading.Thread):
     LiveStatus.COMPONENTS = server_components
 
     logger.debug("Components map updated")
-    logger.debug("LiveStatus.SERVICES" + str(LiveStatus.SERVICES))
-    logger.debug("LiveStatus.CLIENT_COMPONENTS" + str(LiveStatus.CLIENT_COMPONENTS))
-    logger.debug("LiveStatus.COMPONENTS" + str(LiveStatus.COMPONENTS))
+    logger.debug("LiveStatus.SERVICES %s", LiveStatus.SERVICES)
+    logger.debug("LiveStatus.CLIENT_COMPONENTS %s", LiveStatus.CLIENT_COMPONENTS)
+    logger.debug("LiveStatus.COMPONENTS %s", LiveStatus.COMPONENTS)
 
   def get_status_commands_executor(self):
     return self.statusCommandsExecutor

http://git-wip-us.apache.org/repos/asf/ambari/blob/4e731d31/ambari-agent/src/main/python/ambari_agent/CustomServiceOrchestrator.py
----------------------------------------------------------------------
diff --git a/ambari-agent/src/main/python/ambari_agent/CustomServiceOrchestrator.py b/ambari-agent/src/main/python/ambari_agent/CustomServiceOrchestrator.py
index 645f824..f92ef1d 100644
--- a/ambari-agent/src/main/python/ambari_agent/CustomServiceOrchestrator.py
+++ b/ambari-agent/src/main/python/ambari_agent/CustomServiceOrchestrator.py
@@ -112,7 +112,7 @@ class CustomServiceOrchestrator():
 
   def map_task_to_process(self, task_id, processId):
     with self.commands_in_progress_lock:
-      logger.debug('Maps taskId=%s to pid=%s' % (task_id, processId))
+      logger.debug('Maps taskId=%s to pid=%s', task_id, processId)
       self.commands_in_progress[task_id] = processId
 
   def cancel_command(self, task_id, reason):
@@ -446,7 +446,7 @@ class CustomServiceOrchestrator():
   def command_canceled_reason(self, task_id):
     with self.commands_in_progress_lock:
       if self.commands_in_progress.has_key(task_id):#Background command do not push in this collection (TODO)
-        logger.debug('Pop with taskId %s' % task_id)
+        logger.debug('Pop with taskId %s', task_id)
         pid = self.commands_in_progress.pop(task_id)
         if not isinstance(pid, int):
           reason = pid

http://git-wip-us.apache.org/repos/asf/ambari/blob/4e731d31/ambari-agent/src/main/python/ambari_agent/DataCleaner.py
----------------------------------------------------------------------
diff --git a/ambari-agent/src/main/python/ambari_agent/DataCleaner.py b/ambari-agent/src/main/python/ambari_agent/DataCleaner.py
index 0b66fa7..9c3b2e1 100644
--- a/ambari-agent/src/main/python/ambari_agent/DataCleaner.py
+++ b/ambari-agent/src/main/python/ambari_agent/DataCleaner.py
@@ -68,7 +68,7 @@ class DataCleaner(threading.Thread):
     logger.info('Data cleanup thread killed.')
 
   def cleanup(self):
-    logger.debug("Cleaning up inside directory " + self.data_dir)
+    logger.debug("Cleaning up inside directory %s", self.data_dir)
     now = time.time()
     total_size_bytes = 0
     file_path_to_timestamp = {}
@@ -82,7 +82,7 @@ class DataCleaner(threading.Thread):
             file_age = now - os.path.getmtime(file_path)
             if file_age > self.file_max_age:
               os.remove(os.path.join(file_path))
-              logger.debug('Removed file: ' + file_path)
+              logger.debug('Removed file: %s', file_path)
             else:
               # Since file wasn't deleted in first pass, consider it for the second one with oldest files first
               file_size = os.path.getsize(file_path)

http://git-wip-us.apache.org/repos/asf/ambari/blob/4e731d31/ambari-agent/src/main/python/ambari_agent/Heartbeat.py
----------------------------------------------------------------------
diff --git a/ambari-agent/src/main/python/ambari_agent/Heartbeat.py b/ambari-agent/src/main/python/ambari_agent/Heartbeat.py
index d7c0325..11ad652 100644
--- a/ambari-agent/src/main/python/ambari_agent/Heartbeat.py
+++ b/ambari-agent/src/main/python/ambari_agent/Heartbeat.py
@@ -75,12 +75,12 @@ class Heartbeat:
     if int(id) == 0:
       componentsMapped = False
 
-    logger.debug("Building Heartbeat: {responseId = %s, timestamp = %s, "
-                "commandsInProgress = %s, componentsMapped = %s,"
-                "recoveryTimestamp = %s}",
-        str(id), str(timestamp), repr(commandsInProgress), repr(componentsMapped), str(recovery_timestamp))
-
-    logger.debug("Heartbeat: %s", pformat(heartbeat))
+    if logger.isEnabledFor(logging.DEBUG):
+      logger.debug("Building Heartbeat: {responseId = %s, timestamp = %s, "
+                   "commandsInProgress = %s, componentsMapped = %s, "
+                   "recoveryTimestamp = %s}",
+                   id, timestamp, commandsInProgress, componentsMapped, recovery_timestamp)
+      logger.debug("Heartbeat: %s", pformat(heartbeat))
 
     hostInfo = HostInfo(self.config)
     if add_state:
@@ -93,8 +93,9 @@ class Heartbeat:
       mounts = Hardware(config=self.config, cache_info=False).osdisks()
       heartbeat['mounts'] = mounts
 
-      logger.debug("agentEnv: %s", str(nodeInfo))
-      logger.debug("mounts: %s", str(mounts))
+      if logger.isEnabledFor(logging.DEBUG):
+        logger.debug("agentEnv: %s", nodeInfo)
+        logger.debug("mounts: %s", mounts)
 
     if self.collector is not None:
       heartbeat['alerts'] = self.collector.alerts()

http://git-wip-us.apache.org/repos/asf/ambari/blob/4e731d31/ambari-agent/src/main/python/ambari_agent/LiveStatus.py
----------------------------------------------------------------------
diff --git a/ambari-agent/src/main/python/ambari_agent/LiveStatus.py b/ambari-agent/src/main/python/ambari_agent/LiveStatus.py
index b6d54ed..a506e28 100644
--- a/ambari-agent/src/main/python/ambari_agent/LiveStatus.py
+++ b/ambari-agent/src/main/python/ambari_agent/LiveStatus.py
@@ -62,6 +62,5 @@ class LiveStatus:
     if active_config is not None:
       livestatus['configurationTags'] = active_config
 
-    logger.debug("The live status for component " + str(self.component) +
-                 " of service " + str(self.service) + " is " + str(livestatus))
+    logger.debug("The live status for component %s of service %s is %s", self.component, self.service, livestatus)
     return livestatus

http://git-wip-us.apache.org/repos/asf/ambari/blob/4e731d31/ambari-agent/src/main/python/ambari_agent/PythonExecutor.py
----------------------------------------------------------------------
diff --git a/ambari-agent/src/main/python/ambari_agent/PythonExecutor.py b/ambari-agent/src/main/python/ambari_agent/PythonExecutor.py
index ea6f895..139c141 100644
--- a/ambari-agent/src/main/python/ambari_agent/PythonExecutor.py
+++ b/ambari-agent/src/main/python/ambari_agent/PythonExecutor.py
@@ -93,7 +93,8 @@ class PythonExecutor(object):
     The structured out file, however, is preserved during multiple invocations that use the same file.
     """
     pythonCommand = self.python_command(script, script_params)
-    logger.debug("Running command " + pprint.pformat(pythonCommand))
+    if logger.isEnabledFor(logging.DEBUG):
+      logger.debug("Running command %s", pprint.pformat(pythonCommand))
 
     if handle is None:
       tmpout, tmperr = self.open_subprocess_files(tmpoutfile, tmperrfile, override_output_files, backup_log_files)
@@ -127,7 +128,7 @@ class PythonExecutor(object):
     """
     Log some useful information after task failure.
     """
-    logger.info("Command " + pprint.pformat(pythonCommand) + " failed with exitcode=" + str(result['exitcode']))
+    logger.info("Command %s failed with exitcode=%s", pprint.pformat(pythonCommand), result['exitcode'])
     log_process_information(logger)
 
   def prepare_process_result(self, returncode, tmpoutfile, tmperrfile, tmpstructedoutfile, timeout=None):
@@ -138,7 +139,7 @@ class PythonExecutor(object):
               (" after waiting %s secs" % str(timeout) if timeout else "")
       returncode = 999
     result = self.condenseOutput(out, error, returncode, structured_out)
-    logger.debug("Result: %s" % result)
+    logger.debug("Result: %s", result)
     return result
 
   def read_result_from_files(self, out_path, err_path, structured_out_path):
@@ -223,10 +224,10 @@ class BackgroundThread(threading.Thread):
   def run(self):
     process_out, process_err = self.pythonExecutor.open_subprocess_files(self.holder.out_file, self.holder.err_file, True)
 
-    logger.debug("Starting process command %s" % self.holder.command)
+    logger.debug("Starting process command %s", self.holder.command)
     process = self.pythonExecutor.launch_python_subprocess(self.holder.command, process_out, process_err)
 
-    logger.debug("Process has been started. Pid = %s" % process.pid)
+    logger.debug("Process has been started. Pid = %s", process.pid)
 
     self.holder.handle.pid = process.pid
     self.holder.handle.status = BackgroundCommandExecutionHandle.RUNNING_STATUS
@@ -236,6 +237,6 @@ class BackgroundThread(threading.Thread):
 
     self.holder.handle.exitCode = process.returncode
     process_condensed_result = self.pythonExecutor.prepare_process_result(process.returncode, self.holder.out_file, self.holder.err_file, self.holder.structured_out_file)
-    logger.debug("Calling callback with args %s" % process_condensed_result)
+    logger.debug("Calling callback with args %s", process_condensed_result)
     self.holder.handle.on_background_command_complete_callback(process_condensed_result, self.holder.handle)
-    logger.debug("Exiting from thread for holder pid %s" % self.holder.handle.pid)
+    logger.debug("Exiting from thread for holder pid %s", self.holder.handle.pid)

http://git-wip-us.apache.org/repos/asf/ambari/blob/4e731d31/ambari-agent/src/main/python/ambari_agent/PythonReflectiveExecutor.py
----------------------------------------------------------------------
diff --git a/ambari-agent/src/main/python/ambari_agent/PythonReflectiveExecutor.py b/ambari-agent/src/main/python/ambari_agent/PythonReflectiveExecutor.py
index b27d7d1..b021320 100644
--- a/ambari-agent/src/main/python/ambari_agent/PythonReflectiveExecutor.py
+++ b/ambari-agent/src/main/python/ambari_agent/PythonReflectiveExecutor.py
@@ -46,7 +46,8 @@ class PythonReflectiveExecutor(PythonExecutor):
                override_output_files = True, backup_log_files = True,
                handle = None, log_info_on_failure=True):
     pythonCommand = self.python_command(script, script_params)
-    logger.debug("Running command reflectively " + pprint.pformat(pythonCommand))
+    if logger.isEnabledFor(logging.DEBUG):
+      logger.debug("Running command reflectively %s", pprint.pformat(pythonCommand))
     
     script_dir = os.path.dirname(script)
     self.open_subprocess_files(tmpoutfile, tmperrfile, override_output_files, backup_log_files)

http://git-wip-us.apache.org/repos/asf/ambari/blob/4e731d31/ambari-agent/src/main/python/ambari_agent/RecoveryManager.py
----------------------------------------------------------------------
diff --git a/ambari-agent/src/main/python/ambari_agent/RecoveryManager.py b/ambari-agent/src/main/python/ambari_agent/RecoveryManager.py
index be335f2..c196fd8 100644
--- a/ambari-agent/src/main/python/ambari_agent/RecoveryManager.py
+++ b/ambari-agent/src/main/python/ambari_agent/RecoveryManager.py
@@ -128,7 +128,7 @@ class RecoveryManager:
 
   def set_paused(self, paused):
     if self.paused != paused:
-      logger.debug("RecoveryManager is transitioning from isPaused = " + str(self.paused) + " to " + str(paused))
+      logger.debug("RecoveryManager is transitioning from isPaused = %s to %s", self.paused, paused)
     self.paused = paused
 
   def enabled(self):
@@ -574,7 +574,8 @@ class RecoveryManager:
 
 
     if reg_resp and "recoveryConfig" in reg_resp:
-      logger.info("RecoverConfig = " + pprint.pformat(reg_resp["recoveryConfig"]))
+      if logger.isEnabledFor(logging.INFO):
+        logger.info("RecoverConfig = %s", pprint.pformat(reg_resp["recoveryConfig"]))
       config = reg_resp["recoveryConfig"]
       if "type" in config:
         if config["type"] in ["AUTO_INSTALL_START", "AUTO_START", "FULL"]:
@@ -691,8 +692,8 @@ class RecoveryManager:
     if commands and len(commands) > 0:
       for command in commands:
         self.store_or_update_command(command)
-        if self.EXECUTION_COMMAND_DETAILS in command:
-          logger.debug("Details to construct exec commands: " + pprint.pformat(command[self.EXECUTION_COMMAND_DETAILS]))
+        if logger.isEnabledFor(logging.DEBUG) and self.EXECUTION_COMMAND_DETAILS in command:
+          logger.debug("Details to construct exec commands: %s", pprint.pformat(command[self.EXECUTION_COMMAND_DETAILS]))
 
     pass
 
@@ -748,7 +749,7 @@ class RecoveryManager:
           # Store the execution command details
           self.remove_command(component)
           self.add_command(component, command[self.EXECUTION_COMMAND_DETAILS])
-          logger.debug("Stored command details for " + component)
+          logger.debug("Stored command details for %s", component)
         else:
           logger.warn("Expected field " + self.EXECUTION_COMMAND_DETAILS + " unavailable.")
         pass
@@ -855,7 +856,7 @@ class RecoveryManager:
       insert_time = self.stored_exec_commands[component_update_key]
       age = self._now_() - insert_time
       if self.COMMAND_REFRESH_DELAY_SEC < age:
-        logger.debug("Removing stored command for component : " + str(component) + " as its " + str(age) + " sec old")
+        logger.debug("Removing stored command for component : %s as it's %s sec old", component, age)
         self.remove_command(component)
     pass
 
@@ -867,7 +868,7 @@ class RecoveryManager:
         component_update_key = self.COMPONENT_UPDATE_KEY_FORMAT.format(component)
         del self.stored_exec_commands[component]
         del self.stored_exec_commands[component_update_key]
-        logger.debug("Removed stored command for component : " + str(component))
+        logger.debug("Removed stored command for component : %s", component)
         return True
       finally:
         self.__status_lock.release()
@@ -880,7 +881,7 @@ class RecoveryManager:
       component_update_key = self.COMPONENT_UPDATE_KEY_FORMAT.format(component)
       self.stored_exec_commands[component] = command
       self.stored_exec_commands[component_update_key] = self._now_()
-      logger.debug("Added command for component : " + str(component))
+      logger.debug("Added command for component : %s", component)
     finally:
       self.__status_lock.release()
 

http://git-wip-us.apache.org/repos/asf/ambari/blob/4e731d31/ambari-agent/src/main/python/ambari_agent/StatusCommandsExecutor.py
----------------------------------------------------------------------
diff --git a/ambari-agent/src/main/python/ambari_agent/StatusCommandsExecutor.py b/ambari-agent/src/main/python/ambari_agent/StatusCommandsExecutor.py
index f42e134..ad90b83 100644
--- a/ambari-agent/src/main/python/ambari_agent/StatusCommandsExecutor.py
+++ b/ambari-agent/src/main/python/ambari_agent/StatusCommandsExecutor.py
@@ -64,7 +64,8 @@ class SingleProcessStatusCommandsExecutor(StatusCommandsExecutor):
                   command['serviceName'] + " of cluster " + \
                   command['clusterName'] + " to the queue.")
       self.statusCommandQueue.put(command)
-      logger.debug(pprint.pformat(command))
+      if logger.isEnabledFor(logging.DEBUG):
+        logger.debug(pprint.pformat(command))
 
   def process_results(self):
     """

http://git-wip-us.apache.org/repos/asf/ambari/blob/4e731d31/ambari-agent/src/main/python/ambari_agent/alerts/ams_alert.py
----------------------------------------------------------------------
diff --git a/ambari-agent/src/main/python/ambari_agent/alerts/ams_alert.py b/ambari-agent/src/main/python/ambari_agent/alerts/ams_alert.py
index 70f100f..29b885b 100644
--- a/ambari-agent/src/main/python/ambari_agent/alerts/ams_alert.py
+++ b/ambari-agent/src/main/python/ambari_agent/alerts/ams_alert.py
@@ -64,8 +64,9 @@ class AmsAlert(MetricAlert):
     # use the URI lookup keys to get a final URI value to query
     alert_uri = self._get_uri_from_structure(self.uri_property_keys)
 
-    logger.debug("[Alert][{0}] Calculated metric URI to be {1} (ssl={2})".format(
-      self.get_name(), alert_uri.uri, str(alert_uri.is_ssl_enabled)))
+    if logger.isEnabledFor(logging.DEBUG):
+      logger.debug("[Alert][{0}] Calculated metric URI to be {1} (ssl={2})".format(
+        self.get_name(), alert_uri.uri, str(alert_uri.is_ssl_enabled)))
 
     host = BaseAlert.get_host_from_url(alert_uri.uri)
     if host is None:
@@ -94,7 +95,8 @@ class AmsAlert(MetricAlert):
 
         collect_result = self._get_result(value_list[0] if compute_result is None else compute_result)
 
-        logger.debug("[Alert][{0}] Computed result = {1}".format(self.get_name(), str(value_list)))
+        if logger.isEnabledFor(logging.DEBUG):
+          logger.debug("[Alert][{0}] Computed result = {1}".format(self.get_name(), str(value_list)))
 
     return (collect_result, value_list)
 

http://git-wip-us.apache.org/repos/asf/ambari/blob/4e731d31/ambari-agent/src/main/python/ambari_agent/alerts/metric_alert.py
----------------------------------------------------------------------
diff --git a/ambari-agent/src/main/python/ambari_agent/alerts/metric_alert.py b/ambari-agent/src/main/python/ambari_agent/alerts/metric_alert.py
index 803bdc6..66a1d05 100644
--- a/ambari-agent/src/main/python/ambari_agent/alerts/metric_alert.py
+++ b/ambari-agent/src/main/python/ambari_agent/alerts/metric_alert.py
@@ -107,7 +107,8 @@ class MetricAlert(BaseAlert):
       
         collect_result = self._get_result(value_list[0] if check_value is None else check_value)
 
-        logger.debug("[Alert][{0}] Resolved values = {1}".format(self.get_name(), str(value_list)))
+        if logger.isEnabledFor(logging.DEBUG):
+          logger.debug("[Alert][{0}] Resolved values = {1}".format(self.get_name(), str(value_list)))
     
     return (collect_result, value_list)
 

http://git-wip-us.apache.org/repos/asf/ambari/blob/4e731d31/ambari-agent/src/main/python/ambari_agent/security.py
----------------------------------------------------------------------
diff --git a/ambari-agent/src/main/python/ambari_agent/security.py b/ambari-agent/src/main/python/ambari_agent/security.py
index 45de7bb..d752ee6 100644
--- a/ambari-agent/src/main/python/ambari_agent/security.py
+++ b/ambari-agent/src/main/python/ambari_agent/security.py
@@ -48,8 +48,7 @@ class VerifiedHTTPSConnection(httplib.HTTPSConnection):
 
   def connect(self):
     self.two_way_ssl_required = self.config.isTwoWaySSLConnection(self.host)
-    logger.debug("Server two-way SSL authentication required: %s" % str(
-      self.two_way_ssl_required))
+    logger.debug("Server two-way SSL authentication required: %s", self.two_way_ssl_required)
     if self.two_way_ssl_required is True:
       logger.info(
         'Server require two-way SSL authentication. Use it instead of one-way...')
@@ -230,9 +229,10 @@ class CertificateManager():
     f.close()
     try:
       data = json.loads(response)
-      logger.debug("Sign response from Server: \n" + pprint.pformat(data))
+      if logger.isEnabledFor(logging.DEBUG):
+        logger.debug("Sign response from Server: \n" + pprint.pformat(data))
     except Exception:
-      logger.warn("Malformed response! data: " + str(data))
+      logger.warn("Malformed response! data: %s", data)
       data = {'result': 'ERROR'}
     result = data['result']
     if result == 'OK':


[03/24] ambari git commit: AMBARI-22657 Oozie service check failed during 4th digit PU (dgrinenko)

Posted by nc...@apache.org.
AMBARI-22657 Oozie service check failed during 4th digit PU (dgrinenko)


Project: http://git-wip-us.apache.org/repos/asf/ambari/repo
Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/3ab1045c
Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/3ab1045c
Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/3ab1045c

Branch: refs/heads/branch-feature-AMBARI-21674
Commit: 3ab1045c1f95a90159e69fbd934953927947c754
Parents: f1f7302
Author: Dmytro Grinenko <ha...@apache.org>
Authored: Fri Dec 15 17:50:01 2017 +0200
Committer: Dmytro Grinenko <ha...@apache.org>
Committed: Fri Dec 15 17:50:01 2017 +0200

----------------------------------------------------------------------
 .../resources/stacks/HDP/2.0.6/properties/stack_packages.json     | 3 ++-
 .../main/resources/stacks/HDP/3.0/properties/stack_packages.json  | 3 ++-
 2 files changed, 4 insertions(+), 2 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ambari/blob/3ab1045c/ambari-server/src/main/resources/stacks/HDP/2.0.6/properties/stack_packages.json
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/stacks/HDP/2.0.6/properties/stack_packages.json b/ambari-server/src/main/resources/stacks/HDP/2.0.6/properties/stack_packages.json
index 62a46b9..01a30f3 100644
--- a/ambari-server/src/main/resources/stacks/HDP/2.0.6/properties/stack_packages.json
+++ b/ambari-server/src/main/resources/stacks/HDP/2.0.6/properties/stack_packages.json
@@ -536,7 +536,8 @@
             "oozie-server"
           ],
           "PATCH": [
-            "oozie-server"
+            "oozie-server",
+            "oozie-client"
           ],
           "STANDARD": [
             "oozie-client",

http://git-wip-us.apache.org/repos/asf/ambari/blob/3ab1045c/ambari-server/src/main/resources/stacks/HDP/3.0/properties/stack_packages.json
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/stacks/HDP/3.0/properties/stack_packages.json b/ambari-server/src/main/resources/stacks/HDP/3.0/properties/stack_packages.json
index 4f05377..28efbfa 100644
--- a/ambari-server/src/main/resources/stacks/HDP/3.0/properties/stack_packages.json
+++ b/ambari-server/src/main/resources/stacks/HDP/3.0/properties/stack_packages.json
@@ -532,7 +532,8 @@
             "oozie-server"
           ],
           "PATCH": [
-            "oozie-server"
+            "oozie-server",
+            "oozie-client"
           ],
           "STANDARD": [
             "oozie-client",


[13/24] ambari git commit: AMBARI-22665 - Livy2 Does Not Start On HDP 2.6.0 to 2.6.3 (jonathanhurley)

Posted by nc...@apache.org.
AMBARI-22665 - Livy2 Does Not Start On HDP 2.6.0 to 2.6.3 (jonathanhurley)


Project: http://git-wip-us.apache.org/repos/asf/ambari/repo
Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/5c95c4a7
Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/5c95c4a7
Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/5c95c4a7

Branch: refs/heads/branch-feature-AMBARI-21674
Commit: 5c95c4a7a9c75f0b0932b3accf4fb536a3175c0e
Parents: 2817ad4
Author: Jonathan Hurley <jh...@hortonworks.com>
Authored: Mon Dec 18 12:23:06 2017 -0500
Committer: Jonathan Hurley <jh...@hortonworks.com>
Committed: Mon Dec 18 15:53:26 2017 -0500

----------------------------------------------------------------------
 .../resource_management/libraries/functions/conf_select.py    | 7 +++++++
 .../main/resources/custom_actions/scripts/install_packages.py | 4 ++--
 2 files changed, 9 insertions(+), 2 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ambari/blob/5c95c4a7/ambari-common/src/main/python/resource_management/libraries/functions/conf_select.py
----------------------------------------------------------------------
diff --git a/ambari-common/src/main/python/resource_management/libraries/functions/conf_select.py b/ambari-common/src/main/python/resource_management/libraries/functions/conf_select.py
index d38e273..9de2f8f 100644
--- a/ambari-common/src/main/python/resource_management/libraries/functions/conf_select.py
+++ b/ambari-common/src/main/python/resource_management/libraries/functions/conf_select.py
@@ -211,6 +211,13 @@ def convert_conf_directories_to_symlinks(package, version, dirs):
   # determine which directories would be created, if any are needed
   dry_run_directory = create(stack_name, package, version, dry_run = True)
 
+  # if the dry run reported an error, then we must assume that the package does not exist in
+  # the conf-select tool
+  if len(dry_run_directory) == 0:
+    Logger.info("The conf-select tool reported an error for the package {0}. The configuration linking will be skipped.".format(package))
+    return
+
+
   need_dirs = []
   for d in dry_run_directory:
     if not os.path.exists(d):

http://git-wip-us.apache.org/repos/asf/ambari/blob/5c95c4a7/ambari-server/src/main/resources/custom_actions/scripts/install_packages.py
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/custom_actions/scripts/install_packages.py b/ambari-server/src/main/resources/custom_actions/scripts/install_packages.py
index c3fbc48..4cdb0e5 100644
--- a/ambari-server/src/main/resources/custom_actions/scripts/install_packages.py
+++ b/ambari-server/src/main/resources/custom_actions/scripts/install_packages.py
@@ -184,10 +184,10 @@ class InstallPackages(Script):
     from resource_management.libraries.functions import stack_select
     package_dirs = conf_select.get_package_dirs()
     if package_name in package_dirs:
-      Logger.info("Attempting to fix the default conf links for {0}".format(package_name))
+      Logger.info("Determining if the default conf links for {0} need to be fixed".format(package_name))
 
       directories = package_dirs[package_name]
-      Logger.info("The following directories will be fixed for {0}: {1}".format(package_name,
+      Logger.info("The following directories will be checked for {0}: {1}".format(package_name,
         str(directories)))
 
       stack_version = stack_select.get_stack_version_before_install(component_name)


[04/24] ambari git commit: AMBARI-22659. unable to proceed with cluster install after component install fails. (mpapirkovskyy)

Posted by nc...@apache.org.
AMBARI-22659. unable to proceed with cluster install after component install fails. (mpapirkovskyy)


Project: http://git-wip-us.apache.org/repos/asf/ambari/repo
Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/856d9a53
Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/856d9a53
Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/856d9a53

Branch: refs/heads/branch-feature-AMBARI-21674
Commit: 856d9a53d39b1658a846311d672ba54699b73f90
Parents: 3ab1045
Author: Myroslav Papirkovskyi <mp...@hortonworks.com>
Authored: Fri Dec 15 18:13:49 2017 +0200
Committer: Myroslav Papirkovskyi <mp...@hortonworks.com>
Committed: Fri Dec 15 18:46:35 2017 +0200

----------------------------------------------------------------------
 .../apache/ambari/server/orm/dao/HostVersionDAO.java | 15 +++++++++++++++
 .../server/orm/entities/HostVersionEntity.java       |  5 +++++
 .../ambari/server/state/cluster/ClusterImpl.java     | 10 ++++++++++
 .../ambari/server/orm/dao/HostVersionDAOTest.java    | 12 ++++++++++++
 4 files changed, 42 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ambari/blob/856d9a53/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/HostVersionDAO.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/HostVersionDAO.java b/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/HostVersionDAO.java
index 158370f..feb4172 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/HostVersionDAO.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/HostVersionDAO.java
@@ -130,6 +130,21 @@ public class HostVersionDAO extends CrudDAO<HostVersionEntity, Long> {
   }
 
   /**
+   * Retrieve all of the cluster versions for the given cluster name.
+   *
+   * @param clusterName Cluster name
+   * @return Return all of the host versions that match the criteria.
+   */
+  @RequiresSession
+  public List<HostVersionEntity> findByCluster(String  clusterName) {
+    final TypedQuery<HostVersionEntity> query = entityManagerProvider.get()
+        .createNamedQuery("findByCluster", HostVersionEntity.class);
+    query.setParameter("clusterName", clusterName);
+
+    return daoUtils.selectList(query);
+  }
+
+  /**
    * Retrieve all of the host versions for the given cluster name, and state. <br/>
    * @param clusterName Cluster name
    * @param state repository version state

http://git-wip-us.apache.org/repos/asf/ambari/blob/856d9a53/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/HostVersionEntity.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/HostVersionEntity.java b/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/HostVersionEntity.java
index 4a030af..2c61a3c 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/HostVersionEntity.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/HostVersionEntity.java
@@ -66,6 +66,11 @@ import org.apache.ambari.server.state.RepositoryVersionState;
         query = "SELECT hostVersion FROM HostVersionEntity hostVersion JOIN hostVersion.hostEntity host JOIN host.clusterEntities clusters "
             + "WHERE clusters.clusterName=:clusterName AND hostVersion.state=:state"),
 
+    @NamedQuery(
+        name = "findByCluster",
+        query = "SELECT hostVersion FROM HostVersionEntity hostVersion JOIN hostVersion.hostEntity host JOIN host.clusterEntities clusters "
+            + "WHERE clusters.clusterName=:clusterName"),
+
     @NamedQuery(name = "hostVersionByClusterHostnameAndState", query =
         "SELECT hostVersion FROM HostVersionEntity hostVersion JOIN hostVersion.hostEntity host JOIN host.clusterEntities clusters " +
             "WHERE clusters.clusterName=:clusterName AND hostVersion.hostEntity.hostName=:hostName AND hostVersion.state=:state"),

http://git-wip-us.apache.org/repos/asf/ambari/blob/856d9a53/ambari-server/src/main/java/org/apache/ambari/server/state/cluster/ClusterImpl.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/state/cluster/ClusterImpl.java b/ambari-server/src/main/java/org/apache/ambari/server/state/cluster/ClusterImpl.java
index c23b971..2266c62 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/state/cluster/ClusterImpl.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/state/cluster/ClusterImpl.java
@@ -1334,6 +1334,7 @@ public class ClusterImpl implements Cluster {
     try {
       refresh();
       deleteAllServices();
+      resetHostVersions();
 
       refresh(); // update one-to-many clusterServiceEntities
       removeEntities();
@@ -1353,6 +1354,15 @@ public class ClusterImpl implements Cluster {
     clusterDAO.removeByPK(clusterId);
   }
 
+  private void resetHostVersions() {
+    for (HostVersionEntity hostVersionEntity : hostVersionDAO.findByCluster(getClusterName())) {
+      if (!hostVersionEntity.getState().equals(RepositoryVersionState.NOT_REQUIRED)) {
+        hostVersionEntity.setState(RepositoryVersionState.NOT_REQUIRED);
+        hostVersionDAO.merge(hostVersionEntity);
+      }
+    }
+  }
+
   @Override
   public ServiceConfigVersionResponse addDesiredConfig(String user, Set<Config> configs) {
     return addDesiredConfig(user, configs, null);

http://git-wip-us.apache.org/repos/asf/ambari/blob/856d9a53/ambari-server/src/test/java/org/apache/ambari/server/orm/dao/HostVersionDAOTest.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/orm/dao/HostVersionDAOTest.java b/ambari-server/src/test/java/org/apache/ambari/server/orm/dao/HostVersionDAOTest.java
index bb077d6..88f42d3 100644
--- a/ambari-server/src/test/java/org/apache/ambari/server/orm/dao/HostVersionDAOTest.java
+++ b/ambari-server/src/test/java/org/apache/ambari/server/orm/dao/HostVersionDAOTest.java
@@ -247,6 +247,18 @@ public class HostVersionDAOTest {
   }
 
   /**
+   * Test the {@link HostVersionDAO#findByCluster(String)} method.
+   */
+  @Test
+  public void testFindByCluster() {
+    Assert.assertEquals(3, hostVersionDAO.findByCluster("test_cluster1").size());
+
+    addMoreVersions();
+
+    Assert.assertEquals(9, hostVersionDAO.findByCluster("test_cluster1").size());
+  }
+
+  /**
    * Test the {@link HostVersionDAO#findByClusterHostAndState(String, String, org.apache.ambari.server.state.RepositoryVersionState)} method.
    */
   @Test


[08/24] ambari git commit: AMBARI-22647. Rafactor: Package Log Search and Log Feeder into jars + cleanup start scripts (oleewere)

Posted by nc...@apache.org.
AMBARI-22647. Rafactor: Package Log Search and Log Feeder into jars + cleanup start scripts (oleewere)


Project: http://git-wip-us.apache.org/repos/asf/ambari/repo
Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/562795c4
Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/562795c4
Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/562795c4

Branch: refs/heads/branch-feature-AMBARI-21674
Commit: 562795c4d35bf3b45d196856e9d66e5dfdd0a17b
Parents: f9ad13d
Author: Oliver Szabo <ol...@gmail.com>
Authored: Fri Dec 15 22:17:46 2017 +0100
Committer: Oliver Szabo <ol...@gmail.com>
Committed: Mon Dec 18 16:28:38 2017 +0100

----------------------------------------------------------------------
 .../ambari-logsearch-assembly/pom.xml           | 117 +++-----
 .../src/main/package/deb/logfeeder/postinst     |  22 ++
 .../src/main/package/deb/logfeeder/postrm       |   6 +
 .../src/main/package/deb/logfeeder/posttrm      |  15 -
 .../src/main/package/deb/logfeeder/preinst      |  13 +
 .../src/main/package/deb/portal/postinst        |  19 ++
 .../src/main/package/deb/portal/postrm          |   6 +
 .../src/main/package/deb/portal/preinst         |  13 +
 .../main/package/rpm/logfeeder/postinstall.sh   |  37 +++
 .../main/package/rpm/logfeeder/postremove.sh    |  21 ++
 .../main/package/rpm/logfeeder/preinstall.sh    |  28 ++
 .../src/main/package/rpm/portal/postinstall.sh  |  34 +++
 .../src/main/package/rpm/portal/postremove.sh   |  21 ++
 .../src/main/package/rpm/portal/preinstall.sh   |  28 ++
 .../ambari-logsearch-logfeeder/README.md        |   4 +-
 .../ambari-logsearch-logfeeder/build.properties |  18 --
 .../ambari-logsearch-logfeeder/build.xml        |  28 +-
 .../ambari-logsearch-logfeeder/pom.xml          |  31 --
 .../ambari-logsearch-logfeeder/run.sh           |   4 +-
 .../org/apache/ambari/logfeeder/LogFeeder.java  |  35 +--
 .../ambari/logfeeder/LogFeederCommandLine.java  |  63 ++--
 .../ambari/logfeeder/common/ConfigHandler.java  |   7 +-
 .../src/main/package/deb/control/control        |  22 --
 .../src/main/package/deb/control/postinst       |  15 -
 .../src/main/package/deb/control/postrm         |  15 -
 .../src/main/package/deb/control/preinst        |  15 -
 .../src/main/package/deb/control/prerm          |  15 -
 .../src/main/scripts/logfeeder-env.sh           |  40 +++
 .../src/main/scripts/logfeeder.sh               | 292 +++++++++++++++++++
 .../src/main/scripts/run.sh                     | 103 -------
 .../ambari-logsearch-server/README.md           |   2 +-
 .../ambari-logsearch-server/build.xml           |  36 ++-
 .../ambari-logsearch-server/pom.xml             |  11 -
 ambari-logsearch/ambari-logsearch-server/run.sh |   2 +-
 .../org/apache/ambari/logsearch/LogSearch.java  |   2 +-
 .../src/main/scripts/logsearch-env.sh           |  40 +++
 .../src/main/scripts/logsearch.sh               | 274 +++++++++++++++++
 .../src/main/scripts/run.sh                     |  99 -------
 .../src/main/scripts/stop.sh                    |  44 ---
 ambari-logsearch/docker/Dockerfile              |   6 +-
 ambari-logsearch/docker/all.yml                 |   4 +-
 ambari-logsearch/docker/bin/start.sh            |  30 +-
 ambari-logsearch/docker/docker-compose.yml      |   2 -
 ambari-logsearch/docker/logsearch-logfeeder.yml |   1 -
 ambari-logsearch/docker/logsearch-server.yml    |   1 -
 .../test-config/logfeeder/logfeeder-env.sh      |   5 +-
 .../test-config/logfeeder/logfeeder.properties  |   2 +-
 .../test-config/logsearch/logsearch-env.sh      |   5 +-
 .../logsearch/logsearch-https.properties        |   4 +-
 .../test-config/logsearch/logsearch.properties  |   4 +-
 .../0.5.0/configuration/logfeeder-env.xml       |   2 +-
 .../configuration/logfeeder-properties.xml      |   2 +-
 .../0.5.0/configuration/logsearch-env.xml       |   6 +-
 .../0.5.0/package/scripts/logfeeder.py          |   7 +-
 .../0.5.0/package/scripts/logsearch.py          |   8 +-
 .../0.5.0/package/scripts/logsearch_common.py   |  54 ----
 .../LOGSEARCH/0.5.0/package/scripts/params.py   |   8 +-
 .../0.5.0/package/scripts/setup_logfeeder.py    |   2 +-
 .../0.5.0/package/scripts/setup_logsearch.py    |   2 +-
 .../0.5.0/properties/logfeeder-env.sh.j2        |   5 +-
 .../0.5.0/properties/logsearch-env.sh.j2        |   5 +-
 .../stack-hooks/after-INSTALL/scripts/params.py |   2 +-
 .../hooks/after-INSTALL/test_after_install.py   |   8 +-
 .../stacks/2.4/LOGSEARCH/test_logfeeder.py      |  34 +--
 .../stacks/2.4/LOGSEARCH/test_logsearch.py      |  31 +-
 .../test/python/stacks/2.4/configs/default.json |   2 +-
 66 files changed, 1102 insertions(+), 737 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ambari/blob/562795c4/ambari-logsearch/ambari-logsearch-assembly/pom.xml
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-assembly/pom.xml b/ambari-logsearch/ambari-logsearch-assembly/pom.xml
index cbc62ce..19c3d90 100644
--- a/ambari-logsearch/ambari-logsearch-assembly/pom.xml
+++ b/ambari-logsearch/ambari-logsearch-assembly/pom.xml
@@ -82,6 +82,18 @@
                 <configuration>
                   <group>Development</group>
                   <name>${logsearch.portal.package.name}</name>
+                  <postinstallScriptlet>
+                    <scriptFile>${project.basedir}/src/main/package/rpm/portal/postinstall.sh</scriptFile>
+                    <fileEncoding>utf-8</fileEncoding>
+                  </postinstallScriptlet>
+                  <postremoveScriptlet>
+                    <scriptFile>${project.basedir}/src/main/package/rpm/portal/postremove.sh</scriptFile>
+                    <fileEncoding>utf-8</fileEncoding>
+                  </postremoveScriptlet>
+                  <preinstallScriptlet>
+                    <scriptFile>${project.basedir}/src/main/package/rpm/portal/preinstall.sh</scriptFile>
+                    <fileEncoding>utf-8</fileEncoding>
+                  </preinstallScriptlet>
                   <mappings>
                     <mapping>
                       <directory>${logsearch.portal.mapping.path}</directory>
@@ -89,37 +101,11 @@
                         <source>
                           <location>${logsearch.server.dir}/target/package</location>
                           <excludes>
-                            <exclude>classes/log4j.xml</exclude>
-                            <exclude>classes/logsearch.properties</exclude>
-                            <exclude>classes/user_pass.json</exclude>
-                            <exclude>classes/HadoopServiceConfig.json</exclude>
-                            <exclude>solr_configsets/**</exclude>
                             <exclude>libs/checkstyle*.jar</exclude>
                           </excludes>
                         </source>
                       </sources>
                     </mapping>
-                    <mapping>
-                      <directory>${logsearch.portal.conf.mapping.path}</directory>
-                      <sources>
-                        <source>
-                          <location>${logsearch.server.dir}/target/package/classes</location>
-                          <includes>
-                            <include>log4j.xml</include>
-                            <include>logsearch.properties</include>
-                            <include>user_pass.json</include>
-                          </includes>
-                        </source>
-                      </sources>
-                    </mapping>
-                    <mapping>
-                      <directory>${logsearch.portal.conf.mapping.path}/solr_configsets</directory>
-                      <sources>
-                        <source>
-                          <location>${logsearch.server.dir}/target/package/solr_configsets</location>
-                        </source>
-                      </sources>
-                    </mapping>
                   </mappings>
                 </configuration>
               </execution>
@@ -132,6 +118,18 @@
                 <configuration>
                   <group>Development</group>
                   <name>${logsearch.logfeeder.package.name}</name>
+                  <postinstallScriptlet>
+                    <scriptFile>${project.basedir}/src/main/package/rpm/logfeeder/postinstall.sh</scriptFile>
+                    <fileEncoding>utf-8</fileEncoding>
+                  </postinstallScriptlet>
+                  <postremoveScriptlet>
+                    <scriptFile>${project.basedir}/src/main/package/rpm/logfeeder/postremove.sh</scriptFile>
+                    <fileEncoding>utf-8</fileEncoding>
+                  </postremoveScriptlet>
+                  <preinstallScriptlet>
+                    <scriptFile>${project.basedir}/src/main/package/rpm/logfeeder/preinstall.sh</scriptFile>
+                    <fileEncoding>utf-8</fileEncoding>
+                  </preinstallScriptlet>
                   <mappings>
                     <mapping>
                       <directory>${logsearch.logfeeder.mapping.path}</directory>
@@ -139,27 +137,11 @@
                         <source>
                           <location>${logsearch.logfeeder.dir}/target/package</location>
                           <excludes>
-                            <exclude>classes/log4j.xml</exclude>
-                            <exclude>classes/logfeeder.properties</exclude>
-                            <exclude>classes/grok-patterns</exclude>
                             <exclude>libs/checkstyle*.jar</exclude>
                           </excludes>
                         </source>
                       </sources>
                     </mapping>
-                    <mapping>
-                      <directory>${logsearch.logfeeder.conf.mapping.path}</directory>
-                      <sources>
-                        <source>
-                          <location>${logsearch.logfeeder.dir}/target/package/classes</location>
-                          <includes>
-                            <include>log4j.xml</include>
-                            <include>logfeeder.properties</include>
-                            <include>grok-patterns</include>
-                          </includes>
-                        </source>
-                      </sources>
-                    </mapping>
                   </mappings>
                 </configuration>
               </execution>
@@ -197,7 +179,11 @@
                       <directory>${project.basedir}/src/main/package/deb</directory>
                       <excludes>
                         <exclude>portal/postinst</exclude>
+                        <exclude>portal/postrm</exclude>
+                        <exclude>portal/preinstall</exclude>
                         <exclude>logfeeder/postinst</exclude>
+                        <exclude>logfeeder/postrm</exclude>
+                        <exclude>logfeeder/preinstall</exclude>
                       </excludes>
                       <filtering>false</filtering>
                     </resource>
@@ -205,7 +191,11 @@
                       <directory>${project.basedir}/src/main/package/deb</directory>
                       <includes>
                         <include>portal/postinst</include>
+                        <include>portal/postrm</include>
+                        <include>portal/preinstall</include>
                         <include>logfeeder/postinst</include>
+                        <include>logfeeder/postrm</include>
+                        <include>logfeeder/preinstall</include>
                       </includes>
                       <filtering>true</filtering>
                     </resource>
@@ -242,34 +232,9 @@
                         <group>root</group>
                       </mapper>
                       <excludes>
-                        classes/log4j.xml,classes/logsearch.properties,classes/user_pass.json,classes/HadoopServiceConfig.json,solr_configsets/**,libs/checkstyle*.jar
+                        libs/checkstyle*.jar
                       </excludes>
                     </data>
-                    <data>
-                      <src>${logsearch.server.dir}/target/package/classes</src>
-                      <type>directory</type>
-                      <mapper>
-                        <prefix>${logsearch.portal.conf.mapping.path}</prefix>
-                        <type>perm</type>
-                        <user>root</user>
-                        <group>root</group>
-                        <filemode>644</filemode>
-                      </mapper>
-                      <includes>
-                        log4j.xml,logsearch.properties,user_pass.json
-                      </includes>
-                    </data>
-                    <data>
-                      <src>${logsearch.server.dir}/target/package/solr_configsets</src>
-                      <type>directory</type>
-                      <mapper>
-                        <prefix>${logsearch.portal.conf.mapping.path}/solr_configsets</prefix>
-                        <type>perm</type>
-                        <user>root</user>
-                        <group>root</group>
-                      </mapper>
-                      <excludes>libs/checkstyle*.jar</excludes>
-                    </data>
                   </dataSet>
                 </configuration>
               </execution>
@@ -297,23 +262,9 @@
                         <group>root</group>
                       </mapper>
                       <excludes>
-                        classes/log4j.xml,classes/logfeeder.properties,classes/grok-patterns,libs/checkstyle*.jar
+                        libs/checkstyle*.jar
                       </excludes>
                     </data>
-                    <data>
-                      <src>${logsearch.logfeeder.dir}/target/package/classes</src>
-                      <type>directory</type>
-                      <mapper>
-                        <prefix>${logsearch.logfeeder.conf.mapping.path}</prefix>
-                        <type>perm</type>
-                        <user>root</user>
-                        <group>root</group>
-                        <filemode>644</filemode>
-                      </mapper>
-                      <includes>
-                        log4j.xml,logfeeder.properties,grok-patterns
-                      </includes>
-                    </data>
                   </dataSet>
                 </configuration>
               </execution>

http://git-wip-us.apache.org/repos/asf/ambari/blob/562795c4/ambari-logsearch/ambari-logsearch-assembly/src/main/package/deb/logfeeder/postinst
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-assembly/src/main/package/deb/logfeeder/postinst b/ambari-logsearch/ambari-logsearch-assembly/src/main/package/deb/logfeeder/postinst
index 21a01fa..a4eec77 100644
--- a/ambari-logsearch/ambari-logsearch-assembly/src/main/package/deb/logfeeder/postinst
+++ b/ambari-logsearch/ambari-logsearch-assembly/src/main/package/deb/logfeeder/postinst
@@ -13,3 +13,25 @@
 # 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
+
+LOGFEEDER_SCRIPT_LINK_NAME="/usr/bin/logfeeder"
+LOGFEEDER_SCRIPT_SOURCE="/usr/lib/ambari-logsearch-logfeeder/bin/logfeeder.sh"
+
+LOGFEEDER_CONF_LINK="/etc/ambari-logsearch-logfeeder/conf"
+LOGFEEDER_CONF_SOURCE="/usr/lib/ambari-logsearch-logfeeder/conf"
+
+ln -s $LOGFEEDER_SCRIPT_SOURCE $LOGFEEDER_SCRIPT_LINK_NAME
+ln -s $LOGFEEDER_CONF_SOURCE $LOGFEEDER_CONF_LINK
+
+# handle old checkpoint & keys folder
+
+LOGFEEDER_CONF_BACKUP="/usr/lib/ambari-logsearch-logfeeder/conf-old"
+
+if [ -d "$LOGFEEDER_CONF_BACKUP" ]; then
+  if [ -d "$LOGFEEDER_CONF_BACKUP/keys" ]; then
+    cp -r $LOGFEEDER_CONF_BACKUP/keys $LOGFEEDER_CONF_SOURCE
+  fi
+  if [ -d "$LOGFEEDER_CONF_BACKUP/checkpoints" ]; then
+    cp -r $LOGFEEDER_CONF_BACKUP/checkpoints $LOGFEEDER_CONF_SOURCE
+  fi
+fi
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/ambari/blob/562795c4/ambari-logsearch/ambari-logsearch-assembly/src/main/package/deb/logfeeder/postrm
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-assembly/src/main/package/deb/logfeeder/postrm b/ambari-logsearch/ambari-logsearch-assembly/src/main/package/deb/logfeeder/postrm
index 21a01fa..5f1c623 100644
--- a/ambari-logsearch/ambari-logsearch-assembly/src/main/package/deb/logfeeder/postrm
+++ b/ambari-logsearch/ambari-logsearch-assembly/src/main/package/deb/logfeeder/postrm
@@ -13,3 +13,9 @@
 # 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
+
+LOGFEEDER_SCRIPT_LINK_NAME="/usr/bin/logfeeder"
+LOGFEEDER_CONF_DIR_LINK="/etc/ambari-logsearch-logfeeder/conf"
+
+rm -f $LOGFEEDER_SCRIPT_LINK_NAME
+rm -f $LOGFEEDER_CONF_DIR_LINK
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/ambari/blob/562795c4/ambari-logsearch/ambari-logsearch-assembly/src/main/package/deb/logfeeder/posttrm
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-assembly/src/main/package/deb/logfeeder/posttrm b/ambari-logsearch/ambari-logsearch-assembly/src/main/package/deb/logfeeder/posttrm
deleted file mode 100644
index 21a01fa..0000000
--- a/ambari-logsearch/ambari-logsearch-assembly/src/main/package/deb/logfeeder/posttrm
+++ /dev/null
@@ -1,15 +0,0 @@
-#!/bin/bash
-# Licensed to the Apache Software Foundation (ASF) under one or more
-# contributor license agreements.  See the NOTICE file distributed with
-# this work for additional information regarding copyright ownership.
-# The ASF licenses this file to You 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

http://git-wip-us.apache.org/repos/asf/ambari/blob/562795c4/ambari-logsearch/ambari-logsearch-assembly/src/main/package/deb/logfeeder/preinst
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-assembly/src/main/package/deb/logfeeder/preinst b/ambari-logsearch/ambari-logsearch-assembly/src/main/package/deb/logfeeder/preinst
index 21a01fa..01d70e0 100644
--- a/ambari-logsearch/ambari-logsearch-assembly/src/main/package/deb/logfeeder/preinst
+++ b/ambari-logsearch/ambari-logsearch-assembly/src/main/package/deb/logfeeder/preinst
@@ -13,3 +13,16 @@
 # 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
+
+LOGFEEDER_CONF="/etc/ambari-logsearch-logfeeder/conf"
+LOGFEEDER_CONF_BACKUP="/usr/lib/ambari-logsearch-logfeeder/conf-old"
+
+if [ -d $LOGFEEDER_CONF_BACKUP ]; then
+  rm -rf $LOGFEEDER_CONF_BACKUP
+fi
+
+if [ -d $LOGFEEDER_CONF ]; then
+  mkdir -p $LOGFEEDER_CONF_BACKUP
+  cp -r $LOGFEEDER_CONF/* $LOGFEEDER_CONF_BACKUP
+  rm -rf $LOGFEEDER_CONF
+fi
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/ambari/blob/562795c4/ambari-logsearch/ambari-logsearch-assembly/src/main/package/deb/portal/postinst
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-assembly/src/main/package/deb/portal/postinst b/ambari-logsearch/ambari-logsearch-assembly/src/main/package/deb/portal/postinst
index 21a01fa..9107482 100644
--- a/ambari-logsearch/ambari-logsearch-assembly/src/main/package/deb/portal/postinst
+++ b/ambari-logsearch/ambari-logsearch-assembly/src/main/package/deb/portal/postinst
@@ -13,3 +13,22 @@
 # 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
+
+LOGSEARCH_SCRIPT_LINK_NAME="/usr/bin/logsearch"
+LOGSEARCH_SCRIPT_SOURCE="/usr/lib/ambari-logsearch-portal/bin/logsearch.sh"
+
+LOGSEARCH_CONF_LINK="/etc/ambari-logsearch-portal/conf"
+LOGSEARCH_CONF_SOURCE="/usr/lib/ambari-logsearch-portal/conf"
+
+ln -s $LOGSEARCH_SCRIPT_SOURCE $LOGSEARCH_SCRIPT_LINK_NAME
+ln -s $LOGSEARCH_CONF_SOURCE $LOGSEARCH_CONF_LINK
+
+# handle old keys folder
+
+LOGSEARCH_CONF_BACKUP="/usr/lib/ambari-logsearch-portal/conf-old"
+
+if [ -d "$LOGSEARCH_CONF_BACKUP" ]; then
+  if [ -d "$LOGSEARCH_CONF_BACKUP/keys" ]; then
+    cp -r $LOGSEARCH_CONF_BACKUP/keys $LOGSEARCH_CONF_SOURCE
+  fi
+fi
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/ambari/blob/562795c4/ambari-logsearch/ambari-logsearch-assembly/src/main/package/deb/portal/postrm
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-assembly/src/main/package/deb/portal/postrm b/ambari-logsearch/ambari-logsearch-assembly/src/main/package/deb/portal/postrm
index 21a01fa..8de05c1 100644
--- a/ambari-logsearch/ambari-logsearch-assembly/src/main/package/deb/portal/postrm
+++ b/ambari-logsearch/ambari-logsearch-assembly/src/main/package/deb/portal/postrm
@@ -13,3 +13,9 @@
 # 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
+
+LOGSEARCH_SCRIPT_LINK_NAME="/usr/bin/logsearch"
+LOGSEARCH_CONF_DIR_LINK="/etc/ambari-logsearch-portal/conf"
+
+rm -f $LOGSEARCH_SCRIPT_LINK_NAME
+rm -f $LOGSEARCH_CONF_DIR_LINK
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/ambari/blob/562795c4/ambari-logsearch/ambari-logsearch-assembly/src/main/package/deb/portal/preinst
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-assembly/src/main/package/deb/portal/preinst b/ambari-logsearch/ambari-logsearch-assembly/src/main/package/deb/portal/preinst
index 21a01fa..dfb8752 100644
--- a/ambari-logsearch/ambari-logsearch-assembly/src/main/package/deb/portal/preinst
+++ b/ambari-logsearch/ambari-logsearch-assembly/src/main/package/deb/portal/preinst
@@ -13,3 +13,16 @@
 # 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
+
+LOGSEARCH_CONF="/etc/ambari-logsearch-portal/conf"
+LOGSEARCH_CONF_BACKUP="/usr/lib/ambari-logsearch-portal/conf-old"
+
+if [ -d $LOGSEARCH_CONF_BACKUP ]; then
+  rm -rf $LOGSEARCH_CONF_BACKUP
+fi
+
+if [ -d $LOGSEARCH_CONF ]; then
+  mkdir -p $LOGSEARCH_CONF_BACKUP
+  cp -r $LOGSEARCH_CONF/* $LOGSEARCH_CONF_BACKUP
+  rm -rf $LOGSEARCH_CONF
+fi
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/ambari/blob/562795c4/ambari-logsearch/ambari-logsearch-assembly/src/main/package/rpm/logfeeder/postinstall.sh
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-assembly/src/main/package/rpm/logfeeder/postinstall.sh b/ambari-logsearch/ambari-logsearch-assembly/src/main/package/rpm/logfeeder/postinstall.sh
new file mode 100755
index 0000000..a4eec77
--- /dev/null
+++ b/ambari-logsearch/ambari-logsearch-assembly/src/main/package/rpm/logfeeder/postinstall.sh
@@ -0,0 +1,37 @@
+#!/bin/bash
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements.  See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You 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
+
+LOGFEEDER_SCRIPT_LINK_NAME="/usr/bin/logfeeder"
+LOGFEEDER_SCRIPT_SOURCE="/usr/lib/ambari-logsearch-logfeeder/bin/logfeeder.sh"
+
+LOGFEEDER_CONF_LINK="/etc/ambari-logsearch-logfeeder/conf"
+LOGFEEDER_CONF_SOURCE="/usr/lib/ambari-logsearch-logfeeder/conf"
+
+ln -s $LOGFEEDER_SCRIPT_SOURCE $LOGFEEDER_SCRIPT_LINK_NAME
+ln -s $LOGFEEDER_CONF_SOURCE $LOGFEEDER_CONF_LINK
+
+# handle old checkpoint & keys folder
+
+LOGFEEDER_CONF_BACKUP="/usr/lib/ambari-logsearch-logfeeder/conf-old"
+
+if [ -d "$LOGFEEDER_CONF_BACKUP" ]; then
+  if [ -d "$LOGFEEDER_CONF_BACKUP/keys" ]; then
+    cp -r $LOGFEEDER_CONF_BACKUP/keys $LOGFEEDER_CONF_SOURCE
+  fi
+  if [ -d "$LOGFEEDER_CONF_BACKUP/checkpoints" ]; then
+    cp -r $LOGFEEDER_CONF_BACKUP/checkpoints $LOGFEEDER_CONF_SOURCE
+  fi
+fi
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/ambari/blob/562795c4/ambari-logsearch/ambari-logsearch-assembly/src/main/package/rpm/logfeeder/postremove.sh
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-assembly/src/main/package/rpm/logfeeder/postremove.sh b/ambari-logsearch/ambari-logsearch-assembly/src/main/package/rpm/logfeeder/postremove.sh
new file mode 100755
index 0000000..5f1c623
--- /dev/null
+++ b/ambari-logsearch/ambari-logsearch-assembly/src/main/package/rpm/logfeeder/postremove.sh
@@ -0,0 +1,21 @@
+#!/bin/bash
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements.  See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You 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
+
+LOGFEEDER_SCRIPT_LINK_NAME="/usr/bin/logfeeder"
+LOGFEEDER_CONF_DIR_LINK="/etc/ambari-logsearch-logfeeder/conf"
+
+rm -f $LOGFEEDER_SCRIPT_LINK_NAME
+rm -f $LOGFEEDER_CONF_DIR_LINK
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/ambari/blob/562795c4/ambari-logsearch/ambari-logsearch-assembly/src/main/package/rpm/logfeeder/preinstall.sh
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-assembly/src/main/package/rpm/logfeeder/preinstall.sh b/ambari-logsearch/ambari-logsearch-assembly/src/main/package/rpm/logfeeder/preinstall.sh
new file mode 100644
index 0000000..01d70e0
--- /dev/null
+++ b/ambari-logsearch/ambari-logsearch-assembly/src/main/package/rpm/logfeeder/preinstall.sh
@@ -0,0 +1,28 @@
+#!/bin/bash
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements.  See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You 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
+
+LOGFEEDER_CONF="/etc/ambari-logsearch-logfeeder/conf"
+LOGFEEDER_CONF_BACKUP="/usr/lib/ambari-logsearch-logfeeder/conf-old"
+
+if [ -d $LOGFEEDER_CONF_BACKUP ]; then
+  rm -rf $LOGFEEDER_CONF_BACKUP
+fi
+
+if [ -d $LOGFEEDER_CONF ]; then
+  mkdir -p $LOGFEEDER_CONF_BACKUP
+  cp -r $LOGFEEDER_CONF/* $LOGFEEDER_CONF_BACKUP
+  rm -rf $LOGFEEDER_CONF
+fi
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/ambari/blob/562795c4/ambari-logsearch/ambari-logsearch-assembly/src/main/package/rpm/portal/postinstall.sh
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-assembly/src/main/package/rpm/portal/postinstall.sh b/ambari-logsearch/ambari-logsearch-assembly/src/main/package/rpm/portal/postinstall.sh
new file mode 100644
index 0000000..9107482
--- /dev/null
+++ b/ambari-logsearch/ambari-logsearch-assembly/src/main/package/rpm/portal/postinstall.sh
@@ -0,0 +1,34 @@
+#!/bin/bash
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements.  See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You 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
+
+LOGSEARCH_SCRIPT_LINK_NAME="/usr/bin/logsearch"
+LOGSEARCH_SCRIPT_SOURCE="/usr/lib/ambari-logsearch-portal/bin/logsearch.sh"
+
+LOGSEARCH_CONF_LINK="/etc/ambari-logsearch-portal/conf"
+LOGSEARCH_CONF_SOURCE="/usr/lib/ambari-logsearch-portal/conf"
+
+ln -s $LOGSEARCH_SCRIPT_SOURCE $LOGSEARCH_SCRIPT_LINK_NAME
+ln -s $LOGSEARCH_CONF_SOURCE $LOGSEARCH_CONF_LINK
+
+# handle old keys folder
+
+LOGSEARCH_CONF_BACKUP="/usr/lib/ambari-logsearch-portal/conf-old"
+
+if [ -d "$LOGSEARCH_CONF_BACKUP" ]; then
+  if [ -d "$LOGSEARCH_CONF_BACKUP/keys" ]; then
+    cp -r $LOGSEARCH_CONF_BACKUP/keys $LOGSEARCH_CONF_SOURCE
+  fi
+fi
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/ambari/blob/562795c4/ambari-logsearch/ambari-logsearch-assembly/src/main/package/rpm/portal/postremove.sh
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-assembly/src/main/package/rpm/portal/postremove.sh b/ambari-logsearch/ambari-logsearch-assembly/src/main/package/rpm/portal/postremove.sh
new file mode 100644
index 0000000..8de05c1
--- /dev/null
+++ b/ambari-logsearch/ambari-logsearch-assembly/src/main/package/rpm/portal/postremove.sh
@@ -0,0 +1,21 @@
+#!/bin/bash
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements.  See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You 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
+
+LOGSEARCH_SCRIPT_LINK_NAME="/usr/bin/logsearch"
+LOGSEARCH_CONF_DIR_LINK="/etc/ambari-logsearch-portal/conf"
+
+rm -f $LOGSEARCH_SCRIPT_LINK_NAME
+rm -f $LOGSEARCH_CONF_DIR_LINK
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/ambari/blob/562795c4/ambari-logsearch/ambari-logsearch-assembly/src/main/package/rpm/portal/preinstall.sh
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-assembly/src/main/package/rpm/portal/preinstall.sh b/ambari-logsearch/ambari-logsearch-assembly/src/main/package/rpm/portal/preinstall.sh
new file mode 100644
index 0000000..dfb8752
--- /dev/null
+++ b/ambari-logsearch/ambari-logsearch-assembly/src/main/package/rpm/portal/preinstall.sh
@@ -0,0 +1,28 @@
+#!/bin/bash
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements.  See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You 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
+
+LOGSEARCH_CONF="/etc/ambari-logsearch-portal/conf"
+LOGSEARCH_CONF_BACKUP="/usr/lib/ambari-logsearch-portal/conf-old"
+
+if [ -d $LOGSEARCH_CONF_BACKUP ]; then
+  rm -rf $LOGSEARCH_CONF_BACKUP
+fi
+
+if [ -d $LOGSEARCH_CONF ]; then
+  mkdir -p $LOGSEARCH_CONF_BACKUP
+  cp -r $LOGSEARCH_CONF/* $LOGSEARCH_CONF_BACKUP
+  rm -rf $LOGSEARCH_CONF
+fi
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/ambari/blob/562795c4/ambari-logsearch/ambari-logsearch-logfeeder/README.md
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-logfeeder/README.md b/ambari-logsearch/ambari-logsearch-logfeeder/README.md
index d2e55f0..48cb81b 100644
--- a/ambari-logsearch/ambari-logsearch-logfeeder/README.md
+++ b/ambari-logsearch/ambari-logsearch-logfeeder/README.md
@@ -29,11 +29,11 @@ First you need to start every required service (except logfeeder), go to `ambari
 docker-compose up -d zookeeper solr logsearch
 ```
 
-Secondly, if you are planning to run Log Feeder from an IDE, for running the LogFeeder main methoud, you will need to set the working directory to `ambari/ambari-logsearch/ambari-logsearch-logfeeder` and use `--monitor` as a command line argument.
+Secondly, if you are planning to run Log Feeder from an IDE, for running the LogFeeder main methoud, you will need to set the working directory to `ambari/ambari-logsearch/ambari-logsearch-logfeeder` or set `LOGFEEDER_RELATIVE_LOCATION` env variable.
 With Maven, you won't need these steps, just run this command from the ambari-logsearch-logfeeder folder:
 
 ```bash
-mvn clean package -DskipTests exec:java
+mvn clean package -DskipTests spring-boot:run
 ```
 
 # Input Configuration

http://git-wip-us.apache.org/repos/asf/ambari/blob/562795c4/ambari-logsearch/ambari-logsearch-logfeeder/build.properties
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-logfeeder/build.properties b/ambari-logsearch/ambari-logsearch-logfeeder/build.properties
deleted file mode 100644
index 013ba2e..0000000
--- a/ambari-logsearch/ambari-logsearch-logfeeder/build.properties
+++ /dev/null
@@ -1,18 +0,0 @@
-#   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.
-
-app.pkg.dir=${app.work.dir}/pkg
-
-app.dev.war.dir=${app.work.dir}/webapps/logsearch
-app.war.name=logsearch.war
-
-app.target.dir=${builddir}/target/classes/static
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/ambari/blob/562795c4/ambari-logsearch/ambari-logsearch-logfeeder/build.xml
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-logfeeder/build.xml b/ambari-logsearch/ambari-logsearch-logfeeder/build.xml
index 738b2ef..c150b55 100644
--- a/ambari-logsearch/ambari-logsearch-logfeeder/build.xml
+++ b/ambari-logsearch/ambari-logsearch-logfeeder/build.xml
@@ -19,10 +19,8 @@
   <property environment="env"/>
   <property name="debuglevel" value="source,lines,vars"/>
   <dirname property="builddir" file="build.xml"/>
-  <property name="target" value="1.7"/>
-  <property name="source" value="1.7"/>
-  <property file="local.properties"/>
-  <property file="build.properties"/>
+  <property name="target" value="1.8"/>
+  <property name="source" value="1.8"/>
   <target name="init">
   </target>
   <target name="build"/>
@@ -31,18 +29,20 @@
     <delete dir="target/package"/>
     <copy todir="target/package/libs" includeEmptyDirs="no">
       <fileset dir="target/libs"/>
+      <fileset file="target/ambari-logsearch-logfeeder*.jar"/>
     </copy>
-    <copy todir="target/package/classes" includeEmptyDirs="no">
-      <fileset dir="target/classes"/>
+    <copy todir="target/package/bin" includeEmptyDirs="no">
+      <fileset file="src/main/scripts/logfeeder.sh"/>
     </copy>
-    <copy todir="target/package" includeEmptyDirs="no">
-      <fileset file="config.json"/>
+    <copy todir="target/package/conf" includeEmptyDirs="no">
+      <fileset file="target/classes/grok-patterns"/>
+      <fileset file="target/classes/log4j.xml"/>
+      <fileset file="target/classes/logfeeder.properties"/>
+      <fileset file="target/classes/alias_config.json"/>
+      <fileset file="src/main/scripts/logfeeder-env.sh"/>
     </copy>
-    <copy todir="target/package" includeEmptyDirs="no">
-      <fileset file="grok-patterns"/>
-      <fileset file="src/main/scripts/run.sh"/>
-    </copy>
-    <chmod file="target/package/run.sh" perm="755"/>
+    <chmod file="target/package/bin/logfeeder.sh" perm="755"/>
+    <chmod file="target/package/conf/logfeeder-env.sh" perm="755"/>
     <tar compression="gzip" destfile="target/ambari-logsearch-logfeeder.tgz">
       <tarfileset mode="755" dir="target/package">
         <include name="*.sh"/>
@@ -52,6 +52,4 @@
       </tarfileset>
     </tar>
   </target>
-  <target description="Build all projects which reference this project. Useful to propagate changes."
-          name="build-refprojects"/>
 </project>

http://git-wip-us.apache.org/repos/asf/ambari/blob/562795c4/ambari-logsearch/ambari-logsearch-logfeeder/pom.xml
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-logfeeder/pom.xml b/ambari-logsearch/ambari-logsearch-logfeeder/pom.xml
index 005af15..6a3524d 100644
--- a/ambari-logsearch/ambari-logsearch-logfeeder/pom.xml
+++ b/ambari-logsearch/ambari-logsearch-logfeeder/pom.xml
@@ -198,7 +198,6 @@
     </dependency>
   </dependencies>
   <build>
-    <finalName>LogFeeder</finalName>
     <pluginManagement>
       <plugins>
         <plugin>
@@ -222,40 +221,10 @@
           <target>${jdk.version}</target>
         </configuration>
       </plugin>
-
-      <!-- Exec main class plugin -->
-      <plugin>
-        <groupId>org.codehaus.mojo</groupId>
-        <artifactId>exec-maven-plugin</artifactId>
-        <version>1.2.1</version>
-        <executions>
-          <execution>
-            <goals>
-              <goal>java</goal>
-            </goals>
-          </execution>
-        </executions>
-        <configuration>
-          <mainClass>org.apache.ambari.logfeeder.LogFeeder</mainClass>
-          <arguments>
-            <argument>--monitor</argument>
-          </arguments>
-        </configuration>
-      </plugin>
       <plugin>
         <groupId>org.springframework.boot</groupId>
         <artifactId>spring-boot-maven-plugin</artifactId>
         <version>${spring-boot.version}</version>
-        <configuration>
-          <classifier>exec</classifier>
-        </configuration>
-        <executions>
-          <execution>
-            <goals>
-              <goal>repackage</goal>
-            </goals>
-          </execution>
-        </executions>
       </plugin>
       <!-- copy-dependencies -->
       <plugin>

http://git-wip-us.apache.org/repos/asf/ambari/blob/562795c4/ambari-logsearch/ambari-logsearch-logfeeder/run.sh
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-logfeeder/run.sh b/ambari-logsearch/ambari-logsearch-logfeeder/run.sh
index 70947ec..47a9e6c 100755
--- a/ambari-logsearch/ambari-logsearch-logfeeder/run.sh
+++ b/ambari-logsearch/ambari-logsearch-logfeeder/run.sh
@@ -14,6 +14,4 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-echo "LOG FEEDER"
-mvn clean compile
-mvn exec:java
+mvn clean spring-boot:run

http://git-wip-us.apache.org/repos/asf/ambari/blob/562795c4/ambari-logsearch/ambari-logsearch-logfeeder/src/main/java/org/apache/ambari/logfeeder/LogFeeder.java
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-logfeeder/src/main/java/org/apache/ambari/logfeeder/LogFeeder.java b/ambari-logsearch/ambari-logsearch-logfeeder/src/main/java/org/apache/ambari/logfeeder/LogFeeder.java
index 2d31e5a..235109c 100644
--- a/ambari-logsearch/ambari-logsearch-logfeeder/src/main/java/org/apache/ambari/logfeeder/LogFeeder.java
+++ b/ambari-logsearch/ambari-logsearch-logfeeder/src/main/java/org/apache/ambari/logfeeder/LogFeeder.java
@@ -18,54 +18,21 @@
  */
 package org.apache.ambari.logfeeder;
 
-import com.google.gson.GsonBuilder;
-import org.apache.ambari.logfeeder.common.LogEntryParseTester;
-import org.apache.commons.io.FileUtils;
-import org.apache.log4j.LogManager;
 import org.springframework.boot.Banner;
 import org.springframework.boot.autoconfigure.SpringBootApplication;
 import org.springframework.boot.builder.SpringApplicationBuilder;
 import org.springframework.boot.system.ApplicationPidFileWriter;
 
-import java.io.File;
-import java.nio.charset.Charset;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Map;
-
 @SpringBootApplication(
   scanBasePackages = {"org.apache.ambari.logfeeder"}
 )
 public class LogFeeder {
 
   public static void main(String[] args) {
-    LogFeederCommandLine cli = new LogFeederCommandLine(args);
-    if (cli.isTest()) {
-      test(cli);
-    }
-    String pidFile = System.getenv("PID_FILE") == null ? "logfeeder.pid" : System.getenv("PID_FILE");
+    String pidFile = System.getenv("LOGFEEDER_PID_FILE") == null ? "logfeeder.pid" : System.getenv("LOGFEEDER_PID_FILE");
     new SpringApplicationBuilder(LogFeeder.class)
       .bannerMode(Banner.Mode.OFF)
       .listeners(new ApplicationPidFileWriter(pidFile))
       .run(args);
   }
-
-  private static void test(LogFeederCommandLine cli) {
-    try {
-      LogManager.shutdown();
-      String testLogEntry = cli.getTestLogEntry();
-      String testShipperConfig = FileUtils.readFileToString(new File(cli.getTestShipperConfig()), Charset.defaultCharset());
-      List<String> testGlobalConfigs = new ArrayList<>();
-      for (String testGlobalConfigFile : cli.getTestGlobalConfigs().split(",")) {
-        testGlobalConfigs.add(FileUtils.readFileToString(new File(testGlobalConfigFile), Charset.defaultCharset()));
-      }
-      String testLogId = cli.getTestLogId();
-      Map<String, Object> result = new LogEntryParseTester(testLogEntry, testShipperConfig, testGlobalConfigs, testLogId).parse();
-      String parsedLogEntry = new GsonBuilder().setPrettyPrinting().create().toJson(result);
-      System.out.println("The result of the parsing is:\n" + parsedLogEntry);
-    } catch (Exception e) {
-      System.out.println("Exception occurred, could not test if log entry is parseable");
-      e.printStackTrace(System.out);
-    }
-  }
 }

http://git-wip-us.apache.org/repos/asf/ambari/blob/562795c4/ambari-logsearch/ambari-logsearch-logfeeder/src/main/java/org/apache/ambari/logfeeder/LogFeederCommandLine.java
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-logfeeder/src/main/java/org/apache/ambari/logfeeder/LogFeederCommandLine.java b/ambari-logsearch/ambari-logsearch-logfeeder/src/main/java/org/apache/ambari/logfeeder/LogFeederCommandLine.java
index 61e7a1e..a6fcb2a 100644
--- a/ambari-logsearch/ambari-logsearch-logfeeder/src/main/java/org/apache/ambari/logfeeder/LogFeederCommandLine.java
+++ b/ambari-logsearch/ambari-logsearch-logfeeder/src/main/java/org/apache/ambari/logfeeder/LogFeederCommandLine.java
@@ -19,22 +19,25 @@
 
 package org.apache.ambari.logfeeder;
 
+import com.google.gson.GsonBuilder;
+import org.apache.ambari.logfeeder.common.LogEntryParseTester;
 import org.apache.commons.cli.CommandLine;
 import org.apache.commons.cli.CommandLineParser;
 import org.apache.commons.cli.DefaultParser;
 import org.apache.commons.cli.HelpFormatter;
 import org.apache.commons.cli.Option;
 import org.apache.commons.cli.Options;
+import org.apache.commons.io.FileUtils;
 import org.apache.commons.lang.StringUtils;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
+import org.apache.log4j.LogManager;
 
+import java.io.File;
+import java.nio.charset.Charset;
 import java.util.ArrayList;
 import java.util.List;
+import java.util.Map;
 
 public class LogFeederCommandLine {
-
-  private static final Logger LOG = LoggerFactory.getLogger(LogFeederCommandLine.class);
   
   private static final String TEST_COMMAND = "test";
   private static final String TEST_LOG_ENTRY_OPTION = "test-log-entry";
@@ -42,11 +45,9 @@ public class LogFeederCommandLine {
   private static final String TEST_GLOBAL_CONFIG_OPTION = "test-global-config";
   private static final String TEST_LOG_ID_OPTION = "test-log-id";
   
-  private static final String COMMAND_LINE_SYNTAX = "java org.apache.ambari.logfeeder.LogFeeder -(monitor|test) [args]";
-  
-  private CommandLine cli;
+  private static final String COMMAND_LINE_SYNTAX = "java org.apache.ambari.logfeeder.LogFeederCommandLine --test [args]";
 
-  public LogFeederCommandLine(String[] args) {
+  public static void main(String[] args) {
     Options options = new Options();
     HelpFormatter helpFormatter = new HelpFormatter();
     helpFormatter.setDescPadding(10);
@@ -95,7 +96,7 @@ public class LogFeederCommandLine {
 
     try {
       CommandLineParser cmdLineParser = new DefaultParser();
-      cli = cmdLineParser.parse(options, args);
+      CommandLine cli = cmdLineParser.parse(options, args);
 
       if (cli.hasOption('h')) {
         helpFormatter.printHelp(COMMAND_LINE_SYNTAX, options);
@@ -105,11 +106,12 @@ public class LogFeederCommandLine {
       if (cli.hasOption("t")) {
         command = TEST_COMMAND;
         validateRequiredOptions(cli, command, testLogEntryOption, testShipperConfOption);
-      } else {
-        LOG.info("Start application in monitor mode ");
       }
+      test(cli);
     } catch (Exception e) {
-      LOG.info("Error parsing command line parameters: {}. LogFeeder will be started in monitoring mode.", e.getMessage());
+      e.printStackTrace();
+      helpFormatter.printHelp(COMMAND_LINE_SYNTAX, options);
+      System.exit(1);
     }
   }
 
@@ -125,24 +127,23 @@ public class LogFeederCommandLine {
         String.format("The following options required for '%s' : %s", command, StringUtils.join(requiredOptions, ",")));
     }
   }
-  
-  public boolean isTest() {
-    return cli != null && cli.hasOption('t');
-  }
-  
-  public String getTestLogEntry() {
-    return cli.getOptionValue("tle");
-  }
-  
-  public String getTestShipperConfig() {
-    return cli.getOptionValue("tsc");
-  }
-  
-  public String getTestGlobalConfigs() {
-    return cli.getOptionValue("tgc");
-  }
-  
-  public String getTestLogId() {
-    return cli.getOptionValue("tli");
+
+  private static void test(CommandLine cli) {
+    try {
+      LogManager.shutdown();
+      String testLogEntry = cli.getOptionValue("tle");
+      String testShipperConfig = FileUtils.readFileToString(new File(cli.getOptionValue("tsc")), Charset.defaultCharset());
+      List<String> testGlobalConfigs = new ArrayList<>();
+      for (String testGlobalConfigFile : cli.getOptionValue("tgc").split(",")) {
+        testGlobalConfigs.add(FileUtils.readFileToString(new File(testGlobalConfigFile), Charset.defaultCharset()));
+      }
+      String testLogId = cli.getOptionValue("tli");
+      Map<String, Object> result = new LogEntryParseTester(testLogEntry, testShipperConfig, testGlobalConfigs, testLogId).parse();
+      String parsedLogEntry = new GsonBuilder().setPrettyPrinting().create().toJson(result);
+      System.out.println("The result of the parsing is:\n" + parsedLogEntry);
+    } catch (Exception e) {
+      System.out.println("Exception occurred, could not test if log entry is parseable");
+      e.printStackTrace(System.out);
+    }
   }
 }

http://git-wip-us.apache.org/repos/asf/ambari/blob/562795c4/ambari-logsearch/ambari-logsearch-logfeeder/src/main/java/org/apache/ambari/logfeeder/common/ConfigHandler.java
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-logfeeder/src/main/java/org/apache/ambari/logfeeder/common/ConfigHandler.java b/ambari-logsearch/ambari-logsearch-logfeeder/src/main/java/org/apache/ambari/logfeeder/common/ConfigHandler.java
index 35c0e6a..037f4a1 100644
--- a/ambari-logsearch/ambari-logsearch-logfeeder/src/main/java/org/apache/ambari/logfeeder/common/ConfigHandler.java
+++ b/ambari-logsearch/ambari-logsearch-logfeeder/src/main/java/org/apache/ambari/logfeeder/common/ConfigHandler.java
@@ -21,12 +21,12 @@ package org.apache.ambari.logfeeder.common;
 
 import java.io.BufferedInputStream;
 import java.io.File;
+import java.io.FileNotFoundException;
 import java.lang.reflect.Type;
 import java.nio.charset.Charset;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collections;
-import java.util.Comparator;
 import java.util.HashMap;
 import java.util.HashSet;
 import java.util.List;
@@ -62,6 +62,7 @@ import org.apache.log4j.Level;
 import org.apache.log4j.Logger;
 
 import com.google.gson.reflect.TypeToken;
+import org.springframework.core.io.ClassPathResource;
 
 import javax.annotation.PostConstruct;
 import javax.annotation.PreDestroy;
@@ -146,6 +147,10 @@ public class ConfigHandler implements InputConfigMonitor {
 
   private void loadConfigsUsingClassLoader(String configFileName) throws Exception {
     try (BufferedInputStream fis = (BufferedInputStream) this.getClass().getClassLoader().getResourceAsStream(configFileName)) {
+      ClassPathResource configFile = new ClassPathResource(configFileName);
+      if (!configFile.exists()) {
+        throw new FileNotFoundException(configFileName);
+      }
       String configData = IOUtils.toString(fis, Charset.defaultCharset());
       loadConfigs(configData);
     }

http://git-wip-us.apache.org/repos/asf/ambari/blob/562795c4/ambari-logsearch/ambari-logsearch-logfeeder/src/main/package/deb/control/control
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-logfeeder/src/main/package/deb/control/control b/ambari-logsearch/ambari-logsearch-logfeeder/src/main/package/deb/control/control
deleted file mode 100644
index 40cd855..0000000
--- a/ambari-logsearch/ambari-logsearch-logfeeder/src/main/package/deb/control/control
+++ /dev/null
@@ -1,22 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one or more
-# contributor license agreements.  See the NOTICE file distributed with
-# this work for additional information regarding copyright ownership.
-# The ASF licenses this file to You 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: [[artifactId]]
-Version: [[package-version]]-[[package-release]]
-Section: [[deb.section]]
-Priority: [[deb.priority]]
-Depends: [[deb.dependency.list]]
-Architecture: [[deb.architecture]]
-Description: [[description]]
-Maintainer: [[deb.publisher]]

http://git-wip-us.apache.org/repos/asf/ambari/blob/562795c4/ambari-logsearch/ambari-logsearch-logfeeder/src/main/package/deb/control/postinst
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-logfeeder/src/main/package/deb/control/postinst b/ambari-logsearch/ambari-logsearch-logfeeder/src/main/package/deb/control/postinst
deleted file mode 100644
index 21a01fa..0000000
--- a/ambari-logsearch/ambari-logsearch-logfeeder/src/main/package/deb/control/postinst
+++ /dev/null
@@ -1,15 +0,0 @@
-#!/bin/bash
-# Licensed to the Apache Software Foundation (ASF) under one or more
-# contributor license agreements.  See the NOTICE file distributed with
-# this work for additional information regarding copyright ownership.
-# The ASF licenses this file to You 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

http://git-wip-us.apache.org/repos/asf/ambari/blob/562795c4/ambari-logsearch/ambari-logsearch-logfeeder/src/main/package/deb/control/postrm
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-logfeeder/src/main/package/deb/control/postrm b/ambari-logsearch/ambari-logsearch-logfeeder/src/main/package/deb/control/postrm
deleted file mode 100644
index 21a01fa..0000000
--- a/ambari-logsearch/ambari-logsearch-logfeeder/src/main/package/deb/control/postrm
+++ /dev/null
@@ -1,15 +0,0 @@
-#!/bin/bash
-# Licensed to the Apache Software Foundation (ASF) under one or more
-# contributor license agreements.  See the NOTICE file distributed with
-# this work for additional information regarding copyright ownership.
-# The ASF licenses this file to You 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

http://git-wip-us.apache.org/repos/asf/ambari/blob/562795c4/ambari-logsearch/ambari-logsearch-logfeeder/src/main/package/deb/control/preinst
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-logfeeder/src/main/package/deb/control/preinst b/ambari-logsearch/ambari-logsearch-logfeeder/src/main/package/deb/control/preinst
deleted file mode 100644
index 21a01fa..0000000
--- a/ambari-logsearch/ambari-logsearch-logfeeder/src/main/package/deb/control/preinst
+++ /dev/null
@@ -1,15 +0,0 @@
-#!/bin/bash
-# Licensed to the Apache Software Foundation (ASF) under one or more
-# contributor license agreements.  See the NOTICE file distributed with
-# this work for additional information regarding copyright ownership.
-# The ASF licenses this file to You 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

http://git-wip-us.apache.org/repos/asf/ambari/blob/562795c4/ambari-logsearch/ambari-logsearch-logfeeder/src/main/package/deb/control/prerm
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-logfeeder/src/main/package/deb/control/prerm b/ambari-logsearch/ambari-logsearch-logfeeder/src/main/package/deb/control/prerm
deleted file mode 100644
index 21a01fa..0000000
--- a/ambari-logsearch/ambari-logsearch-logfeeder/src/main/package/deb/control/prerm
+++ /dev/null
@@ -1,15 +0,0 @@
-#!/bin/bash
-# Licensed to the Apache Software Foundation (ASF) under one or more
-# contributor license agreements.  See the NOTICE file distributed with
-# this work for additional information regarding copyright ownership.
-# The ASF licenses this file to You 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

http://git-wip-us.apache.org/repos/asf/ambari/blob/562795c4/ambari-logsearch/ambari-logsearch-logfeeder/src/main/scripts/logfeeder-env.sh
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-logfeeder/src/main/scripts/logfeeder-env.sh b/ambari-logsearch/ambari-logsearch-logfeeder/src/main/scripts/logfeeder-env.sh
new file mode 100755
index 0000000..37e9930
--- /dev/null
+++ b/ambari-logsearch/ambari-logsearch-logfeeder/src/main/scripts/logfeeder-env.sh
@@ -0,0 +1,40 @@
+#!/bin/bash
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements.  See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You 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.
+
+# Log Feeder extra options
+export LOGFEEDER_JAVA_OPTS=${LOGFEEDER_JAVA_OPTS:-""}
+
+# Log Feeder debug options
+# export LOGFEEDER_DEBUG=true
+# exoprt LOGFEEDER_DEBUG_SUSPEND=n
+export LOGFEEDER_DEBUG_PORT=5006
+
+# Log Feeder memory
+# export LOGFEEDER_JAVA_MEM="-Xmx512m"
+
+# export LOG_PATH=/var/log/ambari-logsearch-logfeeder/
+# export LOG_FILE=logfeeder.log
+
+# Pid file of the application
+# export LOGFEEDER_PID_DIR=/var/run/ambari-logsearch-logfeeder
+# export LOGFEEDER_PID_FILE=logfeeder.pid
+
+# SSL settings"
+# export LOGFEEDER_SSL="true"
+# export LOGFEEDER_KEYSTORE_LOCATION="/my/path/keystore.jks"
+# export LOGFEEDER_KEYSTORE_TYPE="jks"
+# export LOGFEEDER_TRUSTSTORE_LOCATION="/my/path/trutstore.jks"
+# export LOGFEEDER_TRUSTSTORE_TYPE="jks"
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/ambari/blob/562795c4/ambari-logsearch/ambari-logsearch-logfeeder/src/main/scripts/logfeeder.sh
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-logfeeder/src/main/scripts/logfeeder.sh b/ambari-logsearch/ambari-logsearch-logfeeder/src/main/scripts/logfeeder.sh
new file mode 100755
index 0000000..cfacea5
--- /dev/null
+++ b/ambari-logsearch/ambari-logsearch-logfeeder/src/main/scripts/logfeeder.sh
@@ -0,0 +1,292 @@
+#!/bin/bash
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements.  See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You 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.
+
+JVM="java"
+
+if [ -x $JAVA_HOME/bin/java ]; then
+  JVM=$JAVA_HOME/bin/java
+fi
+
+if [ "$LOGFEEDER_JAVA_MEM" = "" ]; then
+  LOGFEEDER_JAVA_MEM="-Xmx512m"
+fi
+
+readlinkf(){
+  # get real path on mac OSX
+  perl -MCwd -e 'print Cwd::abs_path shift' "$1";
+}
+
+if [ "$(uname -s)" = 'Linux' ]; then
+  SCRIPT_DIR="`dirname "$(readlink -f "$0")"`"
+else
+  SCRIPT_DIR="`dirname "$(readlinkf "$0")"`"
+fi
+
+LOGFEEDER_ROOT_DIR="`dirname \"$SCRIPT_DIR\"`"
+LOGFEEDER_LIBS_DIR="$LOGFEEDER_ROOT_DIR/libs"
+
+if [ "$LOGFEEDER_CONF_DIR" = "" ]; then
+  LOGFEEDER_CONF_DIR="/etc/ambari-logsearch-logfeeder/conf"
+  if [ ! -d $LOGFEEDER_CONF_DIR ]; then
+    if [ -d "$LOGFEEDER_ROOT_DIR/conf" ]; then
+      LOGFEEDER_CONF_DIR="$LOGFEEDER_ROOT_DIR/conf"
+    fi
+  fi
+fi
+
+if [ -f "$LOGFEEDER_CONF_DIR/logfeeder-env.sh" ]; then
+  source $LOGFEEDER_CONF_DIR/logfeeder-env.sh
+fi
+
+if [ ! -z "$LOGSEARCH_SOLR_CLIENT_SSL_INCLUDE" ]; then
+  source $LOGSEARCH_SOLR_CLIENT_SSL_INCLUDE
+fi
+
+if [ -z "$LOGFEEDER_PID_FILE" ]; then
+  LOGFEEDER_PID_DIR=$HOME
+  export LOGFEEDER_PID_FILE=$LOGFEEDER_PID_DIR/logfeeder.pid
+fi
+
+if [ -z "$LOG_FILE" ]; then
+  export LOG_FILE="logfeeder.log"
+fi
+
+LOGFEEDER_GC_LOGFILE="logfeeder_gc.log"
+
+if [ -z "$LOG_PATH" ]; then
+  LOG_FILE="$HOME/$LOG_FILE"
+  LOGFEEDER_GC_LOGFILE="$HOME/$LOGFEEDER_GC_LOGFILE"
+else
+  LOG_PATH_WITHOUT_SLASH=${LOG_PATH%/}
+  LOG_FILE="$LOG_PATH_WITHOUT_SLASH/$LOG_FILE"
+  LOGFEEDER_GC_LOGFILE="$LOG_PATH_WITHOUT_SLASH/$LOGFEEDER_GC_LOGFILE"
+fi
+
+LOGFEEDER_GC_OPTS="-XX:+PrintGCDetails -XX:+PrintGCDateStamps -Xloggc:$LOGFEEDER_GC_LOGFILE"
+
+function print_usage() {
+  cat << EOF
+
+   Usage: [<command>] [<arguments with flags>]
+
+   commands:
+     start                         Start Log Feeder
+     stop                          Stop Log Feeder
+     status                        Check Log Feeder status (pid file)
+     test                          Test Log Feeder shipper configs
+     help                          Print usage
+
+
+   start command arguments:
+     -d, --debug                   Start java process in debug mode
+     -f, --foreground              Start java process in foreground
+
+   test command arguments:
+     -h, --help                    Print usage
+     -tle, --test-log-entry        Log entry to test if it's parseable (required)
+     -tsc, --test-shipper-config   Shipper configuration file for testing if log entry is parseable (required)
+     -tgc, --test-global-config    Global configuration files (comma separated list) for testing if log entry is parseable
+     -tli, --test-log-id           The id of the log to test
+
+EOF
+}
+
+function spinner() {
+  local pid=$1
+  local delay=0.5
+  local spinstr='|/-\'
+  while [ "$(ps aux | awk '{print $2}' | grep -w $pid)" ]; do
+      local temp=${spinstr#?}
+      printf " [%c]  " "$spinstr"
+      local spinstr=$temp${spinstr%"$temp"}
+      sleep $delay
+      printf "\b\b\b\b\b\b"
+  done
+  printf "    \b\b\b\b"
+}
+
+function status() {
+  echo "Checking Log Feeder status ..."
+  if [ -f "$LOGFEEDER_PID_FILE" ]; then
+    LOGFEEDER_PID=`cat "$LOGFEEDER_PID_FILE"`
+  else
+    echo "Log Feeder pid not exists. (probably the process is not running)"
+    exit 1
+  fi
+
+  if ps -p $LOGFEEDER_PID > /dev/null
+   then
+   echo "Log Feeder process is running. (pid: $LOGFEEDER_PID)"
+   exit 0
+  else
+   echo "Log Feeder process is not running."
+   exit 1
+  fi
+}
+
+function start() {
+  (status);
+  exit_status=$(echo $?)
+  if [ "$exit_status" = "0" ]; then
+    echo "Skipping start process."
+    exit 0
+  fi
+
+  FG="false"
+  LOGFEEDER_DEBUG_SUSPEND=${LOGFEEDER_DEBUG_SUSPEND:-n}
+  LOGFEEDER_DEBUG_PORT=${LOGFEEDER_DEBUG_PORT:-"5006"}
+
+  if [ "$LOGFEEDER_DEBUG" = "true" ]; then
+    LOGFEEDER_JAVA_OPTS="$LOGFEEDER_JAVA_OPTS -Xdebug -Xrunjdwp:transport=dt_socket,address=$LOGFEEDER_DEBUG_PORT,server=y,suspend=$LOGFEEDER_DEBUG_SUSPEND "
+  fi
+
+  if [ "$LOGFEEDER_SSL" = "true" ]; then
+    LOGFEEDER_JAVA_OPTS="$LOGFEEDER_JAVA_OPTS -Djavax.net.ssl.keyStore=$LOGFEEDER_KEYSTORE_LOCATION -Djavax.net.ssl.keyStoreType=$LOGFEEDER_KEYSTORE_TYPE -Djavax.net.ssl.trustStore=$LOGFEEDER_TRUSTSTORE_LOCATION -Djavax.net.ssl.trustStoreType=$LOGFEEDER_TRUSTSTORE_TYPE"
+  fi
+
+  if [ "$LOGFEEDER_JMX" = "true" ]; then
+   LOGFEEDER_JAVA_OPTS="$LOGFEEDER_JAVA_OPTS -Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.ssl=false -Dcom.sun.management.jmxremote.authenticate=false -Dcom.sun.management.jmxremote.port=2098"
+  fi
+
+  if [ $# -gt 0 ]; then
+    while true; do
+      case "$1" in
+          -f|--foreground)
+              FG="true"
+              shift
+          ;;
+          -d|--debug)
+              if [ "$LOGFEEDER_DEBUG" != "true" ]; then
+                LOGFEEDER_JAVA_OPTS="$LOGFEEDER_JAVA_OPTS -Xdebug -Xrunjdwp:transport=dt_socket,address=$LOGFEEDER_DEBUG_PORT,server=y,suspend=$LOGFEEDER_DEBUG_SUSPEND "
+              fi
+              shift
+          ;;
+          *)
+              if [ "${1:0:2}" == "-D" ]; then
+                # pass thru any opts that begin with -D (java system props)
+                LOGFEEDER_JAVA_OPTS+=("$1")
+                echo "$LOGFEEDER_JAVA_OPTS"
+                shift
+              else
+                if [ "$1" != "" ]; then
+                  print_usage
+                  exit 1
+                else
+                  break
+                fi
+              fi
+          ;;
+      esac
+    done
+  fi
+
+  if [ $FG == "true" ]; then
+    echo "Starting logfeeder... (foreground) pid_file=$LOGFEEDER_PID_FILE"
+    echo "Run command $JVM -cp '$LOGFEEDER_CONF_DIR:$LOGFEEDER_LIBS_DIR/*' $LOGFEEDER_GC_OPTS $LOGFEEDER_JAVA_OPTS $LOGFEEDER_JAVA_MEM org.apache.ambari.logfeeder.LogFeeder"
+    $JVM -cp "$LOGFEEDER_CONF_DIR:$LOGFEEDER_LIBS_DIR/*" $LOGFEEDER_GC_OPTS $LOGFEEDER_JAVA_OPTS $LOGFEEDER_JAVA_MEM org.apache.ambari.logfeeder.LogFeeder
+  else
+   echo "Starting logfeeder... Output file=$LOG_FILE pid_file=$LOGFEEDER_PID_FILE"
+   echo "Run command nohup $JVM -cp '$LOGFEEDER_CONF_DIR:$LOGFEEDER_LIBS_DIR/*' $LOGFEEDER_GC_OPTS $LOGFEEDER_JAVA_OPTS $LOGFEEDER_JAVA_MEM org.apache.ambari.logfeeder.LogFeeder"
+   nohup $JVM -cp "$LOGFEEDER_CONF_DIR:$LOGFEEDER_LIBS_DIR/*" $LOGFEEDER_GC_OPTS $LOGFEEDER_JAVA_OPTS $LOGFEEDER_JAVA_MEM org.apache.ambari.logfeeder.LogFeeder > $LOG_FILE 2>&1 &
+  fi
+}
+
+function stop() {
+  LOGFEEDER_STOP_WAIT=3
+  if [ -f "$LOGFEEDER_PID_FILE" ]; then
+    LOGFEEDER_PID=`cat "$LOGFEEDER_PID_FILE"`
+  fi
+
+  if [ "$LOGFEEDER_PID" != "" ]; then
+    echo -e "Sending stop command to Log Feeder... Checking PID: $LOGFEEDER_PID."
+    kill $LOGFEEDER_PID
+      (loops=0
+      while true
+      do
+        CHECK_PID=`ps auxww | awk '{print $2}' | grep -w $LOGFEEDER_PID | sort -r | tr -d ' '`
+        if [ "$CHECK_PID" != "" ]; then
+          slept=$((loops * 2))
+          if [ $slept -lt $LOGFEEDER_STOP_WAIT ]; then
+            sleep 2
+            loops=$[$loops+1]
+          else
+            exit # subshell!
+          fi
+        else
+          exit # subshell!
+        fi
+      done) &
+    spinner $!
+    rm -f "$LOGFEEDER_PID_FILE"
+  else
+    echo -e "No LogFeeder process found to stop."
+    exit 0
+  fi
+
+  CHECK_PID=`ps auxww | awk '{print $2}' | grep -w $LOGFEEDER_PID | sort -r | tr -d ' '`
+  if [ "$CHECK_PID" != "" ]; then
+    echo -e "Log Feeder process $LOGFEEDER_PID is still running; forcefully killing it now."
+    kill -9 $LOGFEEDER_PID
+    echo "Killed process $LOGFEEDER_PID"
+    rm -f "$LOGFEEDER_PID_FILE"
+    sleep 1
+  else
+    echo "Log Feeder is stopped."
+  fi
+
+  CHECK_PID=`ps auxww | awk '{print $2}' | grep -w $LOGFEEDER_PID | sort -r | tr -d ' '`
+  if [ "$CHECK_PID" != "" ]; then
+    echo "ERROR: Failed to kill Log Feeder Java process $LOGFEEDER_PID ... script fails."
+    exit 1
+  fi
+}
+
+function test() {
+  echo "Running command: $JVM -cp "$LOGFEEDER_CONF_DIR:$LOGFEEDER_LIBS_DIR/*" org.apache.ambari.logfeeder.LogFeederCommandLine --test ${@}"
+  $JVM -cp "$LOGFEEDER_CONF_DIR:$LOGFEEDER_LIBS_DIR/*" $LOGFEEDER_JAVA_OPTS org.apache.ambari.logfeeder.LogFeederCommandLine --test ${@}
+}
+
+if [ $# -gt 0 ]; then
+    SCRIPT_CMD="$1"
+    shift
+else
+   print_usage
+   exit 1
+fi
+
+case $SCRIPT_CMD in
+  start)
+    start ${1+"$@"}
+  ;;
+  stop)
+    stop
+  ;;
+  status)
+    status
+  ;;
+  test)
+    test ${1+"$@"}
+  ;;
+  help)
+    print_usage
+    exit 0
+  ;;
+  *)
+    print_usage
+    exit 1
+  ;;
+
+esac
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/ambari/blob/562795c4/ambari-logsearch/ambari-logsearch-logfeeder/src/main/scripts/run.sh
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-logfeeder/src/main/scripts/run.sh b/ambari-logsearch/ambari-logsearch-logfeeder/src/main/scripts/run.sh
deleted file mode 100644
index 22e1cb2..0000000
--- a/ambari-logsearch/ambari-logsearch-logfeeder/src/main/scripts/run.sh
+++ /dev/null
@@ -1,103 +0,0 @@
-#!/bin/bash
-# Licensed to the Apache Software Foundation (ASF) under one or more
-# contributor license agreements.  See the NOTICE file distributed with
-# this work for additional information regarding copyright ownership.
-# The ASF licenses this file to You 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.
-
-curr_dir=`pwd`
-cd `dirname $0`; script_dir=`pwd`; cd $curr_dir
-
-foreground=0
-if [ "$1" = "-foreground" ]; then
-  foreground=1
-  shift
-fi
-
-if [ ! -z "$LOGFEEDER_INCLUDE" ]; then
-  source $LOGFEEDER_INCLUDE
-fi
-
-if [ ! -z "$LOGSEARCH_SOLR_CLIENT_SSL_INCLUDE" ]; then
-  source $LOGSEARCH_SOLR_CLIENT_SSL_INCLUDE
-fi
-
-JAVA=java
-if [ -x $JAVA_HOME/bin/java ]; then
-  JAVA=$JAVA_HOME/bin/java
-fi
-
-if [ "$LOGFEEDER_JAVA_MEM" = "" ]; then
-  LOGFEEDER_JAVA_MEM="-Xmx512m"
-fi
-
-if [ "$LOGFILE" = "" ]; then
-  LOGFILE="/var/log/logfeeder/logfeeder.out"
-fi
-
-if [ "$PID_FILE" = "" ]; then
-  LOGFEEDER_PID_DIR=$HOME
-  PID_FILE=$LOGFEEDER_PID_DIR/logsearch-logfeeder-$USER.pid
-fi
-
-if [ "$LOGFEEDER_CONF_DIR" = "" ]; then
-  LOGFEEDER_CONF_DIR="/etc/logfeeder/conf"
-  if [ ! -d $LOGFEEDER_CONF_DIR ]; then
-    if [ -d $script_dir/classes ]; then
-      LOGFEEDER_CONF_DIR=$script_dir/classes
-    fi
-  fi
-fi
-
-LOGFEEDER_DEBUG_SUSPEND=${LOGFEEDER_DEBUG_SUSPEND:-n}
-if [ "$LOGFEEDER_DEBUG" = "true" ] && [ ! -z "$LOGFEEDER_DEBUG_PORT" ]; then
-  LOGFEEDER_JAVA_OPTS="$LOGFEEDER_JAVA_OPTS -Xdebug -Xrunjdwp:transport=dt_socket,address=$LOGFEEDER_DEBUG_PORT,server=y,suspend=$LOGFEEDER_DEBUG_SUSPEND "
-fi
-
-LOGFEEDER_GC_LOGFILE=`dirname $LOGFILE`/logfeeder_gc.log
-LOGFEEDER_GC_OPTS="-XX:+PrintGCDetails -XX:+PrintGCDateStamps -Xloggc:$LOGFEEDER_GC_LOGFILE"
-
-#JMX="-Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.ssl=false -Dcom.sun.management.jmxremote.authenticate=false -Dcom.sun.management.jmxremote.port=2098"
-
-if [ "$LOGFEEDER_SSL" = "true" ]; then
-  LOGFEEDER_JAVA_OPTS="$LOGFEEDER_JAVA_OPTS -Djavax.net.ssl.keyStore=$LOGFEEDER_KEYSTORE_LOCATION -Djavax.net.ssl.keyStoreType=$LOGFEEDER_KEYSTORE_TYPE -Djavax.net.ssl.trustStore=$LOGFEEDER_TRUSTSTORE_LOCATION -Djavax.net.ssl.trustStoreType=$LOGFEEDER_TRUSTSTORE_TYPE"
-fi
-
-if [ $foreground -eq 0 ]; then
-  if [ -f ${PID_FILE} ]; then
-  PID=`cat ${PID_FILE}`
-    if kill -0 $PID 2>/dev/null; then
-      echo "logfeeder already running (${PID}) killing..."
-      kill $PID 2>/dev/null
-      sleep 5
-      if kill -0 $PID 2>/dev/null; then
-        echo "logfeeder still running. Will kill process forcefully in another 10 seconds..."
-        sleep 10
-        kill -9 $PID 2>/dev/null
-        sleep 2
-      fi
-    fi
-
-    if kill -0 $PID 2>/dev/null; then
-      echo "ERROR: Even after all efforts to stop logfeeder, it is still running. pid=$PID. Please manually kill the service and try again."
-      exit 1
-    fi
-  fi
-
-  echo "Starting logfeeder. Output file=$LOGFILE pid_file=$PID_FILE"
-  #LOGFEEDER_CLI_CLASSPATH=set -x
-nohup $JAVA -cp "$LOGFEEDER_CLI_CLASSPATH:$LOGFEEDER_CONF_DIR:$script_dir/libs/*:$script_dir/classes" $LOGFEEDER_GC_OPTS $LOGFEEDER_JAVA_MEM $LOGFEEDER_JAVA_OPTS $JMX org.apache.ambari.logfeeder.LogFeeder --monitor $* > $LOGFILE 2>&1 &
-  echo $! > $PID_FILE
-else
-$JAVA -cp "$LOGFEEDER_CLI_CLASSPATH:$LOGFEEDER_CONF_DIR:$script_dir/libs/*:$script_dir/classes" $LOGFEEDER_JAVA_MEM $LOGFEEDER_JAVA_OPTS $JMX org.apache.ambari.logfeeder.LogFeeder --monitor $*
-fi
-

http://git-wip-us.apache.org/repos/asf/ambari/blob/562795c4/ambari-logsearch/ambari-logsearch-server/README.md
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-server/README.md b/ambari-logsearch/ambari-logsearch-server/README.md
index 26b1f73..7432344 100644
--- a/ambari-logsearch/ambari-logsearch-server/README.md
+++ b/ambari-logsearch/ambari-logsearch-server/README.md
@@ -33,7 +33,7 @@ Then you can start Log Search server from maven
 cd ambari/ambari-logsearch/ambari-logsearch-server
 ./run.sh
 # or
-mvn clean spring-boot:run
+mvn clean package -DskipTests spring-boot:run
 ```
 
 You can also start Log Search server from an IDE as well. One thing is important: the config set location that the server tries to upload to ZooKeeper. By default config sets are located at `${LOGSEARCH_SERVER_RELATIVE_LOCATION:}src/main/configsets` in `logsearch.properties`. Based or from where you run `LogSearch.java`, you need to set `LOGSEARCH_SERVER_RELATIVE_LOCATION` env variable properly. 

http://git-wip-us.apache.org/repos/asf/ambari/blob/562795c4/ambari-logsearch/ambari-logsearch-server/build.xml
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-server/build.xml b/ambari-logsearch/ambari-logsearch-server/build.xml
index 5c50485..c711fe1 100644
--- a/ambari-logsearch/ambari-logsearch-server/build.xml
+++ b/ambari-logsearch/ambari-logsearch-server/build.xml
@@ -19,9 +19,8 @@
   <property environment="env"/>
   <property name="debuglevel" value="source,lines,vars"/>
   <dirname property="builddir" file="build.xml"/>
-  <property name="target" value="1.7"/>
-  <property name="source" value="1.7"/>
-  <property file="build.properties"/>
+  <property name="target" value="1.8"/>
+  <property name="source" value="1.8"/>
 
   <target name="init">
   </target>
@@ -31,20 +30,34 @@
     <delete dir="target/package"/>
     <copy todir="target/package/libs" includeEmptyDirs="no">
       <fileset dir="target/libs"/>
+      <fileset file="target/ambari-logsearch-server*.jar"/>
     </copy>
     <copy todir="target/classes/static" includeEmptyDirs="no">
       <fileset dir="target/dist"/>
     </copy>
-    <copy todir="target/package/classes" includeEmptyDirs="no">
-      <fileset dir="target/classes"/>
+    <copy todir="target/package/webapp/static" includeEmptyDirs="no">
+      <fileset dir="target/classes/static"/>
     </copy>
-    <copy todir="target/package/solr_configsets" includeEmptyDirs="yes">
+    <copy todir="target/package/webapp/swagger" includeEmptyDirs="no">
+      <fileset dir="target/classes/swagger"/>
+    </copy>
+    <copy todir="target/package/conf" includeEmptyDirs="no">
+      <fileset file="src/main/scripts/logsearch-env.sh"/>
+      <fileset file="target/classes/log4j.xml"/>
+      <fileset file="target/classes/default.properties"/>
+      <fileset file="target/classes/logsearch.properties"/>
+      <fileset file="target/classes/info.properties"/>
+      <fileset file="target/classes/user_pass.json"/>
+      <fileset file="target/classes/HadoopServiceConfig.json"/>
+    </copy>
+    <copy todir="target/package/conf/solr_configsets" includeEmptyDirs="yes">
       <fileset dir="src/main/configsets"/>
     </copy>
-    <copy todir="target/package" includeEmptyDirs="no">
-      <fileset file="src/main/scripts/*"/>
+    <copy todir="target/package/bin" includeEmptyDirs="no">
+      <fileset file="src/main/scripts/logsearch.sh"/>
     </copy>
-    <chmod file="target/package/*.sh" perm="755"/>
+    <chmod file="target/package/bin/logsearch.sh" perm="755"/>
+    <chmod file="target/package/conf/logsearch-env.sh" perm="755"/>
     <tar compression="gzip" destfile="target/ambari-logsearch-portal.tar.gz">
       <tarfileset mode="755" dir="target/package">
         <include name="*.sh"/>
@@ -53,10 +66,5 @@
         <exclude name="*.sh"/>
       </tarfileset>
     </tar>
-
   </target>
-
-
-  <target description="Build all projects which reference this project. Useful to propagate changes."
-          name="build-refprojects"/>
 </project>

http://git-wip-us.apache.org/repos/asf/ambari/blob/562795c4/ambari-logsearch/ambari-logsearch-server/pom.xml
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-server/pom.xml b/ambari-logsearch/ambari-logsearch-server/pom.xml
index 5444b00..6a7debf 100755
--- a/ambari-logsearch/ambari-logsearch-server/pom.xml
+++ b/ambari-logsearch/ambari-logsearch-server/pom.xml
@@ -44,7 +44,6 @@
         <activeByDefault>true</activeByDefault>
       </activation>
       <build>
-        <finalName>LogSearch</finalName>
         <resources>
           <resource>
             <directory>src/main/resources</directory>
@@ -77,16 +76,6 @@
             <groupId>org.springframework.boot</groupId>
             <artifactId>spring-boot-maven-plugin</artifactId>
             <version>${spring-boot.version}</version>
-            <configuration>
-              <classifier>exec</classifier>
-            </configuration>
-            <executions>
-              <execution>
-                <goals>
-                  <goal>repackage</goal>
-                </goals>
-              </execution>
-            </executions>
           </plugin>
           <plugin>
             <groupId>org.apache.maven.plugins</groupId>

http://git-wip-us.apache.org/repos/asf/ambari/blob/562795c4/ambari-logsearch/ambari-logsearch-server/run.sh
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-server/run.sh b/ambari-logsearch/ambari-logsearch-server/run.sh
index f245930..2de0536 100755
--- a/ambari-logsearch/ambari-logsearch-server/run.sh
+++ b/ambari-logsearch/ambari-logsearch-server/run.sh
@@ -17,4 +17,4 @@ echo "
 ███████╗╚██████╔╝╚██████╔╝    ███████║███████╗██║  ██║██║  ██║╚██████╗██║  ██║
 ╚══════╝ ╚═════╝  ╚═════╝     ╚══════╝╚══════╝╚═╝  ╚═╝╚═╝  ╚═╝ ╚═════╝╚═╝  ╚═╝
 "
-mvn clean spring-boot:run
+mvn clean package -DskipTests spring-boot:run

http://git-wip-us.apache.org/repos/asf/ambari/blob/562795c4/ambari-logsearch/ambari-logsearch-server/src/main/java/org/apache/ambari/logsearch/LogSearch.java
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-server/src/main/java/org/apache/ambari/logsearch/LogSearch.java b/ambari-logsearch/ambari-logsearch-server/src/main/java/org/apache/ambari/logsearch/LogSearch.java
index 39343c7..45cda0a 100644
--- a/ambari-logsearch/ambari-logsearch-server/src/main/java/org/apache/ambari/logsearch/LogSearch.java
+++ b/ambari-logsearch/ambari-logsearch-server/src/main/java/org/apache/ambari/logsearch/LogSearch.java
@@ -36,7 +36,7 @@ public class LogSearch {
 
   public static void main(String[] args) {
 
-    String pidFile = System.getenv("PID_FILE") == null ? "logsearch.pid" : System.getenv("PID_FILE");
+    String pidFile = System.getenv("LOGSEARCH_PID_FILE") == null ? "logsearch.pid" : System.getenv("LOGSEARCH_PID_FILE");
     new SpringApplicationBuilder(LogSearch.class)
       .bannerMode(Banner.Mode.OFF)
       .listeners(new ApplicationPidFileWriter(pidFile))

http://git-wip-us.apache.org/repos/asf/ambari/blob/562795c4/ambari-logsearch/ambari-logsearch-server/src/main/scripts/logsearch-env.sh
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-server/src/main/scripts/logsearch-env.sh b/ambari-logsearch/ambari-logsearch-server/src/main/scripts/logsearch-env.sh
new file mode 100755
index 0000000..d8a837f
--- /dev/null
+++ b/ambari-logsearch/ambari-logsearch-server/src/main/scripts/logsearch-env.sh
@@ -0,0 +1,40 @@
+#!/bin/bash
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements.  See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You 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.
+
+# Log Search extra options
+export LOGSEARCH_JAVA_OPTS=${LOGSEARCH_JAVA_OPTS:-""}
+
+# Log Search debug options
+# export LOGSEARCH_DEBUG=true
+# exoprt LOGSEARCH_DEBUG_SUSPEND=n
+export LOGSEARCH_DEBUG_PORT=5005
+
+# Log Search memory
+# export LOGSEARCH_JAVA_MEM="--Xmx1024m"
+
+# export LOG_PATH=/var/log/ambari-logsearch-logfeeder/
+# export LOG_FILE=logsearch.log
+
+# Pid file of the application
+# export LOGSEARCH_PID_DIR=/var/run/ambari-logsearch-logfeeder
+# export LOGSEARCH_PID_FILE=logfeeder.pid
+
+# SSL settings"
+# export LOGSEARCH_SSL="true"
+# export LOGSEARCH_KEYSTORE_LOCATION="/my/path/keystore.jks"
+# export LOGSEARCH_KEYSTORE_TYPE="jks"
+# export LOGSEARCH_TRUSTSTORE_LOCATION="/my/path/trutstore.jks"
+# export LOGSEARCH_TRUSTSTORE_TYPE="jks"
\ No newline at end of file


[17/24] ambari git commit: AMBARI-22670 Ambari 3.0: Implement new design for Admin View: Integrate visual-search box. (atkach)

Posted by nc...@apache.org.
AMBARI-22670 Ambari 3.0: Implement new design for Admin View: Integrate visual-search box. (atkach)


Project: http://git-wip-us.apache.org/repos/asf/ambari/repo
Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/30d89a33
Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/30d89a33
Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/30d89a33

Branch: refs/heads/branch-feature-AMBARI-21674
Commit: 30d89a3306dddf24fb2206ff22bc85c40458debd
Parents: 90554f3
Author: Andrii Tkach <at...@apache.org>
Authored: Tue Dec 19 14:53:08 2017 +0200
Committer: Andrii Tkach <at...@apache.org>
Committed: Tue Dec 19 14:53:08 2017 +0200

----------------------------------------------------------------------
 .../main/resources/ui/admin-web/app/index.html  |   1 +
 .../controllers/ambariViews/ViewsListCtrl.js    | 104 +++--
 .../remoteClusters/RemoteClustersListCtrl.js    |   3 +-
 .../stackVersions/StackVersionsListCtrl.js      |   1 +
 .../app/scripts/directives/comboSearch.js       | 455 +++++++++++++++++++
 .../ui/admin-web/app/styles/combo-search.css    | 164 +++++++
 .../resources/ui/admin-web/app/styles/main.css  |  36 ++
 .../app/views/ambariViews/viewsList.html        |  45 +-
 .../app/views/directives/comboSearch.html       |  63 +++
 .../app/views/remoteClusters/list.html          |   2 +-
 .../admin-web/app/views/stackVersions/list.html |   2 +-
 .../ambariViews/ViewsListCtrl_test.js           | 167 +++++++
 .../test/unit/directives/comboSearch_test.js    | 242 ++++++++++
 13 files changed, 1201 insertions(+), 84 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ambari/blob/30d89a33/ambari-admin/src/main/resources/ui/admin-web/app/index.html
----------------------------------------------------------------------
diff --git a/ambari-admin/src/main/resources/ui/admin-web/app/index.html b/ambari-admin/src/main/resources/ui/admin-web/app/index.html
index bf033e6..a1346ed 100644
--- a/ambari-admin/src/main/resources/ui/admin-web/app/index.html
+++ b/ambari-admin/src/main/resources/ui/admin-web/app/index.html
@@ -150,6 +150,7 @@
 <script src="scripts/directives/PasswordVerify.js"></script>
 <script src="scripts/directives/disabledTooltip.js"></script>
 <script src="scripts/directives/editableList.js"></script>
+<script src="scripts/directives/comboSearch.js"></script>
 <script src="scripts/services/Utility.js"></script>
 <script src="scripts/services/UserConstants.js"></script>
 <script src="scripts/services/User.js"></script>

http://git-wip-us.apache.org/repos/asf/ambari/blob/30d89a33/ambari-admin/src/main/resources/ui/admin-web/app/scripts/controllers/ambariViews/ViewsListCtrl.js
----------------------------------------------------------------------
diff --git a/ambari-admin/src/main/resources/ui/admin-web/app/scripts/controllers/ambariViews/ViewsListCtrl.js b/ambari-admin/src/main/resources/ui/admin-web/app/scripts/controllers/ambariViews/ViewsListCtrl.js
index 8b37dca..8c61a25 100644
--- a/ambari-admin/src/main/resources/ui/admin-web/app/scripts/controllers/ambariViews/ViewsListCtrl.js
+++ b/ambari-admin/src/main/resources/ui/admin-web/app/scripts/controllers/ambariViews/ViewsListCtrl.js
@@ -24,6 +24,29 @@ angular.module('ambariAdminConsole')
   $scope.isLoading = false;
   $scope.minInstanceForPagination = Settings.minRowsToShowPagination;
 
+  $scope.filters = [
+    {
+      key: 'short_url_name',
+      label: $t('common.name'),
+      options: []
+    },
+    {
+      key: 'url',
+      label: $t('urls.url'),
+      options: []
+    },
+    {
+      key: 'view_name',
+      label: $t('views.table.viewType'),
+      options: []
+    },
+    {
+      key: 'instance_name',
+      label: $t('urls.viewInstance'),
+      options: []
+    }
+  ];
+
   function checkViewVersionStatus(view, versionObj, versionNumber) {
     var deferred = View.checkViewVersionStatus(view.view_name, versionNumber);
 
@@ -66,27 +89,13 @@ angular.module('ambariAdminConsole')
           $scope.instances.push(instance.ViewInstanceInfo);
         });
       });
-      initTypeFilter();
+      $scope.initFilterOptions();
       $scope.filterInstances();
     }).catch(function (data) {
       Alert.error($t('views.alerts.cannotLoadViews'), data.data.message);
     });
   }
 
-  function initTypeFilter() {
-    var uniqTypes = $.unique($scope.instances.map(function(instance) {
-      return instance.view_name;
-    }));
-    $scope.typeFilterOptions = [ { label: $t('common.all'), value: '*'} ]
-      .concat(uniqTypes.map(function(type) {
-        return {
-          label: type,
-          value: type
-        };
-      }));
-    $scope.instanceTypeFilter = $scope.typeFilterOptions[0];
-  }
-
   function showInstancesOnPage() {
     var startIndex = ($scope.currentPage - 1) * $scope.instancesPerPage + 1;
     var endIndex = $scope.currentPage * $scope.instancesPerPage;
@@ -110,11 +119,7 @@ angular.module('ambariAdminConsole')
   $scope.instances = [];
   $scope.instancesPerPage = 10;
   $scope.currentPage = 1;
-  $scope.instanceNameFilter = '';
-  $scope.instanceUrlFilter = '';
   $scope.maxVisiblePages = 10;
-  $scope.isNotEmptyFilter = true;
-  $scope.instanceTypeFilter = '';
   $scope.tableInfo = {
     filtered: 0,
     showed: 0
@@ -122,25 +127,46 @@ angular.module('ambariAdminConsole')
 
   loadViews();
 
-  $scope.filterInstances = function() {
+  $scope.initFilterOptions = function() {
+    $scope.filters.forEach(function(filter) {
+      filter.options = $.unique($scope.instances.map(function(instance) {
+        if (filter.key === 'url') {
+          return '/main/view/' + instance.view_name + '/' + instance.short_url;
+        }
+        return instance[filter.key];
+      })).map(function(item) {
+        return {
+          key: item,
+          label: item
+        }
+      });
+    });
+  };
+
+  $scope.filterInstances = function(appliedFilters) {
     var filteredCount = 0;
     angular.forEach($scope.instances, function(instance) {
-      if ($scope.instanceNameFilter && instance.short_url_name.indexOf($scope.instanceNameFilter) === -1) {
-        return instance.isFiltered = false;
-      }
-      if ($scope.instanceUrlFilter && ('/main/view/'+ instance.view_name + '/' + instance.short_url).indexOf($scope.instanceUrlFilter) === -1) {
-        return instance.isFiltered = false;
-      }
-      if ($scope.instanceTypeFilter.value !== '*' && instance.view_name.indexOf($scope.instanceTypeFilter.value) === -1) {
-        return instance.isFiltered = false;
-      }
-      filteredCount++;
-      instance.isFiltered = true;
+      instance.isFiltered = !(appliedFilters && appliedFilters.length > 0 && appliedFilters.some(function(filter) {
+        if (filter.key === 'url') {
+          return filter.values.every(function(value) {
+            return ('/main/view/' + instance.view_name + '/' + instance.short_url).indexOf(value) === -1;
+          });
+        }
+        return filter.values.every(function(value) {
+          return instance[filter.key].indexOf(value) === -1;
+        });
+      }));
+
+      filteredCount += ~~instance.isFiltered;
     });
     $scope.tableInfo.filtered = filteredCount;
     $scope.resetPagination();
   };
 
+  $scope.toggleSearchBox = function() {
+    $('.search-box-button .popup-arrow-up, .search-box-row').toggleClass('hide');
+  };
+
   $scope.pageChanged = function() {
     showInstancesOnPage();
   };
@@ -150,22 +176,6 @@ angular.module('ambariAdminConsole')
     showInstancesOnPage();
   };
 
-  $scope.clearFilters = function () {
-    $scope.instanceNameFilter = '';
-    $scope.instanceUrlFilter = '';
-    $scope.instanceTypeFilter = $scope.typeFilterOptions[0];
-    $scope.resetPagination();
-  };
-
-  $scope.$watch(
-    function (scope) {
-      return Boolean(scope.instanceNameFilter || scope.instanceUrlFilter || (scope.instanceTypeFilter && scope.instanceTypeFilter.value !== '*'));
-    },
-    function (newValue, oldValue, scope) {
-      scope.isNotEmptyFilter = newValue;
-    }
-  );
-
   $scope.cloneInstance = function(instanceClone) {
     $scope.createInstance(instanceClone);
   };

http://git-wip-us.apache.org/repos/asf/ambari/blob/30d89a33/ambari-admin/src/main/resources/ui/admin-web/app/scripts/controllers/remoteClusters/RemoteClustersListCtrl.js
----------------------------------------------------------------------
diff --git a/ambari-admin/src/main/resources/ui/admin-web/app/scripts/controllers/remoteClusters/RemoteClustersListCtrl.js b/ambari-admin/src/main/resources/ui/admin-web/app/scripts/controllers/remoteClusters/RemoteClustersListCtrl.js
index 9d47307..4726357 100644
--- a/ambari-admin/src/main/resources/ui/admin-web/app/scripts/controllers/remoteClusters/RemoteClustersListCtrl.js
+++ b/ambari-admin/src/main/resources/ui/admin-web/app/scripts/controllers/remoteClusters/RemoteClustersListCtrl.js
@@ -18,9 +18,10 @@
 'use strict';
 
 angular.module('ambariAdminConsole')
-.controller('RemoteClustersListCtrl', ['$scope', '$routeParams', '$translate', 'RemoteCluster', function ($scope, $routeParams, $translate, RemoteCluster) {
+.controller('RemoteClustersListCtrl', ['$scope', '$routeParams', '$translate', 'RemoteCluster', 'Settings', function ($scope, $routeParams, $translate, RemoteCluster, Settings) {
   var $t = $translate.instant;
 
+  $scope.minInstanceForPagination = Settings.minRowsToShowPagination;
   $scope.clusterName = $routeParams.clusterName;
   $scope.isLoading = false;
 

http://git-wip-us.apache.org/repos/asf/ambari/blob/30d89a33/ambari-admin/src/main/resources/ui/admin-web/app/scripts/controllers/stackVersions/StackVersionsListCtrl.js
----------------------------------------------------------------------
diff --git a/ambari-admin/src/main/resources/ui/admin-web/app/scripts/controllers/stackVersions/StackVersionsListCtrl.js b/ambari-admin/src/main/resources/ui/admin-web/app/scripts/controllers/stackVersions/StackVersionsListCtrl.js
index 003d472..ae00978 100644
--- a/ambari-admin/src/main/resources/ui/admin-web/app/scripts/controllers/stackVersions/StackVersionsListCtrl.js
+++ b/ambari-admin/src/main/resources/ui/admin-web/app/scripts/controllers/stackVersions/StackVersionsListCtrl.js
@@ -23,6 +23,7 @@ angular.module('ambariAdminConsole')
     $scope.getConstant = function (key) {
       return $t(key).toLowerCase();
     };
+    $scope.minInstanceForPagination = Settings.minRowsToShowPagination;
     $scope.isLoading = false;
     $scope.clusterName = $routeParams.clusterName;
     $scope.filter = {

http://git-wip-us.apache.org/repos/asf/ambari/blob/30d89a33/ambari-admin/src/main/resources/ui/admin-web/app/scripts/directives/comboSearch.js
----------------------------------------------------------------------
diff --git a/ambari-admin/src/main/resources/ui/admin-web/app/scripts/directives/comboSearch.js b/ambari-admin/src/main/resources/ui/admin-web/app/scripts/directives/comboSearch.js
new file mode 100644
index 0000000..af25167
--- /dev/null
+++ b/ambari-admin/src/main/resources/ui/admin-web/app/scripts/directives/comboSearch.js
@@ -0,0 +1,455 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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.
+ */
+'use strict';
+
+angular.module('ambariAdminConsole')
+.directive('comboSearch', function() {
+  return {
+    restrict: 'E',
+    templateUrl: 'views/directives/comboSearch.html',
+    scope: {
+      suggestions: '=',
+      filterChange: '=',
+      placeholder: '@',
+      supportCategories: '@'
+    },
+    controller: ['$scope', function($scope) {
+      return {
+        suggestions: $scope.suggestions,
+        placeholder: $scope.placeholder,
+        filterChange: $scope.filterChange,
+        supportCategories: $scope.supportCategories === "true"
+      }
+    }],
+    link: function($scope, $elem, $attr, $ctrl) {
+      var idCounter = 1;
+      var suggestions = $ctrl.suggestions;
+      var supportCategories = $ctrl.supportCategories;
+      var mainInputElement = $elem.find('.main-input.combo-search-input');
+      $scope.paceholder = $ctrl.placeholder;
+      $scope.searchFilterInput = '';
+      $scope.filterSuggestions = [];
+      $scope.showAutoComplete = false;
+      $scope.appliedFilters = [];
+
+      attachInputWidthSetter(mainInputElement);
+      initKeyHandlers();
+      initBlurHandler();
+
+      $scope.$watch(function () {
+        return $scope.appliedFilters.length;
+      }, function () {
+        attachInputWidthSetter($elem.find('.combo-search-input'));
+      });
+
+      $scope.removeFilter = function(filter) {
+        $scope.appliedFilters = $scope.appliedFilters.filter(function(item) {
+          return filter.id !== item.id;
+        });
+        $scope.observeSearchFilterInput(event);
+        mainInputElement.focus();
+        $scope.updateFilters($scope.appliedFilters);
+      };
+
+      $scope.clearFilters = function() {
+        $scope.appliedFilters = [];
+        $scope.updateFilters($scope.appliedFilters);
+      };
+
+      $scope.selectFilter = function(filter, event) {
+        var newAppliedFilter = {
+          id: 'filter_' + idCounter++,
+          currentOption: null,
+          filteredOptions: [],
+          searchOptionInput: '',
+          key: filter.key,
+          label: filter.label,
+          options: filter.options || [],
+          showAutoComplete: false
+        };
+        $scope.appliedFilters.push(newAppliedFilter);
+        if (event) {
+          event.stopPropagation();
+          event.preventDefault();
+        }
+        $scope.isEditing = false;
+        $scope.showAutoComplete = false;
+        $scope.searchFilterInput = '';
+        _.debounce(function() {
+          $('input[name=' + newAppliedFilter.id + ']').focus().width(4);
+        }, 100)();
+      };
+
+      $scope.selectOption = function(event, option, filter) {
+        $('input[name=' + filter.id + ']').val(option.label).trigger('input');
+        filter.showAutoComplete = false;
+        mainInputElement.focus();
+        $scope.observeSearchFilterInput(event);
+        filter.currentOption = option;
+        $scope.updateFilters($scope.appliedFilters);
+      };
+
+      $scope.hideAutocomplete = function(filter) {
+        _.debounce(function() {
+          if (filter) {
+            filter.showAutoComplete = false;
+          } else {
+            if (!$scope.isEditing) {
+              $scope.showAutoComplete = false;
+            }
+          }
+          $scope.$apply();
+        }, 100)();
+      };
+
+      $scope.forceFocus = function(event, filter) {
+        $(event.currentTarget).find('.combo-search-input').focus();
+        $scope.showAutoComplete = false;
+        $scope.observeSearchOptionInput(filter);
+        event.stopPropagation();
+        event.preventDefault();
+      };
+
+      $scope.makeActive = function(active, all) {
+        if (active.isCategory) {
+          return false;
+        }
+        all.forEach(function(item) {
+          item.active = active.key === item.key;
+        });
+      };
+
+      $scope.observeSearchFilterInput = function(event) {
+        if (event) {
+          mainInputElement.focus();
+          $scope.isEditing = true;
+          event.stopPropagation();
+          event.preventDefault();
+        }
+
+        var filteredSuggestions = suggestions.filter(function(item) {
+          return (!$scope.searchFilterInput || item.label.toLowerCase().indexOf($scope.searchFilterInput.toLowerCase()) !== -1);
+        });
+        if (filteredSuggestions.length > 0) {
+          $scope.makeActive(filteredSuggestions[0], filteredSuggestions);
+          $scope.showAutoComplete = true;
+        } else {
+          $scope.showAutoComplete = false;
+        }
+        $scope.filterSuggestions = supportCategories ? formatCategorySuggestions(filteredSuggestions) : filteredSuggestions;
+      };
+
+      $scope.observeSearchOptionInput = function(filter) {
+        var appliedOptions = {};
+        $scope.appliedFilters.forEach(function(item) {
+          if (item.key === filter.key && item.currentOption) {
+            appliedOptions[item.currentOption.key] = true;
+          }
+        });
+
+        if (filter.currentOption && filter.currentOption.key !== filter.searchOptionInput) {
+          filter.currentOption = null;
+        }
+        filter.filteredOptions = filter.options.filter(function(option) {
+          return !(option.key === '' || option.key === undefined || appliedOptions[option.key])
+            && (!filter.searchOptionInput || option.label.toLowerCase().indexOf(filter.searchOptionInput.toLowerCase()) !== -1);
+        });
+        filter.showAutoComplete = filter.filteredOptions.length > 0;
+        if (filter.filteredOptions.length > 0) {
+          $scope.makeActive(filter.filteredOptions[0], filter.filteredOptions);
+        }
+      };
+
+      $scope.extractFilters = function(filters) {
+        var map = {};
+        var result = [];
+
+        filters.forEach(function(filter) {
+          if (filter.currentOption) {
+            if (!map[filter.key]) {
+              map[filter.key] = [];
+            }
+            map[filter.key].push(filter.currentOption.key);
+          }
+        });
+        for(var key in map) {
+          result.push({
+            key: key,
+            values: map[key]
+          });
+        }
+        return result;
+      };
+
+      $scope.updateFilters = function(appliedFilters) {
+        $ctrl.filterChange($scope.extractFilters(appliedFilters));
+      };
+
+      function formatCategorySuggestions(suggestions) {
+        var categories = {};
+        var result = [];
+        suggestions.forEach(function(item) {
+          if (!item.category) {
+            item.category = 'default';
+          }
+          if (!categories[item.category]) {
+            categories[item.category] = [];
+          }
+          categories[item.category].push(item);
+        });
+
+        for(var cat in categories) {
+          result.push({
+            key: cat,
+            label: cat,
+            isCategory: true,
+            isDefault: cat === 'default'
+          });
+          result = result.concat(categories[cat]);
+        }
+        return result;
+      }
+
+      function initBlurHandler() {
+        $(document).click(function() {
+          $scope.isEditing = false;
+          $scope.hideAutocomplete();
+        });
+      }
+
+      function findActiveByName(array, name) {
+        for (var i = 0; i < array.length; i++) {
+          if (array[i].id === name) {
+            return i;
+          }
+        }
+        return null;
+      }
+
+      function findActiveByProperty(array) {
+        for (var i = 0; i < array.length; i++) {
+          if (array[i].active) {
+            return i;
+          }
+        }
+        return 0;
+      }
+
+      function focusInput(filter) {
+        $('input[name=' + filter.id + ']').focus();
+        $scope.showAutoComplete = false;
+        $scope.observeSearchOptionInput(filter);
+      }
+
+      function initKeyHandlers() {
+        $(document).keydown(function(event) {
+          if (event.which === 13) { // "Enter" key
+            enterKeyHandler();
+            $scope.$apply();
+          }
+          if (event.which === 8) { // "Backspace" key
+            backspaceKeyHandler(event);
+            $scope.$apply();
+          }
+          if (event.which === 38) { // "Up" key
+            upKeyHandler();
+            $scope.$apply();
+          }
+          if (event.which === 40) { // "Down" key
+            downKeyHandler();
+            $scope.$apply();
+          }
+          if (event.which === 39) { // "Right Arrow" key
+            rightArrowKeyHandler();
+            $scope.$apply();
+          }
+          if (event.which === 37) { // "Left Arrow" key
+            leftArrowKeyHandler();
+            $scope.$apply();
+          }
+        });
+      }
+
+      function leftArrowKeyHandler() {
+        var activeElement = $(document.activeElement);
+        if (activeElement.is('input') && activeElement[0].selectionStart === 0) {
+          if (activeElement.hasClass('main-input')) {
+            focusInput($scope.appliedFilters[$scope.appliedFilters.length - 1]);
+          } else {
+            var activeIndex = findActiveByName($scope.appliedFilters, activeElement.attr('name'));
+            if (activeIndex !== null && activeIndex > 0) {
+              focusInput($scope.appliedFilters[activeIndex - 1]);
+            }
+          }
+        }
+      }
+
+      function rightArrowKeyHandler() {
+        var activeElement = $(document.activeElement);
+        if (activeElement.is('input') && activeElement[0].selectionStart === activeElement.val().length) {
+          if (!activeElement.hasClass('main-input')) {
+            var activeIndex = findActiveByName($scope.appliedFilters, activeElement.attr('name'));
+            if (activeIndex !== null) {
+              if (activeIndex === $scope.appliedFilters.length - 1) {
+                mainInputElement.focus();
+                $scope.observeSearchFilterInput();
+              } else {
+                focusInput($scope.appliedFilters[activeIndex + 1]);
+              }
+            }
+          }
+        }
+      }
+
+      function downKeyHandler() {
+        var activeIndex = 0;
+        var nextIndex = null;
+
+        if ($scope.showAutoComplete) {
+          activeIndex = findActiveByProperty($scope.filterSuggestions);
+          if (activeIndex < $scope.filterSuggestions.length - 1) {
+            if ($scope.filterSuggestions[activeIndex + 1].isCategory && activeIndex + 2 < $scope.filterSuggestions.length) {
+              nextIndex = activeIndex + 2;
+            } else {
+              nextIndex = activeIndex + 1;
+            }
+          } else {
+            nextIndex = ($scope.filterSuggestions[0].isCategory) ? 1 : 0;
+          }
+          if (nextIndex !== null) {
+            $scope.makeActive($scope.filterSuggestions[nextIndex], $scope.filterSuggestions);
+          }
+        } else {
+          var activeAppliedFilters = $scope.appliedFilters.filter(function(item) {
+            return item.showAutoComplete;
+          });
+          if (activeAppliedFilters.length > 0) {
+            var filteredOptions = activeAppliedFilters[0].filteredOptions;
+            activeIndex = findActiveByProperty(filteredOptions);
+            nextIndex = (activeIndex < filteredOptions.length - 1) ? activeIndex + 1 : 0;
+          }
+          if (nextIndex !== null) {
+            $scope.makeActive(filteredOptions[nextIndex], filteredOptions);
+          }
+        }
+      }
+
+      function upKeyHandler() {
+        var activeIndex = 0;
+        var nextIndex = null;
+
+        if ($scope.showAutoComplete) {
+          activeIndex = findActiveByProperty($scope.filterSuggestions);
+          if (activeIndex > 0) {
+            if ($scope.filterSuggestions[activeIndex - 1].isCategory) {
+              nextIndex = (activeIndex - 2 > 0) ? activeIndex - 2 : $scope.filterSuggestions.length - 1;
+            } else {
+              nextIndex = activeIndex - 1;
+            }
+          } else {
+            nextIndex = $scope.filterSuggestions.length - 1;
+          }
+          if (nextIndex !== null) {
+            $scope.makeActive($scope.filterSuggestions[nextIndex], $scope.filterSuggestions);
+          }
+        } else {
+          var activeAppliedFilters = $scope.appliedFilters.filter(function(item) {
+            return item.showAutoComplete;
+          });
+          if (activeAppliedFilters.length > 0) {
+            var filteredOptions = activeAppliedFilters[0].filteredOptions;
+            activeIndex = findActiveByProperty(filteredOptions);
+            nextIndex = (activeIndex > 0) ?  activeIndex - 1 : filteredOptions.length - 1;
+          }
+          if (nextIndex !== null) {
+            $scope.makeActive(filteredOptions[nextIndex], filteredOptions);
+          }
+        }
+      }
+
+      function enterKeyHandler() {
+        if ($scope.showAutoComplete) {
+          var activeFilters = $scope.filterSuggestions.filter(function(item) {
+            return item.active;
+          });
+          if (activeFilters.length > 0) {
+            $scope.selectFilter(activeFilters[0]);
+          }
+        } else {
+          var activeAppliedFilters = $scope.appliedFilters.filter(function(item) {
+            return item.showAutoComplete;
+          });
+          if (activeAppliedFilters.length > 0) {
+            var activeOptions = activeAppliedFilters[0].filteredOptions.filter(function(item) {
+              return item.active;
+            });
+            if (activeOptions.length > 0) {
+              $scope.selectOption(null, activeOptions[0], activeAppliedFilters[0]);
+            }
+          } else {
+            $scope.appliedFilters.filter(function(item) {
+              return !item.currentOption;
+            }).forEach(function(item) {
+              if (item.searchOptionInput !== '') {
+                $scope.selectOption(null, {
+                  key: item.searchOptionInput,
+                  label: item.searchOptionInput
+                }, item);
+              }
+            });
+          }
+        }
+      }
+
+      function backspaceKeyHandler (event) {
+        if ($(document.activeElement).is('input') && $(document.activeElement)[0].selectionStart === 0) {
+          if ($(document.activeElement).hasClass('main-input') && $scope.appliedFilters.length > 0) {
+            var lastFilter = $scope.appliedFilters[$scope.appliedFilters.length - 1];
+            focusInput(lastFilter);
+            event.stopPropagation();
+            event.preventDefault();
+          } else {
+            var name = $(document.activeElement).attr('name');
+            var activeFilter = $scope.appliedFilters.filter(function(item) {
+              return name === item.id;
+            })[0];
+            if (activeFilter) {
+              $scope.removeFilter(activeFilter);
+            }
+          }
+        }
+      }
+
+      function attachInputWidthSetter(element) {
+        var textPadding = 4;
+        element.on('input', function() {
+          var inputWidth = $(this).textWidth();
+          $(this).css({
+            width: inputWidth + textPadding
+          })
+        }).trigger('input');
+      }
+    }
+  };
+});
+
+$.fn.textWidth = function(text, font) {
+  if (!$.fn.textWidth.fakeEl) $.fn.textWidth.fakeEl = $('<span>').hide().appendTo(document.body);
+  $.fn.textWidth.fakeEl.text(text || this.val() || this.text() || this.attr('placeholder')).css('font', font || this.css('font'));
+  return $.fn.textWidth.fakeEl.width();
+};

http://git-wip-us.apache.org/repos/asf/ambari/blob/30d89a33/ambari-admin/src/main/resources/ui/admin-web/app/styles/combo-search.css
----------------------------------------------------------------------
diff --git a/ambari-admin/src/main/resources/ui/admin-web/app/styles/combo-search.css b/ambari-admin/src/main/resources/ui/admin-web/app/styles/combo-search.css
new file mode 100644
index 0000000..ee9909c
--- /dev/null
+++ b/ambari-admin/src/main/resources/ui/admin-web/app/styles/combo-search.css
@@ -0,0 +1,164 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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.
+ */
+
+.combo-search .combo-search-inner {
+  position: relative;
+  border: 1px solid #ccc;
+  border-radius: 4px;
+  box-shadow: 0 0 1px #fff inset;
+  min-height: 34px;
+  line-height: 1em;
+  cursor: text;
+  padding-right: 30px;
+}
+
+.combo-search .combo-search-close {
+  font-size: 13px;
+  color: #999;
+  position: absolute;
+  right: 10px;
+  top: 30%;
+  cursor: pointer;
+}
+.combo-search .combo-search-close:hover {
+  color: #333;
+}
+.combo-search .combo-search-input {
+  background: transparent;
+  display: inline-block;
+  min-width: 4px;
+  width: 4px;
+  line-height: 10px;
+  height: 100%;
+  border: none;
+  outline: none;
+  margin-left: 1px;
+}
+
+.combo-search .combo-search-input-wrapper {
+  display: inline-block;
+  position: relative;
+  height: 32px;
+  margin-left: 5px;
+}
+
+.combo-search .combo-search-content {
+  display: inline-block;
+}
+
+.combo-search .combo-search-dropdown {
+  position: absolute;
+  border: 1px solid #ccc;
+  border-radius: 4px;
+  background-color: #fff;
+  cursor: pointer;
+  z-index: 10;
+  padding: 0;
+  margin: 0;
+  width: auto;
+  min-width: 80px;
+  max-width: 220px;
+  max-height: 240px;
+  overflow-y: auto;
+  overflow-x: hidden;
+  font-size: 13px;
+  top: 30px;
+  left: 5px;
+  box-shadow: 3px 4px 5px -2px rgba(0, 0, 0, 0.5);
+}
+
+.combo-search .combo-search-dropdown ul {
+  max-height: 250px;
+  list-style: none;
+  padding: 0;
+  margin: 0;
+}
+
+.combo-search .filter a {
+  display: block;
+  width: auto;
+  text-decoration: none;
+  color: initial;
+  white-space: nowrap;
+  overflow: hidden;
+  text-overflow: ellipsis;
+  background: none;
+  border: none;
+  padding: 3px 10px 5px 5px;
+}
+
+.combo-search .category a {
+  display: block;
+  width: auto;
+  text-decoration: none;
+  white-space: nowrap;
+  overflow: hidden;
+  text-overflow: ellipsis;
+  padding: 3px 10px 5px 5px;
+  text-transform: capitalize;
+  font-size: 11px;
+  font-weight: bold;
+  color: white;
+  cursor: default;
+  border-bottom: 1px solid #A2A2A2;
+  background-color: #B7B7B7;
+  text-shadow: 0 -1px 0 #999;
+}
+
+.combo-search .filter a.active {
+  background-color: #ddd;
+}
+
+.combo-search .combo-search-applied-filter {
+  position: relative;
+  display: inline-block;
+  padding: 0 3px 0 18px;
+  background-color: #dddddd;
+  border-radius: 4px;
+  margin: 4px 0 0 4px;
+  vertical-align: top;
+  border: 1px solid #d2d2d2;
+}
+
+.combo-search .combo-search-applied-filter i {
+  position: absolute;
+  left: 5px;
+  font-size: 12px;
+  top: 5px;
+  color: #999;
+  cursor: pointer;
+}
+
+.combo-search .combo-search-applied-filter i:hover {
+  color: #333;
+}
+
+.combo-search .combo-search-applied-filter span,
+.combo-search .combo-search-applied-filter input {
+  color: #666;
+  font-size: 11px;
+}
+
+.combo-search .combo-search-applied-filter span {
+  font-weight: bold;
+}
+
+.combo-search .combo-search-applied-filter .combo-search-input-wrapper {
+  height: 22px;
+  margin-left: 0;
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/ambari/blob/30d89a33/ambari-admin/src/main/resources/ui/admin-web/app/styles/main.css
----------------------------------------------------------------------
diff --git a/ambari-admin/src/main/resources/ui/admin-web/app/styles/main.css b/ambari-admin/src/main/resources/ui/admin-web/app/styles/main.css
index b4aa558..8f693a8 100644
--- a/ambari-admin/src/main/resources/ui/admin-web/app/styles/main.css
+++ b/ambari-admin/src/main/resources/ui/admin-web/app/styles/main.css
@@ -1331,3 +1331,39 @@ th.entity-actions {
 .entity-actions a:focus:hover {
   text-decoration: none;
 }
+
+.search-box-button {
+  position: relative;
+  margin-right: 5px;
+}
+
+.search-box-button .btn {
+  padding: 10px;
+}
+
+.search-box-row {
+  padding-top: 15px;
+  padding-bottom: 5px;
+}
+
+.popup-arrow-up {
+  background: inherit;
+  z-index: 1;
+  left: 6px;
+  position: absolute;
+  width: 24px;
+  height: 16px;
+  overflow: hidden;
+}
+
+.popup-arrow-up:after {
+  content: "";
+  position: absolute;
+  width: 20px;
+  height: 20px;
+  background: #fff;
+  transform: rotate(45deg);
+  top: 10px;
+  left: 2px;
+  box-shadow: -2px -2px 10px -3px rgba(0, 0, 0, 0.5);
+}

http://git-wip-us.apache.org/repos/asf/ambari/blob/30d89a33/ambari-admin/src/main/resources/ui/admin-web/app/views/ambariViews/viewsList.html
----------------------------------------------------------------------
diff --git a/ambari-admin/src/main/resources/ui/admin-web/app/views/ambariViews/viewsList.html b/ambari-admin/src/main/resources/ui/admin-web/app/views/ambariViews/viewsList.html
index ae57b86..9e9cb55 100644
--- a/ambari-admin/src/main/resources/ui/admin-web/app/views/ambariViews/viewsList.html
+++ b/ambari-admin/src/main/resources/ui/admin-web/app/views/ambariViews/viewsList.html
@@ -24,11 +24,21 @@
                 {{'views.create' | translate}}
             </button>
         </div>
+        <div class="search-box-button pull-right">
+            <button class="btn btn-default" ng-click="toggleSearchBox()">
+                <i class="fa fa-filter" aria-hidden="true"></i>
+            </button>
+            <div class="popup-arrow-up hide"></div>
+        </div>
+    </div>
+
+    <div class="search-box-row hide">
+        <combo-search suggestions="filters" filter-change="filterInstances" placeholder="Search"></combo-search>
     </div>
 
     <table class="table table-striped table-hover">
         <thead>
-        <tr class="fix-bottom">
+        <tr>
             <th class="col-md-2">
                 <span>{{'common.name' | translate}}</span>
             </th>
@@ -45,39 +55,6 @@
                 <span>{{'common.actions' | translate}}</span>
             </th>
         </tr>
-        <tr class="fix-top">
-            <th>
-                <div class="search-container">
-                    <input type="text" class="form-control" placeholder="{{'common.any' | translate}}"
-                           ng-model="instanceNameFilter" ng-change="filterInstances()">
-                    <button type="button" class="close clearfilter" ng-show="instanceNameFilter"
-                            ng-click="instanceNameFilter=''; filterInstances()">
-                        <span aria-hidden="true">&times;</span>
-                        <span class="sr-only">{{'common.controls.close' | translate}}</span>
-                    </button>
-                </div>
-            </th>
-            <th>
-                <div class="search-container">
-                    <input type="text" class="form-control" placeholder="{{'common.any' | translate}}"
-                           ng-model="instanceUrlFilter" ng-change="filterInstances()">
-                    <button type="button" class="close clearfilter" ng-show="instanceUrlFilter"
-                            ng-click="instanceUrlFilter=''; filterInstances()">
-                        <span aria-hidden="true">&times;</span>
-                        <span class="sr-only">{{'common.controls.close' | translate}}</span>
-                    </button>
-                </div>
-            </th>
-            <th>
-                <select class="form-control typefilter v-small-input"
-                        ng-model="instanceTypeFilter"
-                        ng-options="item.label for item in typeFilterOptions"
-                        ng-change="filterInstances()">
-                </select>
-            </th>
-            <th></th>
-            <th></th>
-        </tr>
         </thead>
 
         <tbody>

http://git-wip-us.apache.org/repos/asf/ambari/blob/30d89a33/ambari-admin/src/main/resources/ui/admin-web/app/views/directives/comboSearch.html
----------------------------------------------------------------------
diff --git a/ambari-admin/src/main/resources/ui/admin-web/app/views/directives/comboSearch.html b/ambari-admin/src/main/resources/ui/admin-web/app/views/directives/comboSearch.html
new file mode 100644
index 0000000..a4fdfc2
--- /dev/null
+++ b/ambari-admin/src/main/resources/ui/admin-web/app/views/directives/comboSearch.html
@@ -0,0 +1,63 @@
+<!--
+* Licensed to the Apache Software Foundation (ASF) under one
+* or more contributor license agreements.  See the NOTICE file
+* distributed with this work for additional information
+* regarding copyright ownership.  The ASF licenses this file
+* to you 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.
+-->
+
+<div class="combo-search">
+  <div class="combo-search-inner" ng-click="observeSearchFilterInput($event)">
+    <div class="combo-search-applied-filter" ng-repeat="filter in appliedFilters" ng-click="forceFocus($event, filter)">
+      <i class="fa fa-times-circle" ng-click="removeFilter(filter)"></i>
+      <span>{{filter.label}}:</span>
+      <div class="combo-search-input-wrapper">
+        <input type="text"
+               autocomplete="off"
+               ng-attr-name="{{filter.id}}"
+               class="combo-search-input"
+               ng-model="filter.searchOptionInput"
+               ng-change="observeSearchOptionInput(filter)"
+               ng-blur="hideAutocomplete(filter)"/>
+        <div class="combo-search-dropdown" ng-show="filter.showAutoComplete">
+          <ul>
+            <li ng-repeat="item in filter.filteredOptions" class="filter">
+              <a ng-click="selectOption($event, item, filter)"
+                 ng-class="{active: item.active}"
+                 ng-mouseover="makeActive(item, filter.filteredOptions)">{{item.label}}</a>
+            </li>
+          </ul>
+        </div>
+      </div>
+    </div>
+    <div class="combo-search-input-wrapper">
+      <input type="text"
+             autocomplete="off"
+             placeholder="{{appliedFilters.length === 0 ? placeholder : ''}}"
+             class="combo-search-input main-input"
+             ng-model="searchFilterInput"
+             ng-change="observeSearchFilterInput()"/>
+      <div class="combo-search-dropdown" ng-show="showAutoComplete">
+        <ul>
+          <li ng-repeat="item in filterSuggestions"
+              ng-class="{category: item.isCategory, filter: !item.isCategory, hide: (item.isCategory && item.isDefault)}">
+            <a ng-click="selectFilter(item, $event)"
+               ng-class="{active: item.active}"
+               ng-mouseover="makeActive(item, filterSuggestions)">{{item.label}}</a>
+          </li>
+        </ul>
+      </div>
+    </div>
+    <i class="combo-search-close fa fa-times-circle" ng-show="appliedFilters.length" ng-click="clearFilters()"></i>
+  </div>
+</div>

http://git-wip-us.apache.org/repos/asf/ambari/blob/30d89a33/ambari-admin/src/main/resources/ui/admin-web/app/views/remoteClusters/list.html
----------------------------------------------------------------------
diff --git a/ambari-admin/src/main/resources/ui/admin-web/app/views/remoteClusters/list.html b/ambari-admin/src/main/resources/ui/admin-web/app/views/remoteClusters/list.html
index 67d650e..7a8e6f4 100644
--- a/ambari-admin/src/main/resources/ui/admin-web/app/views/remoteClusters/list.html
+++ b/ambari-admin/src/main/resources/ui/admin-web/app/views/remoteClusters/list.html
@@ -61,7 +61,7 @@
   <div class="alert empty-table-alert col-sm-12" ng-show="!remoteClusters.length && !isLoading">
     {{'common.alerts.noRemoteClusterDisplay' | translate}}
   </div>
-  <div class="col-sm-12 table-bar">
+  <div class="col-sm-12 table-bar" ng-show="tableInfo.total >= minInstanceForPagination">
     <div class="pull-left filtered-info">
       <span>{{'common.filterInfo' | translate:{showed: tableInfo.showed, total: tableInfo.total, term: constants.groups} }}</span>
       <span ng-show="isNotEmptyFilter">- <a href ng-click="clearFilters()">{{'common.controls.clearFilters' | translate}}</a></span>

http://git-wip-us.apache.org/repos/asf/ambari/blob/30d89a33/ambari-admin/src/main/resources/ui/admin-web/app/views/stackVersions/list.html
----------------------------------------------------------------------
diff --git a/ambari-admin/src/main/resources/ui/admin-web/app/views/stackVersions/list.html b/ambari-admin/src/main/resources/ui/admin-web/app/views/stackVersions/list.html
index 279343b..9d81543 100644
--- a/ambari-admin/src/main/resources/ui/admin-web/app/views/stackVersions/list.html
+++ b/ambari-admin/src/main/resources/ui/admin-web/app/views/stackVersions/list.html
@@ -123,7 +123,7 @@
   <div class="alert empty-table-alert col-sm-12" ng-show="!repos.length && !isLoading">
     {{'common.alerts.nothingToDisplay' | translate:{term: getConstant("common.version")} }}
   </div>
-  <div class="col-sm-12 table-bar">
+  <div class="col-sm-12 table-bar" ng-show="tableInfo.total >= minInstanceForPagination">
     <div class="pull-left filtered-info">
       <span>{{'common.filterInfo' | translate:{showed: tableInfo.showed, total: tableInfo.total, term: getConstant("common.versions")} }}</span>
       <span ng-show="isNotEmptyFilter">- <a href ng-click="clearFilters()">{{'common.controls.clearFilters' | translate}}</a></span>

http://git-wip-us.apache.org/repos/asf/ambari/blob/30d89a33/ambari-admin/src/main/resources/ui/admin-web/test/unit/controllers/ambariViews/ViewsListCtrl_test.js
----------------------------------------------------------------------
diff --git a/ambari-admin/src/main/resources/ui/admin-web/test/unit/controllers/ambariViews/ViewsListCtrl_test.js b/ambari-admin/src/main/resources/ui/admin-web/test/unit/controllers/ambariViews/ViewsListCtrl_test.js
new file mode 100644
index 0000000..362b94a
--- /dev/null
+++ b/ambari-admin/src/main/resources/ui/admin-web/test/unit/controllers/ambariViews/ViewsListCtrl_test.js
@@ -0,0 +1,167 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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.
+ */
+
+describe('#Cluster', function () {
+  describe('ViewsListCtrl', function() {
+    var scope, ctrl;
+
+    beforeEach(function () {
+      module('ambariAdminConsole');
+      inject(function($rootScope, $controller) {
+        scope = $rootScope.$new();
+        ctrl = $controller('ViewsListCtrl', {$scope: scope});
+      });
+      scope.instances = [
+        {
+          short_url_name: 'sun1',
+          url: 'url1',
+          view_name: 'vn1',
+          instance_name: 'in1',
+          short_url: 'su1'
+        },
+        {
+          short_url_name: 'sun2',
+          url: 'url2',
+          view_name: 'vn2',
+          instance_name: 'in2',
+          short_url: 'su2'
+        }
+      ];
+    });
+
+    describe('#initFilterOptions()', function () {
+      beforeEach(function() {
+        scope.initFilterOptions();
+      });
+
+      it('should fill short_url_name options', function() {
+        expect(scope.filters[0].options).toEqual([
+          {
+            key: 'sun1',
+            label: 'sun1'
+          },
+          {
+            key: 'sun2',
+            label: 'sun2'
+          }
+        ]);
+      });
+
+      it('should fill url options', function() {
+        expect(scope.filters[1].options).toEqual([
+          {
+            key: '/main/view/vn1/su1',
+            label: '/main/view/vn1/su1'
+          },
+          {
+            key: '/main/view/vn2/su2',
+            label: '/main/view/vn2/su2'
+          }
+        ]);
+      });
+
+      it('should fill view_name options', function() {
+        expect(scope.filters[2].options).toEqual([
+          {
+            key: 'vn1',
+            label: 'vn1'
+          },
+          {
+            key: 'vn2',
+            label: 'vn2'
+          }
+        ]);
+      });
+
+      it('should fill instance_name options', function() {
+        expect(scope.filters[3].options).toEqual([
+          {
+            key: 'in1',
+            label: 'in1'
+          },
+          {
+            key: 'in2',
+            label: 'in2'
+          }
+        ]);
+      });
+    });
+
+
+    describe('#filterInstances', function() {
+      beforeEach(function() {
+        spyOn(scope, 'resetPagination');
+      });
+
+      it('all should be filtered when filters not applied', function() {
+        scope.filterInstances();
+        expect(scope.tableInfo.filtered).toEqual(2);
+        scope.filterInstances([]);
+        expect(scope.tableInfo.filtered).toEqual(2);
+      });
+
+      it('resetPagination should be called', function() {
+        scope.filterInstances();
+        expect(scope.resetPagination).toHaveBeenCalled();
+      });
+
+      it('one view should be filtered', function() {
+        var appliedFilters = [
+          {
+            key: 'view_name',
+            values: ['vn1']
+          }
+        ];
+        scope.filterInstances(appliedFilters);
+        expect(scope.tableInfo.filtered).toEqual(1);
+        expect(scope.instances[0].isFiltered).toBeTruthy();
+        expect(scope.instances[1].isFiltered).toBeFalsy();
+      });
+
+      it('two views should be filtered', function() {
+        var appliedFilters = [
+          {
+            key: 'view_name',
+            values: ['vn1', 'vn2']
+          }
+        ];
+        scope.filterInstances(appliedFilters);
+        expect(scope.tableInfo.filtered).toEqual(2);
+        expect(scope.instances[0].isFiltered).toBeTruthy();
+        expect(scope.instances[1].isFiltered).toBeTruthy();
+      });
+
+      it('one views should be filtered with combo filter', function() {
+        var appliedFilters = [
+          {
+            key: 'view_name',
+            values: ['vn1', 'vn2']
+          },
+          {
+            key: 'instance_name',
+            values: ['in2']
+          }
+        ];
+        scope.filterInstances(appliedFilters);
+        expect(scope.tableInfo.filtered).toEqual(1);
+        expect(scope.instances[0].isFiltered).toBeFalsy();
+        expect(scope.instances[1].isFiltered).toBeTruthy();
+      });
+    });
+  });
+});

http://git-wip-us.apache.org/repos/asf/ambari/blob/30d89a33/ambari-admin/src/main/resources/ui/admin-web/test/unit/directives/comboSearch_test.js
----------------------------------------------------------------------
diff --git a/ambari-admin/src/main/resources/ui/admin-web/test/unit/directives/comboSearch_test.js b/ambari-admin/src/main/resources/ui/admin-web/test/unit/directives/comboSearch_test.js
new file mode 100644
index 0000000..9bc7083
--- /dev/null
+++ b/ambari-admin/src/main/resources/ui/admin-web/test/unit/directives/comboSearch_test.js
@@ -0,0 +1,242 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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.
+ */
+
+describe('#comboSearch', function () {
+  var scope, element;
+
+  beforeEach(module('ambariAdminConsole'));
+  beforeEach(module('views/directives/comboSearch.html'));
+
+  beforeEach(inject(function($rootScope, $compile) {
+    scope = $rootScope.$new();
+
+    var preCompiledElement = '<combo-search suggestions="filters" filter-change="filterItems" placeholder="Search"></combo-search>';
+
+    scope.filters = [
+      {
+        key: 'f1',
+        label: 'filter1',
+        options: []
+      },
+      {
+        key: 'f2',
+        label: 'filter2',
+        options: []
+      }
+    ];
+    scope.filterItems = angular.noop;
+    spyOn(scope, 'filterItems');
+
+
+    element = $compile(preCompiledElement)(scope);
+    scope.$digest();
+  }));
+
+  afterEach(function() {
+    element.remove();
+  });
+
+
+  describe('#removeFilter', function() {
+    it('should remove filter by id', function () {
+      var isoScope = element.isolateScope();
+      isoScope.appliedFilters.push({
+        id: 1
+      });
+      spyOn(isoScope, 'observeSearchFilterInput');
+      spyOn(isoScope, 'updateFilters');
+
+      isoScope.removeFilter({id: 1});
+
+      expect(isoScope.appliedFilters).toEqual([]);
+      expect(isoScope.observeSearchFilterInput).toHaveBeenCalled();
+      expect(isoScope.updateFilters).toHaveBeenCalledWith([]);
+    });
+  });
+
+  describe('#clearFilters', function() {
+    it('should empty appliedFilters', function () {
+      var isoScope = element.isolateScope();
+      isoScope.appliedFilters.push({
+        id: 1
+      });
+      spyOn(isoScope, 'updateFilters');
+
+      isoScope.clearFilters();
+
+      expect(isoScope.appliedFilters).toEqual([]);
+      expect(isoScope.updateFilters).toHaveBeenCalledWith([]);
+    });
+  });
+
+  describe('#selectFilter', function() {
+    it('should add new filter to appliedFilters', function () {
+      var isoScope = element.isolateScope();
+
+      isoScope.selectFilter({
+        key: 'f1',
+        label: 'filter1',
+        options: []
+      });
+
+      expect(isoScope.appliedFilters[0]).toEqual({
+        id: 'filter_1',
+        currentOption: null,
+        filteredOptions: [],
+        searchOptionInput: '',
+        key: 'f1',
+        label: 'filter1',
+        options: [],
+        showAutoComplete: false
+      });
+      expect(isoScope.isEditing).toBeFalsy();
+      expect(isoScope.showAutoComplete).toBeFalsy();
+      expect(isoScope.searchFilterInput).toEqual('');
+    });
+  });
+
+  describe('#selectOption', function() {
+    it('should set value to appliedFilter', function () {
+      var isoScope = element.isolateScope();
+      var filter = {};
+
+      spyOn(isoScope, 'observeSearchFilterInput');
+      spyOn(isoScope, 'updateFilters');
+
+      isoScope.selectOption(null, {
+        key: 'o1',
+        label: 'option1'
+      }, filter);
+
+      expect(filter.currentOption).toEqual({
+        key: 'o1',
+        label: 'option1'
+      });
+      expect(filter.showAutoComplete).toBeFalsy();
+      expect(isoScope.observeSearchFilterInput).toHaveBeenCalled();
+      expect(isoScope.updateFilters).toHaveBeenCalled();
+    });
+  });
+
+  describe('#hideAutocomplete', function() {
+
+    it('showAutoComplete should be false when filter passed', function () {
+      var isoScope = element.isolateScope();
+      var filter = {
+        showAutoComplete: true
+      };
+      jasmine.Clock.useMock();
+
+      isoScope.hideAutocomplete(filter);
+
+      jasmine.Clock.tick(101);
+      expect(filter.showAutoComplete).toBeFalsy();
+    });
+
+    it('showAutoComplete should be false when isEditing = false', function () {
+      var isoScope = element.isolateScope();
+      jasmine.Clock.useMock();
+
+      isoScope.isEditing = false;
+      isoScope.showAutoComplete = true;
+      isoScope.hideAutocomplete();
+
+      jasmine.Clock.tick(101);
+      expect(isoScope.showAutoComplete).toBeFalsy();
+    });
+
+    it('showAutoComplete should be false when isEditing = true', function () {
+      var isoScope = element.isolateScope();
+      jasmine.Clock.useMock();
+
+      isoScope.isEditing = true;
+      isoScope.showAutoComplete = true;
+      isoScope.hideAutocomplete();
+
+      jasmine.Clock.tick(101);
+      expect(isoScope.showAutoComplete).toBeTruthy();
+    });
+  });
+
+  describe('#makeActive', function() {
+    it('category option can not be active', function () {
+      var isoScope = element.isolateScope();
+      var active = {
+        key: 'o1',
+        isCategory: true,
+        active: false
+      };
+
+      isoScope.makeActive(active, [active]);
+
+      expect(active.active).toBeFalsy();
+    });
+
+    it('value option can be active', function () {
+      var isoScope = element.isolateScope();
+      var active = {
+        key: 'o1',
+        isCategory: false,
+        active: false
+      };
+
+      isoScope.makeActive(active, [active]);
+
+      expect(active.active).toBeTruthy();
+    });
+  });
+
+  describe('#updateFilters', function() {
+    it('filter function from parent scope should be called', function () {
+      var isoScope = element.isolateScope();
+      spyOn(isoScope, 'extractFilters').andReturn([{}]);
+
+      isoScope.updateFilters([{}]);
+
+      expect(scope.filterItems).toHaveBeenCalledWith([{}]);
+    });
+  });
+
+  describe('#extractFilters', function() {
+    it('should extract filters', function () {
+      var isoScope = element.isolateScope();
+      var filters = [
+        {
+          currentOption: { key: 'o1'},
+          key: 'f1'
+        },
+        {
+          currentOption: { key: 'o2'},
+          key: 'f1'
+        },
+        {
+          currentOption: null,
+          key: 'f2'
+        }
+      ];
+
+      expect(isoScope.extractFilters(filters)).toEqual([
+        {
+          key: 'f1',
+          values: ['o1', 'o2']
+        }
+      ]);
+    });
+  });
+
+});


[02/24] ambari git commit: AMBARI-22635: Addendum fix Ambari should create a dummy core-site.xml for Ranger plugins when namenode is not installed.

Posted by nc...@apache.org.
AMBARI-22635: Addendum fix Ambari should create a dummy core-site.xml for Ranger plugins when namenode is not installed.


Project: http://git-wip-us.apache.org/repos/asf/ambari/repo
Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/f1f73022
Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/f1f73022
Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/f1f73022

Branch: refs/heads/branch-feature-AMBARI-21674
Commit: f1f730229fe559439189726c0cd40cd58cbf0135
Parents: d95d3eb
Author: Vishal Suvagia <vi...@apache.org>
Authored: Fri Dec 15 11:20:31 2017 +0530
Committer: Vishal Suvagia <vi...@apache.org>
Committed: Fri Dec 15 11:20:31 2017 +0530

----------------------------------------------------------------------
 .../KAFKA/0.8.1/package/scripts/setup_ranger_kafka.py              | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ambari/blob/f1f73022/ambari-server/src/main/resources/common-services/KAFKA/0.8.1/package/scripts/setup_ranger_kafka.py
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/common-services/KAFKA/0.8.1/package/scripts/setup_ranger_kafka.py b/ambari-server/src/main/resources/common-services/KAFKA/0.8.1/package/scripts/setup_ranger_kafka.py
index e2cfbcf..16eff94 100644
--- a/ambari-server/src/main/resources/common-services/KAFKA/0.8.1/package/scripts/setup_ranger_kafka.py
+++ b/ambari-server/src/main/resources/common-services/KAFKA/0.8.1/package/scripts/setup_ranger_kafka.py
@@ -90,7 +90,7 @@ def setup_ranger_kafka():
       else:
         Logger.info("Stack supports core-site.xml creation for Ranger plugin and Namenode is not installed, creating create core-site.xml from default configurations")
         setup_core_site_for_required_plugins(component_user = params.kafka_user, component_group = params.user_group,
-                                             create_core_site_path = params.conf_dir, configurations = { 'hadoop.security.authentication' : 'kerberos' if params.security_enabled else 'simple' },
+                                             create_core_site_path = params.conf_dir, configurations = { 'hadoop.security.authentication' : 'kerberos' if params.kerberos_security_enabled else 'simple' },
                                              configuration_attributes = {})
 
     else:


[24/24] ambari git commit: Merge branch 'trunk' into branch-feature-AMBARI-21674

Posted by nc...@apache.org.
Merge branch 'trunk' into branch-feature-AMBARI-21674


Project: http://git-wip-us.apache.org/repos/asf/ambari/repo
Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/41c1e647
Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/41c1e647
Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/41c1e647

Branch: refs/heads/branch-feature-AMBARI-21674
Commit: 41c1e647cdce5591edbae3a972444d97eda8e09b
Parents: 37361fd 81c0454
Author: Nate Cole <nc...@hortonworks.com>
Authored: Thu Dec 21 09:36:20 2017 -0500
Committer: Nate Cole <nc...@hortonworks.com>
Committed: Thu Dec 21 09:36:20 2017 -0500

----------------------------------------------------------------------
 .../main/resources/ui/admin-web/app/index.html  |   3 +
 .../app/scripts/controllers/SideNavCtrl.js      |   6 +-
 .../controllers/ambariViews/ViewsListCtrl.js    | 220 ++++-----
 .../remoteClusters/RemoteClustersListCtrl.js    | 110 ++---
 .../stackVersions/StackVersionsCreateCtrl.js    |   2 +-
 .../stackVersions/StackVersionsEditCtrl.js      |   2 +-
 .../stackVersions/StackVersionsListCtrl.js      | 192 +++-----
 .../userManagement/GroupsListCtrl.js            |  86 ++--
 .../controllers/userManagement/UsersListCtrl.js | 132 ++---
 .../app/scripts/directives/comboSearch.js       | 480 +++++++++++++++++++
 .../admin-web/app/scripts/services/Cluster.js   |   3 +-
 .../admin-web/app/scripts/services/Filters.js   |  84 ++++
 .../ui/admin-web/app/scripts/services/Group.js  |  11 +-
 .../app/scripts/services/Pagination.js          |  59 +++
 .../app/scripts/services/RemoteCluster.js       |  10 +-
 .../ui/admin-web/app/scripts/services/Stack.js  |  32 +-
 .../ui/admin-web/app/scripts/services/User.js   |  13 +-
 .../ui/admin-web/app/styles/combo-search.css    | 164 +++++++
 .../resources/ui/admin-web/app/styles/main.css  |  36 ++
 .../ui/admin-web/app/styles/user-management.css |   4 +
 .../app/views/ambariViews/viewsList.html        |  50 +-
 .../app/views/directives/comboSearch.html       |  63 +++
 .../app/views/remoteClusters/list.html          |  35 +-
 .../admin-web/app/views/stackVersions/list.html |  36 +-
 .../app/views/userManagement/groupsList.html    |  51 +-
 .../app/views/userManagement/usersList.html     |  61 +--
 .../ambariViews/ViewsListCtrl_test.js           | 111 +++++
 .../userManagement/GroupsListCtrl_test.js       | 100 +---
 .../userManagement/UsersListCtrl_test.js        | 306 ------------
 .../test/unit/directives/comboSearch_test.js    | 229 +++++++++
 .../test/unit/services/Filters_test.js          | 161 +++++++
 .../test/unit/services/Pagination_test.js       |  72 +++
 .../src/main/python/ambari_agent/ActionQueue.py |  21 +-
 .../python/ambari_agent/CommandStatusDict.py    |   2 +-
 .../src/main/python/ambari_agent/Controller.py  |  23 +-
 .../ambari_agent/CustomServiceOrchestrator.py   |   4 +-
 .../src/main/python/ambari_agent/DataCleaner.py |   4 +-
 .../src/main/python/ambari_agent/Heartbeat.py   |  17 +-
 .../src/main/python/ambari_agent/LiveStatus.py  |   3 +-
 .../main/python/ambari_agent/PythonExecutor.py  |  15 +-
 .../ambari_agent/PythonReflectiveExecutor.py    |   3 +-
 .../main/python/ambari_agent/RecoveryManager.py |  17 +-
 .../ambari_agent/StatusCommandsExecutor.py      |   3 +-
 .../python/ambari_agent/alerts/ams_alert.py     |   8 +-
 .../python/ambari_agent/alerts/metric_alert.py  |   3 +-
 .../src/main/python/ambari_agent/security.py    |   8 +-
 .../libraries/functions/conf_select.py          |   7 +
 .../libraries/functions/setup_atlas_hook.py     |  11 +-
 .../ambari-logsearch-assembly/pom.xml           | 117 ++---
 .../src/main/package/deb/logfeeder/postinst     |  22 +
 .../src/main/package/deb/logfeeder/postrm       |   6 +
 .../src/main/package/deb/logfeeder/posttrm      |  15 -
 .../src/main/package/deb/logfeeder/preinst      |  13 +
 .../src/main/package/deb/portal/postinst        |  19 +
 .../src/main/package/deb/portal/postrm          |   6 +
 .../src/main/package/deb/portal/preinst         |  13 +
 .../main/package/rpm/logfeeder/postinstall.sh   |  37 ++
 .../main/package/rpm/logfeeder/postremove.sh    |  21 +
 .../main/package/rpm/logfeeder/preinstall.sh    |  28 ++
 .../src/main/package/rpm/portal/postinstall.sh  |  34 ++
 .../src/main/package/rpm/portal/postremove.sh   |  21 +
 .../src/main/package/rpm/portal/preinstall.sh   |  28 ++
 .../ambari-logsearch-logfeeder/README.md        |   4 +-
 .../ambari-logsearch-logfeeder/build.properties |  18 -
 .../ambari-logsearch-logfeeder/build.xml        |  28 +-
 .../ambari-logsearch-logfeeder/pom.xml          |  31 --
 .../ambari-logsearch-logfeeder/run.sh           |   4 +-
 .../org/apache/ambari/logfeeder/LogFeeder.java  |  35 +-
 .../ambari/logfeeder/LogFeederCommandLine.java  |  63 +--
 .../ambari/logfeeder/common/ConfigHandler.java  |   7 +-
 .../src/main/package/deb/control/control        |  22 -
 .../src/main/package/deb/control/postinst       |  15 -
 .../src/main/package/deb/control/postrm         |  15 -
 .../src/main/package/deb/control/preinst        |  15 -
 .../src/main/package/deb/control/prerm          |  15 -
 .../src/main/resources/logfeeder.properties     |   5 +-
 .../src/main/scripts/logfeeder-env.sh           |  40 ++
 .../src/main/scripts/logfeeder.sh               | 291 +++++++++++
 .../src/main/scripts/run.sh                     | 103 ----
 .../ambari-logsearch-server/README.md           |   2 +-
 .../ambari-logsearch-server/build.xml           |  36 +-
 .../ambari-logsearch-server/pom.xml             |  11 -
 ambari-logsearch/ambari-logsearch-server/run.sh |   2 +-
 .../org/apache/ambari/logsearch/LogSearch.java  |   2 +-
 .../src/main/scripts/logsearch-env.sh           |  40 ++
 .../src/main/scripts/logsearch.sh               | 273 +++++++++++
 .../src/main/scripts/run.sh                     |  99 ----
 .../src/main/scripts/stop.sh                    |  44 --
 .../src/app/components/app.component.html       |  11 +-
 .../src/app/components/app.component.less       |   4 +-
 .../filters-panel/filters-panel.component.ts    |   8 +-
 .../logs-container.component.html               |   6 +-
 .../logs-container.component.less               |  17 +-
 .../logs-container/logs-container.component.ts  |  35 +-
 .../main-container.component.html               |   1 -
 .../main-container.component.less               |   1 -
 .../main-container/main-container.component.ts  |   5 +-
 .../src/assets/i18n/en.json                     |   4 +-
 ambari-logsearch/docker/Dockerfile              |   6 +-
 ambari-logsearch/docker/all.yml                 |   4 +-
 ambari-logsearch/docker/bin/start.sh            |  37 +-
 ambari-logsearch/docker/docker-compose.yml      |   2 -
 ambari-logsearch/docker/logsearch-logfeeder.yml |   1 -
 ambari-logsearch/docker/logsearch-server.yml    |   1 -
 .../test-config/logfeeder/logfeeder-env.sh      |   5 +-
 .../test-config/logfeeder/logfeeder.properties  |   2 +-
 .../test-config/logsearch/logsearch-env.sh      |   5 +-
 .../logsearch/logsearch-https.properties        |   4 +-
 .../test-config/logsearch/logsearch.properties  |   4 +-
 ambari-server/pom.xml                           |   2 +-
 .../RootServiceComponentConfiguration.java      |  73 +++
 .../server/configuration/Configuration.java     |  11 +-
 .../ConfigurationPropertyType.java              |  22 +
 .../AmbariServerConfigurationHandler.java       | 102 +++-
 .../AmbariServerConfigurationUtils.java         |  78 +++
 .../AmbariServerLDAPConfigurationHandler.java   |   9 +-
 ...ootServiceComponentConfigurationHandler.java |   7 +-
 ...eComponentConfigurationResourceProvider.java |  18 +-
 .../domain/AmbariLdapConfigurationKeys.java     |  77 +--
 .../ambari/server/orm/dao/HostVersionDAO.java   |  15 +
 .../server/orm/entities/HostVersionEntity.java  |   5 +
 .../server/state/cluster/ClusterImpl.java       |  10 +
 .../HBASE/0.96.0.2.0/package/scripts/hbase.py   |  26 +-
 .../HBASE/2.0.0.3.0/package/scripts/hbase.py    |  39 +-
 .../0.8.1/package/scripts/setup_ranger_kafka.py |   2 +-
 .../0.5.0/configuration/logfeeder-env.xml       |   2 +-
 .../configuration/logfeeder-properties.xml      |   2 +-
 .../0.5.0/configuration/logsearch-env.xml       |   6 +-
 .../0.5.0/package/scripts/logfeeder.py          |   7 +-
 .../0.5.0/package/scripts/logsearch.py          |   8 +-
 .../0.5.0/package/scripts/logsearch_common.py   |  54 ---
 .../LOGSEARCH/0.5.0/package/scripts/params.py   |   8 +-
 .../0.5.0/package/scripts/setup_logfeeder.py    |   2 +-
 .../0.5.0/package/scripts/setup_logsearch.py    |   2 +-
 .../0.5.0/properties/logfeeder-env.sh.j2        |   5 +-
 .../0.5.0/properties/logsearch-env.sh.j2        |   5 +-
 .../SPARK/1.2.1/package/scripts/livy_service.py |  22 +-
 .../SPARK/2.2.0/package/scripts/livy_service.py |  29 +-
 .../2.0.0/package/scripts/livy2_service.py      |  27 +-
 .../SPARK2/2.0.0/package/scripts/setup_livy2.py |   2 +
 .../2.1.0.2.0/package/scripts/params_linux.py   |  19 +-
 .../3.0.0.3.0/package/scripts/params_linux.py   |  20 +-
 .../ZEPPELIN/0.7.0/package/scripts/master.py    |   8 +-
 .../custom_actions/scripts/install_packages.py  |  37 +-
 .../stack-hooks/after-INSTALL/scripts/params.py |   2 +-
 .../HDP/2.0.6/properties/stack_packages.json    |  11 +-
 .../services/YARN/configuration/yarn-site.xml   |   4 +-
 .../stacks/HDP/2.6/upgrades/config-upgrade.xml  |   2 -
 .../HDP/3.0/properties/stack_packages.json      |  11 +-
 .../services/YARN/configuration/yarn-site.xml   |   4 +-
 ...ponentConfigurationResourceProviderTest.java | 192 +++++---
 .../server/orm/dao/HostVersionDAOTest.java      |  12 +
 .../hooks/after-INSTALL/test_after_install.py   |   8 +-
 .../stacks/2.4/LOGSEARCH/test_logfeeder.py      |  34 +-
 .../stacks/2.4/LOGSEARCH/test_logsearch.py      |  31 +-
 .../test/python/stacks/2.4/configs/default.json |   2 +-
 .../python/stacks/2.5/SPARK/test_spark_livy.py  |   3 +-
 .../stacks/2.6/SPARK2/test_spark_livy2.py       |   5 +-
 .../test/python/stacks/2.6/configs/default.json |   2 +
 docs/pom.xml                                    |   2 +-
 docs/src/site/apt/index.apt                     |   2 +-
 docs/src/site/apt/whats-new.apt                 |  14 +-
 docs/src/site/site.xml                          |   4 +
 163 files changed, 3853 insertions(+), 2089 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ambari/blob/41c1e647/ambari-server/src/main/java/org/apache/ambari/server/configuration/Configuration.java
----------------------------------------------------------------------


[07/24] ambari git commit: AMBARI-22647. Rafactor: Package Log Search and Log Feeder into jars + cleanup start scripts (oleewere)

Posted by nc...@apache.org.
http://git-wip-us.apache.org/repos/asf/ambari/blob/562795c4/ambari-logsearch/ambari-logsearch-server/src/main/scripts/logsearch.sh
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-server/src/main/scripts/logsearch.sh b/ambari-logsearch/ambari-logsearch-server/src/main/scripts/logsearch.sh
new file mode 100755
index 0000000..128617c
--- /dev/null
+++ b/ambari-logsearch/ambari-logsearch-server/src/main/scripts/logsearch.sh
@@ -0,0 +1,274 @@
+#!/bin/bash
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements.  See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You 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.
+
+JVM="java"
+
+if [ -x $JAVA_HOME/bin/java ]; then
+  JVM=$JAVA_HOME/bin/java
+fi
+
+if [ "$LOGSEARCH_JAVA_MEM" = "" ]; then
+    LOGSEARCH_JAVA_MEM="-Xmx1g"
+fi
+
+readlinkf(){
+  # get real path on mac OSX
+  perl -MCwd -e 'print Cwd::abs_path shift' "$1";
+}
+
+if [ "$(uname -s)" = 'Linux' ]; then
+  SCRIPT_DIR="`dirname "$(readlink -f "$0")"`"
+else
+  SCRIPT_DIR="`dirname "$(readlinkf "$0")"`"
+fi
+
+LOGSEARCH_ROOT_DIR="`dirname \"$SCRIPT_DIR\"`"
+LOGSEARCH_LIBS_DIR="$LOGSEARCH_ROOT_DIR/libs"
+LOGSEARCH_WEBAPP_DIR="$LOGSEARCH_ROOT_DIR/webapp"
+
+if [ "$LOGSEARCH_CONF_DIR" = "" ]; then
+  if [ -d "$LOGSEARCH_ROOT_DIR/conf" ]; then
+    LOGSEARCH_CONF_DIR="$LOGSEARCH_ROOT_DIR/conf"
+  fi
+fi
+
+if [ -f "$LOGSEARCH_CONF_DIR/logsearch-env.sh" ]; then
+  source $LOGSEARCH_CONF_DIR/logsearch-env.sh
+fi
+
+if [ ! -z "$LOGSEARCH_SOLR_CLIENT_SSL_INCLUDE" ]; then
+  source $LOGSEARCH_SOLR_CLIENT_SSL_INCLUDE
+fi
+
+if [ -z "$LOGSEARCH_PID_FILE" ]; then
+  LOGSEARCH_PID_DIR=$HOME
+  export LOGSEARCH_PID_FILE=$LOGSEARCH_PID_DIR/logsearch.pid
+fi
+
+if [ -z "$LOG_FILE" ]; then
+  export LOG_FILE="logsearch.log"
+fi
+
+LOGSEARCH_GC_LOGFILE="logsearch_gc.log"
+
+if [ -z "$LOG_PATH" ]; then
+  LOG_FILE="$HOME/$LOG_FILE"
+  LOGSEARCH_GC_LOGFILE="$HOME/$LOGSEARCH_GC_LOGFILE"
+else
+  LOG_PATH_WITHOUT_SLASH=${LOG_PATH%/}
+  LOG_FILE="$LOG_PATH_WITHOUT_SLASH/$LOG_FILE"
+  LOGSEARCH_GC_LOGFILE="$LOG_PATH_WITHOUT_SLASH/$LOGSEARCH_GC_LOGFILE"
+fi
+
+LOGSEARCH_GC_OPTS="-XX:+PrintGCDetails -XX:+PrintGCDateStamps -Xloggc:$LOGSEARCH_GC_LOGFILE"
+
+function print_usage() {
+  cat << EOF
+
+   Usage: [<command>] [<arguments with flags>]
+
+   commands:
+     start                         Start Log Search
+     stop                          Stop Log Search
+     status                        Check Log Search status (pid file)
+     help                          Print usage
+
+
+   start command arguments:
+     -d, --debug                   Start java process in debug mode
+     -f, --foreground              Start java process in foreground
+
+EOF
+}
+
+function spinner() {
+  local pid=$1
+  local delay=0.5
+  local spinstr='|/-\'
+  while [ "$(ps aux | awk '{print $2}' | grep -w $pid)" ]; do
+      local temp=${spinstr#?}
+      printf " [%c]  " "$spinstr"
+      local spinstr=$temp${spinstr%"$temp"}
+      sleep $delay
+      printf "\b\b\b\b\b\b"
+  done
+  printf "    \b\b\b\b"
+}
+
+function status() {
+  echo "Checking Log Search status ..."
+  if [ -f "$LOGSEARCH_PID_FILE" ]; then
+    LOGSEARCH_PID=`cat "$LOGSEARCH_PID_FILE"`
+  else
+    echo "Log Search pid not exists. (probably the process is not running)"
+    exit 1
+  fi
+
+  if ps -p $LOGSEARCH_PID > /dev/null
+   then
+   echo "Log Search process is running. (pid: $LOGSEARCH_PID)"
+   exit 0
+  else
+   echo "Log Search process is not running."
+   exit 1
+  fi
+}
+
+function start() {
+  (status);
+  exit_status=$(echo $?)
+  if [ "$exit_status" = "0" ]; then
+    echo "Skipping start process."
+    exit 0
+  fi
+
+  FG="false"
+  LOGSEARCH_DEBUG_SUSPEND=${LOGSEARCH_DEBUG_SUSPEND:-n}
+  LOGSEARCH_DEBUG_PORT=${LOGSEARCH_DEBUG_PORT:-"5005"}
+
+  if [ "$LOGSEARCH_DEBUG" = "true" ]; then
+    LOGSEARCH_JAVA_OPTS="$LOGSEARCH_JAVA_OPTS -Xdebug -Xrunjdwp:transport=dt_socket,address=$LOGSEARCH_DEBUG_PORT,server=y,suspend=$LOGSEARCH_DEBUG_SUSPEND "
+  fi
+
+  if [ "$LOGSEARCH_SSL" = "true" ]; then
+    LOGSEARCH_JAVA_OPTS="$LOGSEARCH_JAVA_OPTS -Djavax.net.ssl.keyStore=$LOGSEARCH_KEYSTORE_LOCATION -Djavax.net.ssl.keyStoreType=$LOGSEARCH_KEYSTORE_TYPE -Djavax.net.ssl.trustStore=$LOGSEARCH_TRUSTSTORE_LOCATION -Djavax.net.ssl.trustStoreType=$LOGSEARCH_TRUSTSTORE_TYPE"
+  fi
+
+  if [ "$LOGSEARCH_JMX" = "true" ]; then
+   LOGSEARCH_JAVA_OPTS="$LOGSEARCH_JAVA_OPTS -Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.ssl=false -Dcom.sun.management.jmxremote.authenticate=false -Dcom.sun.management.jmxremote.port=2099"
+  fi
+
+  if [ $# -gt 0 ]; then
+    while true; do
+      case "$1" in
+          -f|--foreground)
+              FG="true"
+              shift
+          ;;
+          -d|--debug)
+              if [ "$LOGSEARCH_DEBUG" != "true" ]; then
+                LOGSEARCH_JAVA_OPTS="$LOGSEARCH_JAVA_OPTS -Xdebug -Xrunjdwp:transport=dt_socket,address=$LOGSEARCH_DEBUG_PORT,server=y,suspend=$LOGSEARCH_DEBUG_SUSPEND "
+              fi
+              shift
+          ;;
+          *)
+              if [ "${1:0:2}" == "-D" ]; then
+                # pass thru any opts that begin with -D (java system props)
+                LOGSEARCH_JAVA_OPTS+=("$1")
+                echo "$LOGSEARCH_JAVA_OPTS"
+                shift
+              else
+                if [ "$1" != "" ]; then
+                  print_usage
+                  exit 1
+                else
+                  break
+                fi
+              fi
+          ;;
+      esac
+    done
+  fi
+
+  if [ $FG == "true" ]; then
+    echo "Starting Log Search... (foreground) pid_file=$LOGSEARCH_PID_FILE"
+    echo "Run command $JVM -cp '$LOGSEARCH_CONF_DIR:$LOGSEARCH_WEBAPP_DIR:$LOGSEARCH_LIBS_DIR/*' $LOGSEARCH_GC_OPTS $LOGSEARCH_JAVA_OPTS $LOGSEARCH_JAVA_MEM org.apache.ambari.logsearch.LogSearch"
+    $JVM -cp "$LOGSEARCH_CONF_DIR:$LOGSEARCH_WEBAPP_DIR:$LOGSEARCH_LIBS_DIR/*" $LOGSEARCH_GC_OPTS $LOGSEARCH_JAVA_OPTS $LOGSEARCH_JAVA_MEM org.apache.ambari.logsearch.LogSearch
+  else
+   echo "Starting Log Search... Output file=$LOG_FILE pid_file=$LOGSEARCH_PID_FILE"
+   echo "Run command nohup $JVM -cp '$LOGSEARCH_CONF_DIR:$LOGSEARCH_WEBAPP_DIR:$LOGSEARCH_LIBS_DIR/*' $LOGSEARCH_GC_OPTS $LOGSEARCH_JAVA_OPTS $LOGSEARCH_JAVA_MEM org.apache.ambari.logsearch.LogSearch"
+   nohup $JVM -cp "$LOGSEARCH_CONF_DIR:$LOGSEARCH_WEBAPP_DIR:$LOGSEARCH_LIBS_DIR/*" $LOGSEARCH_GC_OPTS $LOGSEARCH_JAVA_OPTS $LOGSEARCH_JAVA_MEM org.apache.ambari.logsearch.LogSearch > $LOG_FILE 2>&1 &
+  fi
+}
+
+function stop() {
+  LOGSEARCH_STOP_WAIT=3
+  if [ -f "$LOGSEARCH_PID_FILE" ]; then
+    LOGSEARCH_PID=`cat "$LOGSEARCH_PID_FILE"`
+  fi
+
+  if [ "$LOGSEARCH_PID" != "" ]; then
+    echo -e "Sending stop command to Log Search... Checking PID: $LOGSEARCH_PID."
+    kill $LOGSEARCH_PID
+      (loops=0
+      while true
+      do
+        CHECK_PID=`ps auxww | awk '{print $2}' | grep -w $LOGSEARCH_PID | sort -r | tr -d ' '`
+        if [ "$CHECK_PID" != "" ]; then
+          slept=$((loops * 2))
+          if [ $slept -lt $LOGSEARCH_STOP_WAIT ]; then
+            sleep 2
+            loops=$[$loops+1]
+          else
+            exit # subshell!
+          fi
+        else
+          exit # subshell!
+        fi
+      done) &
+    spinner $!
+    rm -f "$LOGSEARCH_PID_FILE"
+  else
+    echo -e "No Log Search process found to stop."
+    exit 0
+  fi
+
+  CHECK_PID=`ps auxww | awk '{print $2}' | grep -w $LOGSEARCH_PID | sort -r | tr -d ' '`
+  if [ "$CHECK_PID" != "" ]; then
+    echo -e "Log Search process $LOGSEARCH_PID is still running; forcefully killing it now."
+    kill -9 $LOGSEARCH_PID
+    echo "Killed process $LOGSEARCH_PID"
+    rm -f "$LOGSEARCH_PID_FILE"
+    sleep 1
+  else
+    echo "Log Search is stopped."
+  fi
+
+  CHECK_PID=`ps auxww | awk '{print $2}' | grep -w $LOGSEARCH_PID | sort -r | tr -d ' '`
+  if [ "$CHECK_PID" != "" ]; then
+    echo "ERROR: Failed to kill Log Search Java process $LOGSEARCH_PID ... script fails."
+    exit 1
+  fi
+}
+
+if [ $# -gt 0 ]; then
+    SCRIPT_CMD="$1"
+    shift
+else
+   print_usage
+   exit 1
+fi
+
+case $SCRIPT_CMD in
+  start)
+    start ${1+"$@"}
+  ;;
+  stop)
+    stop
+  ;;
+  status)
+    status
+  ;;
+  help)
+    print_usage
+    exit 0
+  ;;
+  *)
+    print_usage
+    exit 1
+  ;;
+
+esac
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/ambari/blob/562795c4/ambari-logsearch/ambari-logsearch-server/src/main/scripts/run.sh
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-server/src/main/scripts/run.sh b/ambari-logsearch/ambari-logsearch-server/src/main/scripts/run.sh
deleted file mode 100755
index 241b32f..0000000
--- a/ambari-logsearch/ambari-logsearch-server/src/main/scripts/run.sh
+++ /dev/null
@@ -1,99 +0,0 @@
-#!/bin/bash
-# Licensed to the Apache Software Foundation (ASF) under one or more
-# contributor license agreements.  See the NOTICE file distributed with
-# this work for additional information regarding copyright ownership.
-# The ASF licenses this file to You 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.
-
-curr_dir=`pwd`
-cd `dirname $0`; script_dir=`pwd`; cd $curr_dir
-
-if [ ! -z "$LOGSEARCH_INCLUDE" ]; then
-   source $LOGSEARCH_INCLUDE
-fi
-
-if [ ! -z "$LOGSEARCH_SOLR_CLIENT_SSL_INCLUDE" ]; then
-   source $LOGSEARCH_SOLR_CLIENT_SSL_INCLUDE
-fi
-
-JAVA=java
-if [ -x $JAVA_HOME/bin/java ]; then
-    JAVA=$JAVA_HOME/bin/java
-fi
-
-if [ "$LOGSEARCH_JAVA_MEM" = "" ]; then
-    LOGSEARCH_JAVA_MEM="-Xmx1g"
-fi
-
-if [ "$LOGFILE" = "" ]; then
-    LOGFILE="/var/log/logsearch/logsearch.out"
-    touch $LOGFILE 2> /dev/null
-    if [ $? -ne 0 ]; then
-	LOGFILE=/tmp/${USER}_logsearch.out
-    fi
-fi
-
-
-#Temporarily enabling JMX so we can monitor the memory and CPU utilization of the process
-#JMX="-Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.ssl=false -Dcom.sun.management.jmxremote.authenticate=false -Dcom.sun.management.jmxremote.port=3098"
-
-LOGSEARCH_DEBUG_SUSPEND=${LOGSEARCH_DEBUG_SUSPEND:-n}
-if [ "$LOGSEARCH_DEBUG" = "true" ] && [ ! -z "$LOGSEARCH_DEBUG_PORT" ]; then
-  LOGSEARCH_JAVA_OPTS="$LOGSEARCH_JAVA_OPTS -Xdebug -Xrunjdwp:transport=dt_socket,address=$LOGSEARCH_DEBUG_PORT,server=y,suspend=$LOGSEARCH_DEBUG_SUSPEND "
-fi
-
-if [ "$LOGSEARCH_SSL" = "true" ]; then
-  LOGSEARCH_JAVA_OPTS="$LOGSEARCH_JAVA_OPTS -Djavax.net.ssl.keyStore=$LOGSEARCH_KEYSTORE_LOCATION -Djavax.net.ssl.keyStoreType=$LOGSEARCH_KEYSTORE_TYPE -Djavax.net.ssl.trustStore=$LOGSEARCH_TRUSTSTORE_LOCATION -Djavax.net.ssl.trustStoreType=$LOGSEARCH_TRUSTSTORE_TYPE"
-fi
-
-if [ "$PID_FILE" = "" ]; then
-    LOGSEARCH_PID_DIR=$HOME
-    PID_FILE=$LOGSEARCH_PID_DIR/logsearch-search-$USER.pid
-fi
-
-if [ -f ${PID_FILE} ]; then
-    PID=`cat ${PID_FILE}`
-    if kill -0 $PID 2>/dev/null; then
-	echo "logsearch already running (${PID}) killing..."
-	kill $PID 2>/dev/null
-	sleep 5
-	if kill -0 $PID 2>/dev/null; then
-	    echo "logsearch still running. Will kill process forcefully in another 10 seconds..."
-	    sleep 10
-	    kill -9 $PID 2>/dev/null
-	    sleep 2
-	fi
-    fi
-
-    if kill -0 $PID 2>/dev/null; then
-	echo "ERROR: Even after all efforts to stop logsearch, it is still running. pid=$PID. Please manually kill the service and try again."
-	exit 1
-    fi
-fi
-
-if [ -z "$LOGSEARCH_CONF_DIR" ]; then
-  LOGSEARCH_CONF_DIR="/etc/logsearch/conf"
-  if [ ! -d $LOGSEARCH_CONF_DIR ]; then
-      if [ -d $script_dir/classes ]; then
-	  LOGSEARCH_CONF_DIR=$script_dir/classes
-      fi
-  fi
-  echo "LOGSEARCH_CONF_DIR not found. Use default: $LOGSEARCH_CONF_DIR"
-fi
-
-LOGSEARCH_GC_LOGFILE=`dirname $LOGFILE`/logsearch_gc.log
-LOGSEARCH_GC_OPTS="-XX:+PrintGCDetails -XX:+PrintGCDateStamps -Xloggc:$LOGSEARCH_GC_LOGFILE"
-
-echo "Starting logsearch. Output file=$LOGFILE pid_file=$PID_FILE"
-#LOGSEARCH_CLI_CLASSPATH=
-#set -x
-nohup $JAVA -cp "$LOGSEARCH_CLI_CLASSPATH:$LOGSEARCH_CONF_DIR:$script_dir/libs/*:$script_dir/classes" $LOGSEARCH_GC_OPTS $LOGSEARCH_JAVA_MEM $LOGSEARCH_JAVA_OPTS $JMX org.apache.ambari.logsearch.LogSearch $* > $LOGFILE 2>&1 &

http://git-wip-us.apache.org/repos/asf/ambari/blob/562795c4/ambari-logsearch/ambari-logsearch-server/src/main/scripts/stop.sh
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-server/src/main/scripts/stop.sh b/ambari-logsearch/ambari-logsearch-server/src/main/scripts/stop.sh
deleted file mode 100755
index 3612f08..0000000
--- a/ambari-logsearch/ambari-logsearch-server/src/main/scripts/stop.sh
+++ /dev/null
@@ -1,44 +0,0 @@
-#!/bin/bash
-# Licensed to the Apache Software Foundation (ASF) under one or more
-# contributor license agreements.  See the NOTICE file distributed with
-# this work for additional information regarding copyright ownership.
-# The ASF licenses this file to You 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.
-
-curr_dir=`pwd`
-cd `dirname $0`; script_dir=`pwd`; cd $curr_dir
-
-if [ "$PID_FILE" = "" ]; then
-    LOGSEARCH_PID_DIR=$HOME
-    PID_FILE=$LOGSEARCH_PID_DIR/logsearch-search-$USER.pid
-fi
-
-if [ -f ${PID_FILE} ]; then
-    PID=`cat ${PID_FILE}`
-    if kill -0 $PID 2>/dev/null; then
-	echo "logsearch running with process id (${PID}). Killing..."
-	kill $PID 2>/dev/null
-	sleep 5
-	if kill -0 $PID 2>/dev/null; then
-	    echo "logsearch still running. Will kill process forcefully in another 10 seconds..."
-	    sleep 10
-	    kill -9 $PID 2>/dev/null
-	    sleep 2
-	fi
-    fi
-
-    if kill -0 $PID 2>/dev/null; then
-	echo "ERROR: Even after all efforts to stop logsearch, it is still running. pid=$PID. Please manually kill the service and try again."
-	exit 1
-    fi
-fi
-

http://git-wip-us.apache.org/repos/asf/ambari/blob/562795c4/ambari-logsearch/docker/Dockerfile
----------------------------------------------------------------------
diff --git a/ambari-logsearch/docker/Dockerfile b/ambari-logsearch/docker/Dockerfile
index e79f61b..8bfcae3 100644
--- a/ambari-logsearch/docker/Dockerfile
+++ b/ambari-logsearch/docker/Dockerfile
@@ -64,11 +64,9 @@ RUN chmod -R 777 /root/test-config
 RUN chmod +x /root/start.sh
 
 ENV SOLR_CONFIG_LOCATION /root/config/solr
-ENV LOGSEARCH_CONFIG_LOCATION /root/config/logsearch
-ENV LOGFEEDER_CONFIG_LOCATION /root/config/logfeeder
+ENV LOGSEARCH_CONF_DIR /root/config/logsearch
+ENV LOGFEEDER_CONF_DIR /root/config/logfeeder
 ENV SOLR_INCLUDE /root/config/solr/solr-env.sh
-ENV LOGSEARCH_INCLUDE /root/config/logsearch/logsearch-env.sh
-ENV LOGFEEDER_INCLUDE /root/config/logfeeder/logfeeder-env.sh
 
 RUN mkdir -p /var/run/ambari-logsearch-solr /var/log/ambari-logsearch-solr /var/run/ambari-infra-solr-client \
   /var/log/ambari-infra-solr-client /root/logsearch_solr_index/data \

http://git-wip-us.apache.org/repos/asf/ambari/blob/562795c4/ambari-logsearch/docker/all.yml
----------------------------------------------------------------------
diff --git a/ambari-logsearch/docker/all.yml b/ambari-logsearch/docker/all.yml
index 369db39..a5afb9a 100644
--- a/ambari-logsearch/docker/all.yml
+++ b/ambari-logsearch/docker/all.yml
@@ -35,6 +35,4 @@ services:
           - $MAVEN_REPOSITORY_LOCATION:/root/.m2
           - $AMBARI_LOCATION:/root/ambari
           - $AMBARI_LOCATION/ambari-logsearch/docker/test-logs:/root/test-logs
-          - $AMBARI_LOCATION/ambari-logsearch/docker/test-config:/root/test-config
-          - $AMBARI_LOCATION/ambari-logsearch/ambari-logsearch-logfeeder/target/classes:/root/ambari/ambari-logsearch/ambari-logsearch-logfeeder/target/package/classes
-          - $AMBARI_LOCATION/ambari-logsearch/ambari-logsearch-server/target/classes/org:/root/ambari/ambari-logsearch/ambari-logsearch-server/target/package/classes/org
\ No newline at end of file
+          - $AMBARI_LOCATION/ambari-logsearch/docker/test-config:/root/test-config
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/ambari/blob/562795c4/ambari-logsearch/docker/bin/start.sh
----------------------------------------------------------------------
diff --git a/ambari-logsearch/docker/bin/start.sh b/ambari-logsearch/docker/bin/start.sh
index bea06de..f2acf9b 100644
--- a/ambari-logsearch/docker/bin/start.sh
+++ b/ambari-logsearch/docker/bin/start.sh
@@ -49,6 +49,7 @@ function create_logsearch_configs() {
   mkdir /root/config/logsearch
   cp /root/test-config/logsearch/log4j.xml /root/config/logsearch/
   cp /root/test-config/logsearch/logsearch-env.sh /root/config/logsearch/
+  cp $LOGSEARCH_SERVER_PATH/conf/user_pass.json /root/config/logsearch/user_pass.json
   if [ $LOGSEARCH_HTTPS_ENABLED == 'true' ]
   then
     cp /root/test-config/logsearch/logsearch-https.properties /root/config/logsearch/logsearch.properties
@@ -87,7 +88,7 @@ function generate_keys() {
   fi
 }
 
-function start_solr() {
+function start_solr_d() {
   echo "Starting Solr..."
   /root/solr-$SOLR_VERSION/bin/solr start -cloud -s /root/logsearch_solr_index/data -verbose -force
   touch /var/log/ambari-logsearch-solr/solr.log
@@ -102,16 +103,25 @@ function start_solr() {
 }
 
 function start_logsearch() {
-  $LOGSEARCH_SERVER_PATH/run.sh
+  $LOGSEARCH_SERVER_PATH/bin/logsearch.sh start -f
+}
+
+function start_logsearch_d() {
+  $LOGSEARCH_SERVER_PATH/bin/logsearch.sh start
   touch /var/log/ambari-logsearch-portal/logsearch-app.log
 }
 
 function start_logfeeder() {
-  $LOGFEEDER_PATH/run.sh
+  $LOGFEEDER_PATH/bin/logfeeder.sh start -f
+}
+
+
+function start_logfeeder_d() {
+  $LOGFEEDER_PATH/bin/logfeeder.sh start
   touch /var/log/ambari-logsearch-logfeeder/logsearch-logfeeder.log
 }
 
-function start_selenium_server() {
+function start_selenium_server_d() {
   nohup java -jar /root/selenium-server-standalone.jar > /var/log/selenium-test.log &
 }
 
@@ -141,7 +151,7 @@ function main() {
       echo "Start Solr only.."
       export COMPONENT_LOG="solr"
       generate_keys
-      start_solr
+      start_solr_d
       log
      ;;
     "logfeeder")
@@ -150,7 +160,6 @@ function main() {
       export COMPONENT_LOG="logfeeder"
       generate_keys
       start_logfeeder
-      log
      ;;
     "logsearch")
       create_logsearch_configs
@@ -158,15 +167,14 @@ function main() {
       export COMPONENT_LOG="logsearch"
       generate_keys
       start_logsearch
-      log
      ;;
      *)
       create_configs
       generate_keys
-      start_selenium_server
-      start_solr
-      start_logfeeder
-      start_logsearch
+      start_selenium_server_d
+      start_solr_d
+      start_logfeeder_d
+      start_logsearch_d
       log
      ;;
   esac

http://git-wip-us.apache.org/repos/asf/ambari/blob/562795c4/ambari-logsearch/docker/docker-compose.yml
----------------------------------------------------------------------
diff --git a/ambari-logsearch/docker/docker-compose.yml b/ambari-logsearch/docker/docker-compose.yml
index 725af36..e865ec3 100644
--- a/ambari-logsearch/docker/docker-compose.yml
+++ b/ambari-logsearch/docker/docker-compose.yml
@@ -64,7 +64,6 @@ services:
       - $AMBARI_LOCATION:/root/ambari
       - $AMBARI_LOCATION/ambari-logsearch/docker/test-logs:/root/test-logs
       - $AMBARI_LOCATION/ambari-logsearch/docker/test-config:/root/test-config
-      - $AMBARI_LOCATION/ambari-logsearch/ambari-logsearch-server/target/classes/org:/root/ambari/ambari-logsearch/ambari-logsearch-server/target/package/classes/org
   logfeeder:
     image: ambari-logsearch:v1.0
     restart: always
@@ -83,7 +82,6 @@ services:
       - $AMBARI_LOCATION:/root/ambari
       - $AMBARI_LOCATION/ambari-logsearch/docker/test-logs:/root/test-logs
       - $AMBARI_LOCATION/ambari-logsearch/docker/test-config:/root/test-config
-      - $AMBARI_LOCATION/ambari-logsearch/ambari-logsearch-logfeeder/target/classes:/root/ambari/ambari-logsearch/ambari-logsearch-logfeeder/target/package/classes
 networks:
    logsearch-network:
       driver: bridge

http://git-wip-us.apache.org/repos/asf/ambari/blob/562795c4/ambari-logsearch/docker/logsearch-logfeeder.yml
----------------------------------------------------------------------
diff --git a/ambari-logsearch/docker/logsearch-logfeeder.yml b/ambari-logsearch/docker/logsearch-logfeeder.yml
index 4d48501..75d4391 100644
--- a/ambari-logsearch/docker/logsearch-logfeeder.yml
+++ b/ambari-logsearch/docker/logsearch-logfeeder.yml
@@ -29,7 +29,6 @@ services:
           - $AMBARI_LOCATION:/root/ambari
           - $AMBARI_LOCATION/ambari-logsearch/docker/test-logs:/root/test-logs
           - $AMBARI_LOCATION/ambari-logsearch/docker/test-config:/root/test-config
-          - $AMBARI_LOCATION/ambari-logsearch/ambari-logsearch-logfeeder/target/classes:/root/ambari/ambari-logsearch/ambari-logsearch-logfeeder/target/package/classes
 networks:
      logsearch-network:
         driver: bridge
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/ambari/blob/562795c4/ambari-logsearch/docker/logsearch-server.yml
----------------------------------------------------------------------
diff --git a/ambari-logsearch/docker/logsearch-server.yml b/ambari-logsearch/docker/logsearch-server.yml
index 6a0d71e..00c08a2 100644
--- a/ambari-logsearch/docker/logsearch-server.yml
+++ b/ambari-logsearch/docker/logsearch-server.yml
@@ -29,7 +29,6 @@ services:
           - $AMBARI_LOCATION:/root/ambari
           - $AMBARI_LOCATION/ambari-logsearch/docker/test-logs:/root/test-logs
           - $AMBARI_LOCATION/ambari-logsearch/docker/test-config:/root/test-config
-          - $AMBARI_LOCATION/ambari-logsearch/ambari-logsearch-server/target/classes/org:/root/ambari/ambari-logsearch/ambari-logsearch-server/target/package/classes/org
 networks:
      logsearch-network:
         driver: bridge
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/ambari/blob/562795c4/ambari-logsearch/docker/test-config/logfeeder/logfeeder-env.sh
----------------------------------------------------------------------
diff --git a/ambari-logsearch/docker/test-config/logfeeder/logfeeder-env.sh b/ambari-logsearch/docker/test-config/logfeeder/logfeeder-env.sh
index 5beb093..a57b1f1 100644
--- a/ambari-logsearch/docker/test-config/logfeeder/logfeeder-env.sh
+++ b/ambari-logsearch/docker/test-config/logfeeder/logfeeder-env.sh
@@ -21,10 +21,11 @@ export LOGFEEDER_PATH=/root/ambari/ambari-logsearch/ambari-logsearch-logfeeder/t
 export LOGFEEDER_CONF_DIR=/root/config/logfeeder
 
 #Logfile e.g. /var/log/logfeeder.log
-export LOGFILE=/var/log/ambari-logsearch-logfeeder/logfeeder.out
+export LOG_PATH=/var/log/ambari-logsearch-logfeeder
+export LOG_FILE=logfeeder.out
 
 #pid file e.g. /var/run/logfeeder.pid
-export PID_FILE=/var/run/ambari-logsearch-logfeeder/logfeeder.pid
+export LOGFEEDER_PID_FILE=/var/run/ambari-logsearch-logfeeder/logfeeder.pid
 
 export JAVA_HOME=/usr/java/default
 

http://git-wip-us.apache.org/repos/asf/ambari/blob/562795c4/ambari-logsearch/docker/test-config/logfeeder/logfeeder.properties
----------------------------------------------------------------------
diff --git a/ambari-logsearch/docker/test-config/logfeeder/logfeeder.properties b/ambari-logsearch/docker/test-config/logfeeder/logfeeder.properties
index 1ae57bb..028cb9f 100644
--- a/ambari-logsearch/docker/test-config/logfeeder/logfeeder.properties
+++ b/ambari-logsearch/docker/test-config/logfeeder/logfeeder.properties
@@ -16,7 +16,7 @@
 cluster.name=cl1
 logfeeder.checkpoint.folder=/root/checkpoints
 logfeeder.metrics.collector.hosts=
-logfeeder.config.dir=/root/test-config/logfeeder/shipper-conf/
+logfeeder.config.dir=/root/config/logfeeder/shipper-conf/
 logfeeder.config.files=shipper-conf/global.config.json,\
   shipper-conf/output.config.json
 logfeeder.log.filter.enable=true

http://git-wip-us.apache.org/repos/asf/ambari/blob/562795c4/ambari-logsearch/docker/test-config/logsearch/logsearch-env.sh
----------------------------------------------------------------------
diff --git a/ambari-logsearch/docker/test-config/logsearch/logsearch-env.sh b/ambari-logsearch/docker/test-config/logsearch/logsearch-env.sh
index 80f9c4c..2a2efd8 100644
--- a/ambari-logsearch/docker/test-config/logsearch/logsearch-env.sh
+++ b/ambari-logsearch/docker/test-config/logsearch/logsearch-env.sh
@@ -20,9 +20,10 @@ export LOGSEARCH_PATH=/root/ambari/ambari-logsearch/ambari-logsearch-server/targ
 
 export LOGSEARCH_CONF_DIR=/root/config/logsearch
 
-export LOGFILE=/var/log/ambari-logsearch-portal/logsearch-app.log
+export LOG_PATH=/var/log/ambari-logsearch-portal
+export LOG_FILE=logsearch-app.log
 
-export PID_FILE=/var/run/ambari-logsearch-portal/logsearch.pid
+export LOGSEARCH_PID_FILE=/var/run/ambari-logsearch-portal/logsearch.pid
 
 export JAVA_HOME=/usr/java/default
 

http://git-wip-us.apache.org/repos/asf/ambari/blob/562795c4/ambari-logsearch/docker/test-config/logsearch/logsearch-https.properties
----------------------------------------------------------------------
diff --git a/ambari-logsearch/docker/test-config/logsearch/logsearch-https.properties b/ambari-logsearch/docker/test-config/logsearch/logsearch-https.properties
index 5e7853d..6b59ac8 100644
--- a/ambari-logsearch/docker/test-config/logsearch/logsearch-https.properties
+++ b/ambari-logsearch/docker/test-config/logsearch/logsearch-https.properties
@@ -36,8 +36,8 @@ logsearch.solr.collection.history=history
 logsearch.solr.history.config.name=history
 logsearch.collection.history.replication.factor=1
 
-logsearch.solr.config_set.folder=/root/ambari/ambari-logsearch/ambari-logsearch-server/target/package/solr_configsets
-logsearch.solr.audit.logs.config_set.folder=/root/ambari/ambari-logsearch/ambari-logsearch-server/target/package/solr_configsets
+logsearch.solr.config_set.folder=/root/ambari/ambari-logsearch/ambari-logsearch-server/target/package/conf/solr_configsets
+logsearch.solr.audit.logs.config_set.folder=/root/ambari/ambari-logsearch/ambari-logsearch-server/target/package/conf/solr_configsets
 
 # Metrics
 logsearch.solr.metrics.collector.hosts=

http://git-wip-us.apache.org/repos/asf/ambari/blob/562795c4/ambari-logsearch/docker/test-config/logsearch/logsearch.properties
----------------------------------------------------------------------
diff --git a/ambari-logsearch/docker/test-config/logsearch/logsearch.properties b/ambari-logsearch/docker/test-config/logsearch/logsearch.properties
index 5bde17c..22edf76 100644
--- a/ambari-logsearch/docker/test-config/logsearch/logsearch.properties
+++ b/ambari-logsearch/docker/test-config/logsearch/logsearch.properties
@@ -31,8 +31,8 @@ logsearch.audit.logs.split.interval.mins=15
 logsearch.collection.audit.logs.numshards=3
 logsearch.collection.audit.logs.replication.factor=2
 
-logsearch.solr.config_set.folder=/root/ambari/ambari-logsearch/ambari-logsearch-server/target/package/solr_configsets
-logsearch.solr.audit.logs.config_set.folder=/root/ambari/ambari-logsearch/ambari-logsearch-server/target/package/solr_configsets
+logsearch.solr.config_set.folder=/root/ambari/ambari-logsearch/ambari-logsearch-server/target/package/conf/solr_configsets
+logsearch.solr.audit.logs.config_set.folder=/root/ambari/ambari-logsearch/ambari-logsearch-server/target/package/conf/solr_configsets
 
 # History logs
 logsearch.solr.collection.history=history

http://git-wip-us.apache.org/repos/asf/ambari/blob/562795c4/ambari-server/src/main/resources/common-services/LOGSEARCH/0.5.0/configuration/logfeeder-env.xml
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/common-services/LOGSEARCH/0.5.0/configuration/logfeeder-env.xml b/ambari-server/src/main/resources/common-services/LOGSEARCH/0.5.0/configuration/logfeeder-env.xml
index e308479..4afd7b6 100644
--- a/ambari-server/src/main/resources/common-services/LOGSEARCH/0.5.0/configuration/logfeeder-env.xml
+++ b/ambari-server/src/main/resources/common-services/LOGSEARCH/0.5.0/configuration/logfeeder-env.xml
@@ -160,6 +160,6 @@
       <property-file-name>logfeeder-env.sh.j2</property-file-name>
       <property-file-type>text</property-file-type>
     </value-attributes>
-    <on-ambari-upgrade add="true"/>
+    <on-ambari-upgrade add="true" update="true"/>
   </property>
 </configuration>

http://git-wip-us.apache.org/repos/asf/ambari/blob/562795c4/ambari-server/src/main/resources/common-services/LOGSEARCH/0.5.0/configuration/logfeeder-properties.xml
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/common-services/LOGSEARCH/0.5.0/configuration/logfeeder-properties.xml b/ambari-server/src/main/resources/common-services/LOGSEARCH/0.5.0/configuration/logfeeder-properties.xml
index a38f961..b43aaa6 100644
--- a/ambari-server/src/main/resources/common-services/LOGSEARCH/0.5.0/configuration/logfeeder-properties.xml
+++ b/ambari-server/src/main/resources/common-services/LOGSEARCH/0.5.0/configuration/logfeeder-properties.xml
@@ -29,7 +29,7 @@
   </property>
   <property>
     <name>logfeeder.checkpoint.folder</name>
-    <value>/etc/ambari-logsearch-logfeeder/conf/checkpoints</value>
+    <value>/usr/lib/ambari-logsearch-logfeeder/conf/checkpoints</value>
     <description>Checkpoint folder for Log Feeder</description>
     <display-name>Log Feeder checkpoint dir</display-name>
     <value-attributes>

http://git-wip-us.apache.org/repos/asf/ambari/blob/562795c4/ambari-server/src/main/resources/common-services/LOGSEARCH/0.5.0/configuration/logsearch-env.xml
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/common-services/LOGSEARCH/0.5.0/configuration/logsearch-env.xml b/ambari-server/src/main/resources/common-services/LOGSEARCH/0.5.0/configuration/logsearch-env.xml
index 5c263db..cfc3504 100644
--- a/ambari-server/src/main/resources/common-services/LOGSEARCH/0.5.0/configuration/logsearch-env.xml
+++ b/ambari-server/src/main/resources/common-services/LOGSEARCH/0.5.0/configuration/logsearch-env.xml
@@ -107,7 +107,7 @@
   </property>
   <property>
     <name>logsearch_truststore_location</name>
-    <value>/etc/ambari-logsearch-portal/conf/keys/logsearch.jks</value>
+    <value>/usr/lib/ambari-logsearch-portal/conf/keys/logsearch.jks</value>
     <display-name>Log Search trust store location</display-name>
     <description>Location of the trust store file.</description>
     <on-ambari-upgrade add="true"/>
@@ -133,7 +133,7 @@
   </property>
   <property>
     <name>logsearch_keystore_location</name>
-    <value>/etc/ambari-logsearch-portal/conf/keys/logsearch.jks</value>
+    <value>/usr/lib/ambari-logsearch-portal/conf/keys/logsearch.jks</value>
     <display-name>Log Search key store location</display-name>
     <description>Location of the key store file.</description>
     <on-ambari-upgrade add="true"/>
@@ -183,6 +183,6 @@
       <property-file-name>logsearch-env.sh.j2</property-file-name>
       <property-file-type>text</property-file-type>
     </value-attributes>
-    <on-ambari-upgrade add="true"/>
+    <on-ambari-upgrade add="true" update="true"/>
   </property>
 </configuration>

http://git-wip-us.apache.org/repos/asf/ambari/blob/562795c4/ambari-server/src/main/resources/common-services/LOGSEARCH/0.5.0/package/scripts/logfeeder.py
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/common-services/LOGSEARCH/0.5.0/package/scripts/logfeeder.py b/ambari-server/src/main/resources/common-services/LOGSEARCH/0.5.0/package/scripts/logfeeder.py
index fbc29c8..2f6c13c 100644
--- a/ambari-server/src/main/resources/common-services/LOGSEARCH/0.5.0/package/scripts/logfeeder.py
+++ b/ambari-server/src/main/resources/common-services/LOGSEARCH/0.5.0/package/scripts/logfeeder.py
@@ -23,7 +23,6 @@ from resource_management.libraries.functions.format import format
 from resource_management.libraries.functions.check_process_status import check_process_status
 from resource_management.libraries.script.script import Script
 from setup_logfeeder import setup_logfeeder
-from logsearch_common import kill_process
 
 class LogFeeder(Script):
   def install(self, env):
@@ -43,15 +42,15 @@ class LogFeeder(Script):
     env.set_params(params)
     self.configure(env)
 
-    Execute((format('{logfeeder_dir}/run.sh'),),
-            environment={'LOGFEEDER_INCLUDE': format('{logsearch_logfeeder_conf}/logfeeder-env.sh')},
+    Execute((format('{logfeeder_dir}/bin/logfeeder.sh start'),),
             sudo=True)
 
   def stop(self, env, upgrade_type=None):
     import params
     env.set_params(params)
 
-    kill_process(params.logfeeder_pid_file, getpass.getuser(), params.logfeeder_log_dir)
+    Execute((format('{logfeeder_dir}/bin/logfeeder.sh stop'),),
+            sudo=True)
 
   def status(self, env):
     import status_params

http://git-wip-us.apache.org/repos/asf/ambari/blob/562795c4/ambari-server/src/main/resources/common-services/LOGSEARCH/0.5.0/package/scripts/logsearch.py
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/common-services/LOGSEARCH/0.5.0/package/scripts/logsearch.py b/ambari-server/src/main/resources/common-services/LOGSEARCH/0.5.0/package/scripts/logsearch.py
index 4410712..a276357 100644
--- a/ambari-server/src/main/resources/common-services/LOGSEARCH/0.5.0/package/scripts/logsearch.py
+++ b/ambari-server/src/main/resources/common-services/LOGSEARCH/0.5.0/package/scripts/logsearch.py
@@ -22,7 +22,6 @@ from resource_management.libraries.functions.check_process_status import check_p
 from resource_management.libraries.functions.format import format
 from resource_management.libraries.script.script import Script
 from setup_logsearch import setup_logsearch
-from logsearch_common import kill_process
 
 class LogSearch(Script):
   def install(self, env):
@@ -41,8 +40,7 @@ class LogSearch(Script):
     env.set_params(params)
     self.configure(env)
 
-    Execute(format("{logsearch_dir}/run.sh"),
-            environment={'LOGSEARCH_INCLUDE': format('{logsearch_server_conf}/logsearch-env.sh')},
+    Execute(format("{logsearch_dir}/bin/logsearch.sh start"),
             user=params.logsearch_user
             )
 
@@ -50,7 +48,9 @@ class LogSearch(Script):
     import params
     env.set_params(params)
 
-    kill_process(params.logsearch_pid_file, params.logsearch_user, params.logsearch_log_dir)
+    Execute(format("{logsearch_dir}/bin/logsearch.sh stop"),
+            user=params.logsearch_user
+            )
 
   def status(self, env):
     import status_params

http://git-wip-us.apache.org/repos/asf/ambari/blob/562795c4/ambari-server/src/main/resources/common-services/LOGSEARCH/0.5.0/package/scripts/logsearch_common.py
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/common-services/LOGSEARCH/0.5.0/package/scripts/logsearch_common.py b/ambari-server/src/main/resources/common-services/LOGSEARCH/0.5.0/package/scripts/logsearch_common.py
deleted file mode 100644
index c4e0c16..0000000
--- a/ambari-server/src/main/resources/common-services/LOGSEARCH/0.5.0/package/scripts/logsearch_common.py
+++ /dev/null
@@ -1,54 +0,0 @@
-"""
-Licensed to the Apache Software Foundation (ASF) under one
-or more contributor license agreements.  See the NOTICE file
-distributed with this work for additional information
-regarding copyright ownership.  The ASF licenses this file
-to you 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.
-
-"""
-
-from resource_management.core.resources.system import Execute, File
-from resource_management.libraries.functions.format import format
-from resource_management.libraries.functions.get_user_call_output import get_user_call_output
-from resource_management.libraries.functions.show_logs import show_logs
-
-def kill_process(pid_file, user, log_dir):
-  import params
-  """
-  Kill the process by pid file, then check the process is running or not. If the process is still running after the kill
-  command, it will try to kill with -9 option (hard kill)
-  """
-  pid = get_user_call_output(format("cat {pid_file}"), user=user, is_checked_call=False)[1]
-  process_id_exists_command = format("ls {pid_file} >/dev/null 2>&1 && ps -p {pid} >/dev/null 2>&1")
-
-  kill_cmd = format("{sudo} kill {pid}")
-  Execute(kill_cmd,
-          not_if=format("! ({process_id_exists_command})"))
-  wait_time = 5
-
-  hard_kill_cmd = format("{sudo} kill -9 {pid}")
-  Execute(hard_kill_cmd,
-          not_if=format("! ({process_id_exists_command}) || ( sleep {wait_time} && ! ({process_id_exists_command}) )"),
-          ignore_failures = True)
-  try:
-    Execute(format("! ({process_id_exists_command})"),
-            tries=20,
-            try_sleep=3,
-            )
-  except:
-    show_logs(log_dir, user)
-    raise
-
-  File(pid_file,
-       action="delete"
-       )
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/ambari/blob/562795c4/ambari-server/src/main/resources/common-services/LOGSEARCH/0.5.0/package/scripts/params.py
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/common-services/LOGSEARCH/0.5.0/package/scripts/params.py b/ambari-server/src/main/resources/common-services/LOGSEARCH/0.5.0/package/scripts/params.py
index 884d32a..4ea2018 100644
--- a/ambari-server/src/main/resources/common-services/LOGSEARCH/0.5.0/package/scripts/params.py
+++ b/ambari-server/src/main/resources/common-services/LOGSEARCH/0.5.0/package/scripts/params.py
@@ -56,9 +56,9 @@ credential_store_enabled = False
 if 'credentialStoreEnabled' in config:
   credential_store_enabled = config['credentialStoreEnabled']
 
-logsearch_server_conf = "/etc/ambari-logsearch-portal/conf"
+logsearch_server_conf = "/usr/lib/ambari-logsearch-portal/conf"
 logsearch_server_keys_folder = logsearch_server_conf + "/keys"
-logsearch_logfeeder_conf = "/etc/ambari-logsearch-logfeeder/conf"
+logsearch_logfeeder_conf = "/usr/lib/ambari-logsearch-logfeeder/conf"
 logsearch_logfeeder_keys_folder = logsearch_logfeeder_conf + "/keys"
 
 logsearch_config_set_dir = format("{logsearch_server_conf}/solr_configsets")
@@ -170,7 +170,7 @@ zookeeper_quorum = logsearch_solr_zk_quorum
 # logsearch-env configs
 logsearch_user = config['configurations']['logsearch-env']['logsearch_user']
 logsearch_log_dir = config['configurations']['logsearch-env']['logsearch_log_dir']
-logsearch_log = logsearch_log_dir + '/logsearch.out'
+logsearch_log = 'logsearch.out'
 logsearch_debug_enabled = str(config['configurations']['logsearch-env']["logsearch_debug_enabled"]).lower()
 logsearch_debug_port = config['configurations']['logsearch-env']["logsearch_debug_port"]
 logsearch_app_max_memory = config['configurations']['logsearch-env']['logsearch_app_max_memory']
@@ -304,7 +304,7 @@ logfeeder_json_log_maxbackupindex = default('/configurations/logfeeder-log4j/log
 
 # logfeeder-env configs
 logfeeder_log_dir = config['configurations']['logfeeder-env']['logfeeder_log_dir']
-logfeeder_log = logfeeder_log_dir + '/logfeeder.out'
+logfeeder_log = 'logfeeder.out'
 logfeeder_max_mem = config['configurations']['logfeeder-env']['logfeeder_max_mem']
 solr_service_logs_enable = default('/configurations/logfeeder-env/logfeeder_solr_service_logs_enable', True)
 solr_audit_logs_enable = default('/configurations/logfeeder-env/logfeeder_solr_audit_logs_enable', True)

http://git-wip-us.apache.org/repos/asf/ambari/blob/562795c4/ambari-server/src/main/resources/common-services/LOGSEARCH/0.5.0/package/scripts/setup_logfeeder.py
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/common-services/LOGSEARCH/0.5.0/package/scripts/setup_logfeeder.py b/ambari-server/src/main/resources/common-services/LOGSEARCH/0.5.0/package/scripts/setup_logfeeder.py
index 653d604..52b1d76 100644
--- a/ambari-server/src/main/resources/common-services/LOGSEARCH/0.5.0/package/scripts/setup_logfeeder.py
+++ b/ambari-server/src/main/resources/common-services/LOGSEARCH/0.5.0/package/scripts/setup_logfeeder.py
@@ -40,7 +40,7 @@ def setup_logfeeder():
             recursive_ownership=True
             )
 
-  File(params.logfeeder_log,
+  File(format("{logfeeder_log_dir}/{logfeeder_log}"),
        mode=0644,
        content=''
        )

http://git-wip-us.apache.org/repos/asf/ambari/blob/562795c4/ambari-server/src/main/resources/common-services/LOGSEARCH/0.5.0/package/scripts/setup_logsearch.py
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/common-services/LOGSEARCH/0.5.0/package/scripts/setup_logsearch.py b/ambari-server/src/main/resources/common-services/LOGSEARCH/0.5.0/package/scripts/setup_logsearch.py
index 7738cc1..e804b9a 100644
--- a/ambari-server/src/main/resources/common-services/LOGSEARCH/0.5.0/package/scripts/setup_logsearch.py
+++ b/ambari-server/src/main/resources/common-services/LOGSEARCH/0.5.0/package/scripts/setup_logsearch.py
@@ -53,7 +53,7 @@ def setup_logsearch():
             owner=params.logsearch_user,
             group=params.user_group)
 
-  File(params.logsearch_log,
+  File(format("{logsearch_log_dir}/{logsearch_log}"),
        mode=0644,
        owner=params.logsearch_user,
        group=params.user_group,

http://git-wip-us.apache.org/repos/asf/ambari/blob/562795c4/ambari-server/src/main/resources/common-services/LOGSEARCH/0.5.0/properties/logfeeder-env.sh.j2
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/common-services/LOGSEARCH/0.5.0/properties/logfeeder-env.sh.j2 b/ambari-server/src/main/resources/common-services/LOGSEARCH/0.5.0/properties/logfeeder-env.sh.j2
index f2dd06b..f9f7e40 100644
--- a/ambari-server/src/main/resources/common-services/LOGSEARCH/0.5.0/properties/logfeeder-env.sh.j2
+++ b/ambari-server/src/main/resources/common-services/LOGSEARCH/0.5.0/properties/logfeeder-env.sh.j2
@@ -21,10 +21,11 @@ export LOGFEEDER_PATH={{logfeeder_dir}}
 export LOGFEEDER_CONF_DIR={{logsearch_logfeeder_conf}}
 
 #Logfile e.g. /var/log/logfeeder.log
-export LOGFILE={{logfeeder_log}}
+export LOG_PATH={{logfeeder_log_dir}}
+export LOG_FILE={{logfeeder_log}}
 
 #pid file e.g. /var/run/logfeeder.pid
-export PID_FILE={{logfeeder_pid_file}}
+export LOGFEEDER_PID_FILE={{logfeeder_pid_file}}
 
 export JAVA_HOME={{java64_home}}
 

http://git-wip-us.apache.org/repos/asf/ambari/blob/562795c4/ambari-server/src/main/resources/common-services/LOGSEARCH/0.5.0/properties/logsearch-env.sh.j2
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/common-services/LOGSEARCH/0.5.0/properties/logsearch-env.sh.j2 b/ambari-server/src/main/resources/common-services/LOGSEARCH/0.5.0/properties/logsearch-env.sh.j2
index 7d9b5de..e823094 100644
--- a/ambari-server/src/main/resources/common-services/LOGSEARCH/0.5.0/properties/logsearch-env.sh.j2
+++ b/ambari-server/src/main/resources/common-services/LOGSEARCH/0.5.0/properties/logsearch-env.sh.j2
@@ -21,9 +21,10 @@ export LOGSEARCH_PATH={{logsearch_dir}}
 
 export LOGSEARCH_CONF_DIR={{logsearch_server_conf}}
 
-export LOGFILE={{logsearch_log_dir}}/logsearch.log
+export LOG_PATH={{logsearch_log_dir}}
+export LOG_FILE={{logsearch_log}}
 
-export PID_FILE={{logsearch_pid_file}}
+export LOGSEARCH_PID_FILE={{logsearch_pid_file}}
 
 export JAVA_HOME={{java64_home}}
 

http://git-wip-us.apache.org/repos/asf/ambari/blob/562795c4/ambari-server/src/main/resources/stack-hooks/after-INSTALL/scripts/params.py
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/stack-hooks/after-INSTALL/scripts/params.py b/ambari-server/src/main/resources/stack-hooks/after-INSTALL/scripts/params.py
index bf9d79b..4eecfa2 100644
--- a/ambari-server/src/main/resources/stack-hooks/after-INSTALL/scripts/params.py
+++ b/ambari-server/src/main/resources/stack-hooks/after-INSTALL/scripts/params.py
@@ -47,7 +47,7 @@ major_stack_version = get_major_version(stack_version_formatted)
 service_name = config['serviceName']
 
 # logsearch configuration
-logsearch_logfeeder_conf = "/etc/ambari-logsearch-logfeeder/conf"
+logsearch_logfeeder_conf = "/usr/lib/ambari-logsearch-logfeeder/conf"
 
 agent_cache_dir = config['hostLevelParams']['agentCacheDir']
 service_package_folder = config['commandParams']['service_package_folder']

http://git-wip-us.apache.org/repos/asf/ambari/blob/562795c4/ambari-server/src/test/python/stacks/2.0.6/hooks/after-INSTALL/test_after_install.py
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/python/stacks/2.0.6/hooks/after-INSTALL/test_after_install.py b/ambari-server/src/test/python/stacks/2.0.6/hooks/after-INSTALL/test_after_install.py
index 19c81a8..1f1d3f7 100644
--- a/ambari-server/src/test/python/stacks/2.0.6/hooks/after-INSTALL/test_after_install.py
+++ b/ambari-server/src/test/python/stacks/2.0.6/hooks/after-INSTALL/test_after_install.py
@@ -58,7 +58,7 @@ class TestHookAfterInstall(RMFTestCase):
                               configuration_attributes = self.getConfig()['configuration_attributes']['core-site'],
                               only_if="ls /etc/hadoop/conf")
     self.assertResourceCalled('Directory',
-                              '/etc/ambari-logsearch-logfeeder/conf',
+                              '/usr/lib/ambari-logsearch-logfeeder/conf',
                               mode = 0755,
                               cd_access = 'a',
                               create_parents = True)
@@ -106,7 +106,7 @@ class TestHookAfterInstall(RMFTestCase):
       only_if="ls /usr/hdp/2.3.0.0-1234/hadoop/conf")
 
     self.assertResourceCalled('Directory',
-                              '/etc/ambari-logsearch-logfeeder/conf',
+                              '/usr/lib/ambari-logsearch-logfeeder/conf',
                               mode = 0755,
                               cd_access = 'a',
                               create_parents = True)
@@ -174,7 +174,7 @@ class TestHookAfterInstall(RMFTestCase):
       only_if="ls /usr/hdp/2.3.0.0-1234/hadoop/conf")
 
     self.assertResourceCalled('Directory',
-                              '/etc/ambari-logsearch-logfeeder/conf',
+                              '/usr/lib/ambari-logsearch-logfeeder/conf',
                               mode = 0755,
                               cd_access = 'a',
                               create_parents = True)
@@ -277,7 +277,7 @@ class TestHookAfterInstall(RMFTestCase):
       only_if="ls /usr/hdp/2.3.0.0-1234/hadoop/conf")
 
     self.assertResourceCalled('Directory',
-                              '/etc/ambari-logsearch-logfeeder/conf',
+                              '/usr/lib/ambari-logsearch-logfeeder/conf',
                               mode = 0755,
                               cd_access = 'a',
                               create_parents = True)

http://git-wip-us.apache.org/repos/asf/ambari/blob/562795c4/ambari-server/src/test/python/stacks/2.4/LOGSEARCH/test_logfeeder.py
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/python/stacks/2.4/LOGSEARCH/test_logfeeder.py b/ambari-server/src/test/python/stacks/2.4/LOGSEARCH/test_logfeeder.py
index 159cb81..13774f7 100644
--- a/ambari-server/src/test/python/stacks/2.4/LOGSEARCH/test_logfeeder.py
+++ b/ambari-server/src/test/python/stacks/2.4/LOGSEARCH/test_logfeeder.py
@@ -37,7 +37,7 @@ class TestLogFeeder(RMFTestCase):
                               cd_access='a',
                               mode=0755
                               )
-    self.assertResourceCalled('Directory', '/etc/ambari-logsearch-logfeeder/conf/checkpoints',
+    self.assertResourceCalled('Directory', '/usr/lib/ambari-logsearch-logfeeder/conf/checkpoints',
                               create_parents=True,
                               cd_access='a',
                               mode=0755
@@ -49,7 +49,7 @@ class TestLogFeeder(RMFTestCase):
                               cd_access='a',
                               mode=0755
                               )
-    self.assertResourceCalled('Directory', '/etc/ambari-logsearch-logfeeder/conf',
+    self.assertResourceCalled('Directory', '/usr/lib/ambari-logsearch-logfeeder/conf',
                               create_parents=True,
                               recursive_ownership=True,
                               cd_access='a',
@@ -60,18 +60,18 @@ class TestLogFeeder(RMFTestCase):
                               mode=0644,
                               content=''
                               )
-    self.assertResourceCalled('File', '/etc/ambari-logsearch-logfeeder/conf/keys/ks_pass.txt',
+    self.assertResourceCalled('File', '/usr/lib/ambari-logsearch-logfeeder/conf/keys/ks_pass.txt',
                               action = ['delete']
                               )
-    self.assertResourceCalled('File', '/etc/ambari-logsearch-logfeeder/conf/keys/ts_pass.txt',
+    self.assertResourceCalled('File', '/usr/lib/ambari-logsearch-logfeeder/conf/keys/ts_pass.txt',
                               action = ['delete']
                               )
-    self.assertResourceCalled('PropertiesFile', '/etc/ambari-logsearch-logfeeder/conf/logfeeder.properties',
+    self.assertResourceCalled('PropertiesFile', '/usr/lib/ambari-logsearch-logfeeder/conf/logfeeder.properties',
                               properties={'cluster.name': 'c1',
                                           'common-property': 'common-value',
-                                          'hadoop.security.credential.provider.path': 'jceks://file/etc/ambari-logsearch-logfeeder/conf/logfeeder.jceks',
-                                          'logfeeder.checkpoint.folder': '/etc/ambari-logsearch-logfeeder/conf/checkpoints',
-                                          'logfeeder.config.dir': '/etc/ambari-logsearch-logfeeder/conf',
+                                          'hadoop.security.credential.provider.path': 'jceks://file/usr/lib/ambari-logsearch-logfeeder/conf/logfeeder.jceks',
+                                          'logfeeder.checkpoint.folder': '/usr/lib/ambari-logsearch-logfeeder/conf/checkpoints',
+                                          'logfeeder.config.dir': '/usr/lib/ambari-logsearch-logfeeder/conf',
                                           'logfeeder.config.files': 'output.config.json,global.config.json',
                                           'logfeeder.metrics.collector.hosts': '',
                                           'logfeeder.metrics.collector.path': '/ws/v1/timeline/metrics',
@@ -82,25 +82,25 @@ class TestLogFeeder(RMFTestCase):
                                           'logsearch.config.zk_connect_string': 'c6401.ambari.apache.org:2181'
                                          }
                               )
-    self.assertResourceCalled('File', '/etc/ambari-logsearch-logfeeder/conf/logfeeder-env.sh',
+    self.assertResourceCalled('File', '/usr/lib/ambari-logsearch-logfeeder/conf/logfeeder-env.sh',
                               mode=0755,
                               content=InlineTemplate(self.getConfig()['configurations']['logfeeder-env']['content'])
                               )
-    self.assertResourceCalled('File', '/etc/ambari-logsearch-logfeeder/conf/log4j.xml',
+    self.assertResourceCalled('File', '/usr/lib/ambari-logsearch-logfeeder/conf/log4j.xml',
                               content=InlineTemplate(self.getConfig()['configurations']['logfeeder-log4j']['content'])
                               )
-    self.assertResourceCalled('File', '/etc/ambari-logsearch-logfeeder/conf/grok-patterns',
+    self.assertResourceCalled('File', '/usr/lib/ambari-logsearch-logfeeder/conf/grok-patterns',
                               content=InlineTemplate('GP'),
                               encoding='utf-8'
                               )
-    self.assertResourceCalled('File', '/etc/ambari-logsearch-logfeeder/conf/global.config.json',
+    self.assertResourceCalled('File', '/usr/lib/ambari-logsearch-logfeeder/conf/global.config.json',
                               content=Template('global.config.json.j2')
                               )
-    self.assertResourceCalled('File', '/etc/ambari-logsearch-logfeeder/conf/input.config-ambari.json',
+    self.assertResourceCalled('File', '/usr/lib/ambari-logsearch-logfeeder/conf/input.config-ambari.json',
                               content=InlineTemplate('ambari-grok-filter'),
                               encoding='utf-8'
                               )
-    self.assertResourceCalled('File', '/etc/ambari-logsearch-logfeeder/conf/output.config.json',
+    self.assertResourceCalled('File', '/usr/lib/ambari-logsearch-logfeeder/conf/output.config.json',
                               content=InlineTemplate('output-grok-filter'),
                               encoding='utf-8'
                               )
@@ -127,8 +127,6 @@ class TestLogFeeder(RMFTestCase):
                        )
 
     self.configureResourcesCalled()
-    self.assertResourceCalled('Execute', ('/usr/lib/ambari-logsearch-logfeeder/run.sh',),
-                              sudo=True,
-                              environment={
-                                'LOGFEEDER_INCLUDE': '/etc/ambari-logsearch-logfeeder/conf/logfeeder-env.sh'}
+    self.assertResourceCalled('Execute', ('/usr/lib/ambari-logsearch-logfeeder/bin/logfeeder.sh start',),
+                              sudo=True
                               )

http://git-wip-us.apache.org/repos/asf/ambari/blob/562795c4/ambari-server/src/test/python/stacks/2.4/LOGSEARCH/test_logsearch.py
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/python/stacks/2.4/LOGSEARCH/test_logsearch.py b/ambari-server/src/test/python/stacks/2.4/LOGSEARCH/test_logsearch.py
index db19e0f..292773b 100644
--- a/ambari-server/src/test/python/stacks/2.4/LOGSEARCH/test_logsearch.py
+++ b/ambari-server/src/test/python/stacks/2.4/LOGSEARCH/test_logsearch.py
@@ -47,7 +47,7 @@ class TestLogSearch(RMFTestCase):
                               cd_access = 'a',
                               mode = 0755
     )
-    self.assertResourceCalled('Directory', '/etc/ambari-logsearch-portal/conf',
+    self.assertResourceCalled('Directory', '/usr/lib/ambari-logsearch-portal/conf',
                               owner = 'logsearch',
                               group = 'hadoop',
                               create_parents = True,
@@ -55,7 +55,7 @@ class TestLogSearch(RMFTestCase):
                               cd_access = 'a',
                               mode = 0755
     )
-    self.assertResourceCalled('Directory', '/etc/ambari-logsearch-portal/conf/solr_configsets',
+    self.assertResourceCalled('Directory', '/usr/lib/ambari-logsearch-portal/conf/solr_configsets',
                               owner = 'logsearch',
                               group = 'hadoop',
                               create_parents = True,
@@ -63,7 +63,7 @@ class TestLogSearch(RMFTestCase):
                               cd_access = 'a',
                               mode = 0755
                               )
-    self.assertResourceCalled('Directory', '/etc/ambari-logsearch-portal/conf/keys',
+    self.assertResourceCalled('Directory', '/usr/lib/ambari-logsearch-portal/conf/keys',
                               owner = 'logsearch',
                               group = 'hadoop',
                               cd_access = 'a',
@@ -76,15 +76,15 @@ class TestLogSearch(RMFTestCase):
                               mode = 0644,
                               content = ''
     )
-    self.assertResourceCalled('File', '/etc/ambari-logsearch-portal/conf/keys/ks_pass.txt',
+    self.assertResourceCalled('File', '/usr/lib/ambari-logsearch-portal/conf/keys/ks_pass.txt',
                               action = ['delete']
     )
-    self.assertResourceCalled('File', '/etc/ambari-logsearch-portal/conf/keys/ts_pass.txt',
+    self.assertResourceCalled('File', '/usr/lib/ambari-logsearch-portal/conf/keys/ts_pass.txt',
                               action = ['delete']
     )
-    self.assertResourceCalled('PropertiesFile', '/etc/ambari-logsearch-portal/conf/logsearch.properties',
+    self.assertResourceCalled('PropertiesFile', '/usr/lib/ambari-logsearch-portal/conf/logsearch.properties',
                               properties = {'common-property': 'common-value',
-                                            'hadoop.security.credential.provider.path': 'jceks://file/etc/ambari-logsearch-portal/conf/logsearch.jceks',
+                                            'hadoop.security.credential.provider.path': 'jceks://file/usr/lib/ambari-logsearch-portal/conf/logsearch.jceks',
                                             'logsearch.audit.logs.split.interval.mins': '1',
                                             'logsearch.auth.external_auth.enabled': 'false',
                                             'logsearch.auth.external_auth.host_url': 'http://c6401.ambari.apache.org:8080',
@@ -115,38 +115,38 @@ class TestLogSearch(RMFTestCase):
                                             'logsearch.spnego.kerberos.host': 'localhost'
                               }
     )
-    self.assertResourceCalled('File', '/etc/ambari-logsearch-portal/conf/HadoopServiceConfig.json',
+    self.assertResourceCalled('File', '/usr/lib/ambari-logsearch-portal/conf/HadoopServiceConfig.json',
                               owner = 'logsearch',
                               group='hadoop',
                               content = Template('HadoopServiceConfig.json.j2')
     )
-    self.assertResourceCalled('File', '/etc/ambari-logsearch-portal/conf/log4j.xml',
+    self.assertResourceCalled('File', '/usr/lib/ambari-logsearch-portal/conf/log4j.xml',
                               owner = 'logsearch',
                               group='hadoop',
                               content = InlineTemplate(self.getConfig()['configurations']['logsearch-log4j']['content'])
     )
-    self.assertResourceCalled('File', '/etc/ambari-logsearch-portal/conf/logsearch-env.sh',
+    self.assertResourceCalled('File', '/usr/lib/ambari-logsearch-portal/conf/logsearch-env.sh',
                               content = InlineTemplate(self.getConfig()['configurations']['logsearch-env']['content']),
                               mode = 0755,
                               owner = "logsearch",
                               group='hadoop'
     )
-    self.assertResourceCalled('File', '/etc/ambari-logsearch-portal/conf/logsearch-admin.json',
+    self.assertResourceCalled('File', '/usr/lib/ambari-logsearch-portal/conf/logsearch-admin.json',
                               owner = 'logsearch',
                               group='hadoop',
                               content = InlineTemplate(self.getConfig()['configurations']['logsearch-admin-json']['content'])
                               )
-    self.assertResourceCalled('File', '/etc/ambari-logsearch-portal/conf/solr_configsets/hadoop_logs/conf/solrconfig.xml',
+    self.assertResourceCalled('File', '/usr/lib/ambari-logsearch-portal/conf/solr_configsets/hadoop_logs/conf/solrconfig.xml',
                               owner = 'logsearch',
                               group='hadoop',
                               content = InlineTemplate(self.getConfig()['configurations']['logsearch-service_logs-solrconfig']['content'])
     )
-    self.assertResourceCalled('File', '/etc/ambari-logsearch-portal/conf/solr_configsets/audit_logs/conf/solrconfig.xml',
+    self.assertResourceCalled('File', '/usr/lib/ambari-logsearch-portal/conf/solr_configsets/audit_logs/conf/solrconfig.xml',
                               owner = 'logsearch',
                               group='hadoop',
                               content = InlineTemplate(self.getConfig()['configurations']['logsearch-audit_logs-solrconfig']['content'])
                               )
-    self.assertResourceCalled('Execute', ('chmod', '-R', 'ugo+r', '/etc/ambari-logsearch-portal/conf/solr_configsets'),
+    self.assertResourceCalled('Execute', ('chmod', '-R', 'ugo+r', '/usr/lib/ambari-logsearch-portal/conf/solr_configsets'),
                               sudo = True
     )
     self.assertResourceCalled('Execute', 'ambari-sudo.sh JAVA_HOME=/usr/jdk64/jdk1.7.0_45 /usr/lib/ambari-infra-solr-client/solrCloudCli.sh --zookeeper-connect-string c6401.ambari.apache.org:2181 --znode /infra-solr --check-znode --retry 30 --interval 5')
@@ -174,7 +174,6 @@ class TestLogSearch(RMFTestCase):
     )
 
     self.configureResourcesCalled()
-    self.assertResourceCalled('Execute', "/usr/lib/ambari-logsearch-portal/run.sh",
-                              environment = {'LOGSEARCH_INCLUDE': '/etc/ambari-logsearch-portal/conf/logsearch-env.sh'},
+    self.assertResourceCalled('Execute', "/usr/lib/ambari-logsearch-portal/bin/logsearch.sh start",
                               user = "logsearch"
     )

http://git-wip-us.apache.org/repos/asf/ambari/blob/562795c4/ambari-server/src/test/python/stacks/2.4/configs/default.json
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/python/stacks/2.4/configs/default.json b/ambari-server/src/test/python/stacks/2.4/configs/default.json
index 9966f3e..701132a 100644
--- a/ambari-server/src/test/python/stacks/2.4/configs/default.json
+++ b/ambari-server/src/test/python/stacks/2.4/configs/default.json
@@ -315,7 +315,7 @@
         "logsearch.roles.allowed": "AMBARI.ADMINISTRATOR,CLUSTER.ADMINISTRATOR"
       },
       "logfeeder-properties": {
-        "logfeeder.checkpoint.folder" : "/etc/ambari-logsearch-logfeeder/conf/checkpoints",
+        "logfeeder.checkpoint.folder" : "/usr/lib/ambari-logsearch-logfeeder/conf/checkpoints",
         "logfeeder.metrics.collector.hosts" : "{metrics_collector_hosts}",
         "logfeeder.config.files" : "{default_config_files}"
       },


[21/24] ambari git commit: AMBARI-22677. Addendum - Don't call pprint.pformat unnecessarily in Ambari agent (amagyar)

Posted by nc...@apache.org.
AMBARI-22677. Addendum - Don't call pprint.pformat unnecessarily in Ambari agent (amagyar)


Project: http://git-wip-us.apache.org/repos/asf/ambari/repo
Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/9ea3fa15
Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/9ea3fa15
Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/9ea3fa15

Branch: refs/heads/branch-feature-AMBARI-21674
Commit: 9ea3fa154adb1328000bfb8170ea93b7faa66783
Parents: 4e731d3
Author: Attila Magyar <am...@hortonworks.com>
Authored: Wed Dec 20 17:34:45 2017 +0100
Committer: Attila Magyar <am...@hortonworks.com>
Committed: Wed Dec 20 17:34:45 2017 +0100

----------------------------------------------------------------------
 ambari-agent/src/main/python/ambari_agent/Controller.py | 6 ++----
 1 file changed, 2 insertions(+), 4 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ambari/blob/9ea3fa15/ambari-agent/src/main/python/ambari_agent/Controller.py
----------------------------------------------------------------------
diff --git a/ambari-agent/src/main/python/ambari_agent/Controller.py b/ambari-agent/src/main/python/ambari_agent/Controller.py
index ef50440..e4f148f 100644
--- a/ambari-agent/src/main/python/ambari_agent/Controller.py
+++ b/ambari-agent/src/main/python/ambari_agent/Controller.py
@@ -164,14 +164,12 @@ class Controller(threading.Thread):
     while not self.isRegistered:
       try:
         data = json.dumps(self.register.build(self.version))
-        prettyData = pprint.pformat(data)
-
         try:
           server_ip = socket.gethostbyname(self.hostname)
-          logger.info("Registering with %s (%s) (agent=%s)", self.hostname, server_ip, prettyData)
+          logger.info("Registering with %s (%s) (agent=%s)", self.hostname, server_ip, data)
         except socket.error:
           logger.warn("Unable to determine the IP address of '%s', agent registration may fail (agent=%s)",
-                      self.hostname, prettyData)
+                      self.hostname, data)
 
         ret = self.sendRequest(self.registerUrl, data)
 


[22/24] ambari git commit: AMBARI-22682 Ambari 3.0 Admin View: Add visual-search box to all pages. (atkach)

Posted by nc...@apache.org.
http://git-wip-us.apache.org/repos/asf/ambari/blob/81c04545/ambari-admin/src/main/resources/ui/admin-web/test/unit/controllers/userManagement/UsersListCtrl_test.js
----------------------------------------------------------------------
diff --git a/ambari-admin/src/main/resources/ui/admin-web/test/unit/controllers/userManagement/UsersListCtrl_test.js b/ambari-admin/src/main/resources/ui/admin-web/test/unit/controllers/userManagement/UsersListCtrl_test.js
index fcafa59..db91b56 100644
--- a/ambari-admin/src/main/resources/ui/admin-web/test/unit/controllers/userManagement/UsersListCtrl_test.js
+++ b/ambari-admin/src/main/resources/ui/admin-web/test/unit/controllers/userManagement/UsersListCtrl_test.js
@@ -33,312 +33,6 @@ describe('#Cluster', function () {
       });
     }));
 
-    describe('#clearFilters()', function () {
-
-      it('should clear filters and reset pagination', function () {
-        scope.currentPage = 2;
-        scope.filters.name = 'a';
-        scope.filters.status = {
-          label: $t('common.local'),
-          value: false
-        };
-        scope.filters.type = {
-          label: $t('common.local'),
-          value: 'LOCAL'
-        };
-        scope.clearFilters();
-        expect(scope.filters.name).toEqual('');
-        expect(scope.filters.status).toEqual({
-          label: $t('common.all'),
-          value: '*'
-        });
-        expect(scope.filters.type).toEqual({
-          label: $t('common.all'),
-          value: '*'
-        });
-        expect(scope.currentPage).toEqual(1);
-      });
-
-    });
-
-    describe('#isNotEmptyFilter', function () {
-
-      var cases = [
-        {
-          currentNameFilter: '',
-          currentTypeFilter: null,
-          currentActiveFilter: null,
-          isNotEmptyFilter: false,
-          title: 'no filters'
-        },
-        {
-          currentNameFilter: '',
-          currentTypeFilter: {
-            value: '*'
-          },
-          currentActiveFilter: {
-            value: '*'
-          },
-          isNotEmptyFilter: false,
-          title: 'empty filters'
-        },
-        {
-          currentNameFilter: 'a',
-          currentTypeFilter: {
-            value: '*'
-          },
-          currentActiveFilter: {
-            value: '*'
-          },
-          isNotEmptyFilter: true,
-          title: 'name filter'
-        },
-        {
-          currentNameFilter: '0',
-          currentTypeFilter: {
-            value: '*'
-          },
-          currentActiveFilter: {
-            value: '*'
-          },
-          isNotEmptyFilter: true,
-          title: 'name filter with "0" as string'
-        },
-        {
-          currentNameFilter: '',
-          currentTypeFilter: {
-            value: 'LOCAL'
-          },
-          currentActiveFilter: {
-            value: '*'
-          },
-          isNotEmptyFilter: true,
-          title: 'type filter'
-        },
-        {
-          currentNameFilter: '',
-          currentTypeFilter: {
-            value: '*'
-          },
-          currentActiveFilter: {
-            value: false
-          },
-          isNotEmptyFilter: true,
-          title: 'activity filter'
-        },
-        {
-          currentNameFilter: 'a',
-          currentTypeFilter: {
-            value: 'LOCAL'
-          },
-          currentActiveFilter: {
-            value: '*'
-          },
-          isNotEmptyFilter: true,
-          title: 'name and type filters'
-        },
-        {
-          currentNameFilter: 'a',
-          currentTypeFilter: {
-            value: '*'
-          },
-          currentActiveFilter: {
-            value: false
-          },
-          isNotEmptyFilter: true,
-          title: 'name and activity filters'
-        },
-        {
-          currentNameFilter: 'a',
-          currentTypeFilter: {
-            value: '*'
-          },
-          currentActiveFilter: {
-            value: '*'
-          },
-          isNotEmptyFilter: true,
-          title: 'name and admin filters'
-        },
-        {
-          currentNameFilter: '0',
-          currentTypeFilter: {
-            value: 'LOCAL'
-          },
-          currentActiveFilter: {
-            value: '*'
-          },
-          isNotEmptyFilter: true,
-          title: 'name and type filters with "0" as string'
-        },
-        {
-          currentNameFilter: '0',
-          currentTypeFilter: {
-            value: '*'
-          },
-          currentActiveFilter: {
-            value: false
-          },
-          isNotEmptyFilter: true,
-          title: 'name and activity filters with "0" as string'
-        },
-        {
-          currentNameFilter: '0',
-          currentTypeFilter: {
-            value: '*'
-          },
-          currentActiveFilter: {
-            value: '*'
-          },
-          isNotEmptyFilter: true,
-          title: 'name and admin filters with "0" as string'
-        },
-        {
-          currentNameFilter: '',
-          currentTypeFilter: {
-            value: 'LOCAL'
-          },
-          currentActiveFilter: {
-            value: false
-          },
-          isNotEmptyFilter: true,
-          title: 'type and activity filters'
-        },
-        {
-          currentNameFilter: '',
-          currentTypeFilter: {
-            value: 'LOCAL'
-          },
-          currentActiveFilter: {
-            value: '*'
-          },
-          isNotEmptyFilter: true,
-          title: 'type and admin filters'
-        },
-        {
-          currentNameFilter: '',
-          currentTypeFilter: {
-            value: '*'
-          },
-          currentActiveFilter: {
-            value: false
-          },
-          isNotEmptyFilter: true,
-          title: 'activity and admin filters'
-        },
-        {
-          currentNameFilter: '',
-          currentTypeFilter: {
-            value: 'LOCAL'
-          },
-          currentActiveFilter: {
-            value: false
-          },
-          isNotEmptyFilter: true,
-          title: 'all filters except name one'
-        },
-        {
-          currentNameFilter: 'a',
-          currentTypeFilter: {
-            value: '*'
-          },
-          currentActiveFilter: {
-            value: false
-          },
-          isNotEmptyFilter: true,
-          title: 'all filters except type one'
-        },
-        {
-          currentNameFilter: 'a',
-          currentTypeFilter: {
-            value: 'LOCAL'
-          },
-          currentActiveFilter: {
-            value: '*'
-          },
-          isNotEmptyFilter: true,
-          title: 'all filters except activity one'
-        },
-        {
-          currentNameFilter: 'a',
-          currentTypeFilter: {
-            value: 'LOCAL'
-          },
-          currentActiveFilter: {
-            value: false
-          },
-          isNotEmptyFilter: true,
-          title: 'all filters except admin one'
-        },
-        {
-          currentNameFilter: '0',
-          currentTypeFilter: {
-            value: '*'
-          },
-          currentActiveFilter: {
-            value: false
-          },
-          isNotEmptyFilter: true,
-          title: 'all filters with "0" as string except type one'
-        },
-        {
-          currentNameFilter: '0',
-          currentTypeFilter: {
-            value: 'LOCAL'
-          },
-          currentActiveFilter: {
-            value: '*'
-          },
-          isNotEmptyFilter: true,
-          title: 'all filters with "0" as string except activity one'
-        },
-        {
-          currentNameFilter: '0',
-          currentTypeFilter: {
-            value: 'LOCAL'
-          },
-          currentActiveFilter: {
-            value: false
-          },
-          isNotEmptyFilter: true,
-          title: 'all filters with "0" as string except admin one'
-        },
-        {
-          currentNameFilter: 'a',
-          currentTypeFilter: {
-            value: false
-          },
-          currentActiveFilter: {
-            value: 'LOCAL'
-          },
-          isNotEmptyFilter: true,
-          title: 'all filters'
-        },
-        {
-          currentNameFilter: '0',
-          currentTypeFilter: {
-            value: false
-          },
-          currentActiveFilter: {
-            value: 'LOCAL'
-          },
-          isNotEmptyFilter: true,
-          title: 'all filters with "0" as string'
-        }
-      ];
-
-      cases.forEach(function (item) {
-        it(item.title, function () {
-          $httpBackend.expectGET(/\/api\/v1\/users/).respond(200);
-          scope.filters.name = item.currentNameFilter;
-          scope.filters.status = item.currentActiveFilter;
-          scope.filters.type = item.currentTypeFilter;
-          scope.$digest();
-          expect(scope.isNotEmptyFilter).toEqual(item.isNotEmptyFilter);
-        });
-      });
-
-    });
-
   });
 
 });

http://git-wip-us.apache.org/repos/asf/ambari/blob/81c04545/ambari-admin/src/main/resources/ui/admin-web/test/unit/directives/comboSearch_test.js
----------------------------------------------------------------------
diff --git a/ambari-admin/src/main/resources/ui/admin-web/test/unit/directives/comboSearch_test.js b/ambari-admin/src/main/resources/ui/admin-web/test/unit/directives/comboSearch_test.js
index 9bc7083..0f4e3b3 100644
--- a/ambari-admin/src/main/resources/ui/admin-web/test/unit/directives/comboSearch_test.js
+++ b/ambari-admin/src/main/resources/ui/admin-web/test/unit/directives/comboSearch_test.js
@@ -135,19 +135,6 @@ describe('#comboSearch', function () {
 
   describe('#hideAutocomplete', function() {
 
-    it('showAutoComplete should be false when filter passed', function () {
-      var isoScope = element.isolateScope();
-      var filter = {
-        showAutoComplete: true
-      };
-      jasmine.Clock.useMock();
-
-      isoScope.hideAutocomplete(filter);
-
-      jasmine.Clock.tick(101);
-      expect(filter.showAutoComplete).toBeFalsy();
-    });
-
     it('showAutoComplete should be false when isEditing = false', function () {
       var isoScope = element.isolateScope();
       jasmine.Clock.useMock();

http://git-wip-us.apache.org/repos/asf/ambari/blob/81c04545/ambari-admin/src/main/resources/ui/admin-web/test/unit/services/Filters_test.js
----------------------------------------------------------------------
diff --git a/ambari-admin/src/main/resources/ui/admin-web/test/unit/services/Filters_test.js b/ambari-admin/src/main/resources/ui/admin-web/test/unit/services/Filters_test.js
new file mode 100644
index 0000000..a8b2924
--- /dev/null
+++ b/ambari-admin/src/main/resources/ui/admin-web/test/unit/services/Filters_test.js
@@ -0,0 +1,161 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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.
+ */
+
+describe('Filters Service', function () {
+  var Filters;
+
+  beforeEach(function () {
+    module('ambariAdminConsole', angular.noop);
+    inject(function (_Filters_) {
+      Filters = _Filters_;
+    });
+  });
+  describe('#initFilterOptions', function() {
+    var items = [
+      {
+        k1: {
+          values: ['val1', 'val3']
+        },
+        k2: 'val2'
+      }
+    ];
+    var filters = [
+      {
+        isMultiple: true,
+        key: 'k1',
+        options: [],
+        customValueConverter: function(item) {
+          return item.k1.values;
+        }
+      },
+      {
+        key: 'k2',
+        options: []
+      },
+      {
+        isStatic: true,
+        options: [
+          {
+            key: 'static1',
+            label: 'static1'
+          }
+        ]
+      }
+    ];
+    beforeEach(function() {
+      Filters.initFilterOptions(filters, items);
+    });
+
+    it('should set static options of filters', function() {
+      expect(filters[2].options).toEqual([{
+        key: 'static1',
+        label: 'static1'
+      }]);
+    });
+
+    it('should set options of filters', function() {
+      expect(filters[1].options).toEqual([{
+        key: 'val2',
+        label: 'val2'
+      }]);
+    });
+
+    it('should set multiple options of filters', function() {
+      expect(filters[0].options).toEqual([
+        {
+          key: 'val1',
+          label: 'val1'
+        },
+        {
+          key: 'val3',
+          label: 'val3'
+        }
+      ]);
+    });
+  });
+
+  describe('#filterItems', function() {
+
+    it('all items should be filtered when no filters applied', function() {
+      var items = [{}];
+
+      expect(Filters.filterItems(null, items, [])).toEqual(1);
+      expect(items[0].isFiltered).toBeTruthy();
+    });
+
+    it('items should be filtered when simple filter applied', function() {
+      var appliedFilters = [
+        {
+          key: 'p1',
+          values: ['val1']
+        }
+      ];
+      var items = [
+        { p1: 'val1' },
+        { p1: 'val2' }
+      ];
+      var filterDefinitions = [];
+
+      expect(Filters.filterItems(appliedFilters, items, filterDefinitions)).toEqual(1);
+      expect(items[0].isFiltered).toBeTruthy();
+      expect(items[1].isFiltered).toBeFalsy();
+    });
+
+    it('items should be filtered when filter applied on array values', function() {
+      var appliedFilters = [
+        {
+          key: 'p1',
+          values: ['a']
+        }
+      ];
+      var items = [
+        { p1: ['a', 'b'] },
+        { p1: ['c', 'b'] }
+      ];
+      var filterDefinitions = [];
+
+      expect(Filters.filterItems(appliedFilters, items, filterDefinitions)).toEqual(1);
+      expect(items[0].isFiltered).toBeTruthy();
+      expect(items[1].isFiltered).toBeFalsy();
+    });
+
+    it('items should be filtered when custom filter applied', function() {
+      var appliedFilters = [
+        {
+          key: 'p1',
+          values: ['a']
+        }
+      ];
+      var items = [
+        { p1: { customValue: 'a' } },
+        { p1: { customValue: 'b' } }
+      ];
+      var filterDefinitions = [{
+        key: 'p1',
+        customValueConverter: function(item) {
+          return item.p1.customValue;
+        }
+      }];
+
+      expect(Filters.filterItems(appliedFilters, items, filterDefinitions)).toEqual(1);
+      expect(items[0].isFiltered).toBeTruthy();
+      expect(items[1].isFiltered).toBeFalsy();
+    });
+  });
+
+});

http://git-wip-us.apache.org/repos/asf/ambari/blob/81c04545/ambari-admin/src/main/resources/ui/admin-web/test/unit/services/Pagination_test.js
----------------------------------------------------------------------
diff --git a/ambari-admin/src/main/resources/ui/admin-web/test/unit/services/Pagination_test.js b/ambari-admin/src/main/resources/ui/admin-web/test/unit/services/Pagination_test.js
new file mode 100644
index 0000000..ce6cb52
--- /dev/null
+++ b/ambari-admin/src/main/resources/ui/admin-web/test/unit/services/Pagination_test.js
@@ -0,0 +1,72 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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.
+ */
+
+describe('Pagination Service', function () {
+  var Pagination, $pagination;
+
+  beforeEach(function () {
+    module('ambariAdminConsole', angular.noop);
+    inject(function (_Pagination_) {
+      Pagination = _Pagination_;
+      $pagination = Pagination.create({
+        itemsPerPage: 1
+      });
+    });
+  });
+
+  describe('#pageChanged', function() {
+
+    it('should show items on second page', function() {
+      var items = [
+        { isFiltered: true },
+        { isFiltered: true },
+        { isFiltered: true }
+      ];
+      var tableInfo = {
+        showed: 0
+      };
+      $pagination.currentPage = 2;
+      $pagination.pageChanged(items, tableInfo);
+      expect(items[0].isShowed).toBeFalsy();
+      expect(items[1].isShowed).toBeTruthy();
+      expect(items[2].isShowed).toBeFalsy();
+      expect(tableInfo.showed).toEqual(1);
+    });
+  });
+
+  describe('#resetPagination', function() {
+
+    it('should show items on first page', function() {
+      var items = [
+        { isFiltered: true },
+        { isFiltered: true },
+        { isFiltered: true }
+      ];
+      var tableInfo = {
+        showed: 0
+      };
+      $pagination.currentPage = 2;
+      $pagination.resetPagination(items, tableInfo);
+      expect(items[0].isShowed).toBeTruthy();
+      expect(items[1].isShowed).toBeFalsy();
+      expect(items[2].isShowed).toBeFalsy();
+      expect(tableInfo.showed).toEqual(1);
+    });
+  });
+
+});


[18/24] ambari git commit: AMBARI-22672. Error on add version view in web admin (alexantonenko)

Posted by nc...@apache.org.
AMBARI-22672. Error on add version view in web admin (alexantonenko)


Project: http://git-wip-us.apache.org/repos/asf/ambari/repo
Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/9bb0980d
Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/9bb0980d
Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/9bb0980d

Branch: refs/heads/branch-feature-AMBARI-21674
Commit: 9bb0980da1261f3be769ba26db9adb5ebaa74a55
Parents: 30d89a3
Author: Alex Antonenko <aa...@hortonworks.com>
Authored: Tue Dec 19 16:42:37 2017 +0300
Committer: Alex Antonenko <aa...@hortonworks.com>
Committed: Tue Dec 19 16:42:37 2017 +0300

----------------------------------------------------------------------
 .../scripts/controllers/stackVersions/StackVersionsCreateCtrl.js   | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ambari/blob/9bb0980d/ambari-admin/src/main/resources/ui/admin-web/app/scripts/controllers/stackVersions/StackVersionsCreateCtrl.js
----------------------------------------------------------------------
diff --git a/ambari-admin/src/main/resources/ui/admin-web/app/scripts/controllers/stackVersions/StackVersionsCreateCtrl.js b/ambari-admin/src/main/resources/ui/admin-web/app/scripts/controllers/stackVersions/StackVersionsCreateCtrl.js
index 3d93b0d..2a2151d 100644
--- a/ambari-admin/src/main/resources/ui/admin-web/app/scripts/controllers/stackVersions/StackVersionsCreateCtrl.js
+++ b/ambari-admin/src/main/resources/ui/admin-web/app/scripts/controllers/stackVersions/StackVersionsCreateCtrl.js
@@ -43,7 +43,7 @@ angular.module('ambariAdminConsole')
   $scope.isGPLAccepted = false;
 
   $scope.isGPLRepo = function (repository) {
-    return repository.Repositories.tags.indexOf('GPL') >= 0;
+    return  repository.Repositories.tags && repository.Repositories.tags.indexOf('GPL') >= 0;
   };
 
   $scope.showRepo = function (repository) {


[06/24] ambari git commit: AMBARI-22663 Log Search UI: incorrect caption for graph gap in weeks. (ababiichuk)

Posted by nc...@apache.org.
AMBARI-22663 Log Search UI: incorrect caption for graph gap in weeks. (ababiichuk)


Project: http://git-wip-us.apache.org/repos/asf/ambari/repo
Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/f9ad13d0
Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/f9ad13d0
Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/f9ad13d0

Branch: refs/heads/branch-feature-AMBARI-21674
Commit: f9ad13d0a304414b7e37b6a61afac876912e74ce
Parents: ab342d7
Author: ababiichuk <ab...@hortonworks.com>
Authored: Mon Dec 18 13:30:27 2017 +0200
Committer: ababiichuk <ab...@hortonworks.com>
Committed: Mon Dec 18 13:30:27 2017 +0200

----------------------------------------------------------------------
 ambari-logsearch/ambari-logsearch-web/src/assets/i18n/en.json | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ambari/blob/f9ad13d0/ambari-logsearch/ambari-logsearch-web/src/assets/i18n/en.json
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-web/src/assets/i18n/en.json b/ambari-logsearch/ambari-logsearch-web/src/assets/i18n/en.json
index 3f4f5c8..9561ca0 100644
--- a/ambari-logsearch/ambari-logsearch-web/src/assets/i18n/en.json
+++ b/ambari-logsearch/ambari-logsearch-web/src/assets/i18n/en.json
@@ -169,5 +169,7 @@
   "histogram.gap.hour": "hour",
   "histogram.gap.hours": "hours",
   "histogram.gap.day": "day",
-  "histogram.gap.days": "days"
+  "histogram.gap.days": "days",
+  "histogram.gap.week": "week",
+  "histogram.gap.weeks": "weeks"
 }


[14/24] ambari git commit: AMBARI-22647. ADDENDUM -Rafactor: Package Log Search and Log Feeder into jars + cleanup start scripts (oleewere)

Posted by nc...@apache.org.
AMBARI-22647. ADDENDUM -Rafactor: Package Log Search and Log Feeder into jars + cleanup start scripts (oleewere)


Project: http://git-wip-us.apache.org/repos/asf/ambari/repo
Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/afe469c9
Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/afe469c9
Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/afe469c9

Branch: refs/heads/branch-feature-AMBARI-21674
Commit: afe469c98564aa7face62fe185eeb50b9b322e5f
Parents: 5c95c4a
Author: Oliver Szabo <ol...@gmail.com>
Authored: Mon Dec 18 22:01:09 2017 +0100
Committer: Oliver Szabo <ol...@gmail.com>
Committed: Mon Dec 18 22:01:44 2017 +0100

----------------------------------------------------------------------
 .../src/main/resources/logfeeder.properties        |  5 +----
 .../src/main/scripts/logfeeder.sh                  | 17 ++++++++---------
 .../src/main/scripts/logsearch.sh                  | 17 ++++++++---------
 ambari-logsearch/docker/bin/start.sh               |  9 +++++----
 4 files changed, 22 insertions(+), 26 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ambari/blob/afe469c9/ambari-logsearch/ambari-logsearch-logfeeder/src/main/resources/logfeeder.properties
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-logfeeder/src/main/resources/logfeeder.properties b/ambari-logsearch/ambari-logsearch-logfeeder/src/main/resources/logfeeder.properties
index 4b49446..5217309 100644
--- a/ambari-logsearch/ambari-logsearch-logfeeder/src/main/resources/logfeeder.properties
+++ b/ambari-logsearch/ambari-logsearch-logfeeder/src/main/resources/logfeeder.properties
@@ -23,9 +23,8 @@ logfeeder.config.files=${LOGFEEDER_RELATIVE_LOCATION:}target/classes/log-samples
  ${LOGFEEDER_RELATIVE_LOCATION:}target/classes/log-samples/shipper-conf/output.config-sample.json
 
 logfeeder.log.filter.enable=true
+logfeeder.include.default.level=FATAL,ERROR,WARN,INFO,DEBUG,TRACE,UNKNOWN
 
-logfeeder.solr.config.interval=5
-logfeeder.solr.core.config.name=history
 logfeeder.solr.zk_connect_string=localhost:2181
 
 logfeeder.cache.enabled=true
@@ -34,7 +33,5 @@ logfeeder.cache.key.field=log_message
 logfeeder.cache.dedup.interval=1000
 logfeeder.cache.last.dedup.enabled=true
 
-logfeeder.include.default.level=FATAL,ERROR,WARN,INFO,DEBUG,TRACE,UNKNOWN
-
 #logfeeder tmp dir
 logfeeder.tmp.dir=${LOGFEEDER_RELATIVE_LOCATION:}target/tmp

http://git-wip-us.apache.org/repos/asf/ambari/blob/afe469c9/ambari-logsearch/ambari-logsearch-logfeeder/src/main/scripts/logfeeder.sh
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-logfeeder/src/main/scripts/logfeeder.sh b/ambari-logsearch/ambari-logsearch-logfeeder/src/main/scripts/logfeeder.sh
index cfacea5..5f4edea 100755
--- a/ambari-logsearch/ambari-logsearch-logfeeder/src/main/scripts/logfeeder.sh
+++ b/ambari-logsearch/ambari-logsearch-logfeeder/src/main/scripts/logfeeder.sh
@@ -119,27 +119,26 @@ function spinner() {
 }
 
 function status() {
-  echo "Checking Log Feeder status ..."
+  echo "Checking Log Feeder status ..." >&2
   if [ -f "$LOGFEEDER_PID_FILE" ]; then
     LOGFEEDER_PID=`cat "$LOGFEEDER_PID_FILE"`
   else
-    echo "Log Feeder pid not exists. (probably the process is not running)"
-    exit 1
+    echo "Log Feeder pid not exists. (probably the process is not running)" >&2
+    return 1
   fi
 
   if ps -p $LOGFEEDER_PID > /dev/null
    then
-   echo "Log Feeder process is running. (pid: $LOGFEEDER_PID)"
-   exit 0
+   echo "Log Feeder process is running. (pid: $LOGFEEDER_PID)" >&2
+   return 0
   else
-   echo "Log Feeder process is not running."
-   exit 1
+   echo "Log Feeder process is not running." >&2
+   return 1
   fi
 }
 
 function start() {
-  (status);
-  exit_status=$(echo $?)
+  exit_status=$(status; echo $?)
   if [ "$exit_status" = "0" ]; then
     echo "Skipping start process."
     exit 0

http://git-wip-us.apache.org/repos/asf/ambari/blob/afe469c9/ambari-logsearch/ambari-logsearch-server/src/main/scripts/logsearch.sh
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-server/src/main/scripts/logsearch.sh b/ambari-logsearch/ambari-logsearch-server/src/main/scripts/logsearch.sh
index 128617c..8439065 100755
--- a/ambari-logsearch/ambari-logsearch-server/src/main/scripts/logsearch.sh
+++ b/ambari-logsearch/ambari-logsearch-server/src/main/scripts/logsearch.sh
@@ -109,27 +109,26 @@ function spinner() {
 }
 
 function status() {
-  echo "Checking Log Search status ..."
+  echo "Checking Log Search status ..." >&2
   if [ -f "$LOGSEARCH_PID_FILE" ]; then
     LOGSEARCH_PID=`cat "$LOGSEARCH_PID_FILE"`
   else
-    echo "Log Search pid not exists. (probably the process is not running)"
-    exit 1
+    echo "Log Search pid not exists. (probably the process is not running)" >&2
+    return 1
   fi
 
   if ps -p $LOGSEARCH_PID > /dev/null
    then
-   echo "Log Search process is running. (pid: $LOGSEARCH_PID)"
-   exit 0
+   echo "Log Search process is running. (pid: $LOGSEARCH_PID)" >&2
+   return 0
   else
-   echo "Log Search process is not running."
-   exit 1
+   echo "Log Search process is not running." >&2
+   return 1
   fi
 }
 
 function start() {
-  (status);
-  exit_status=$(echo $?)
+  exit_status=$(status; echo $?)
   if [ "$exit_status" = "0" ]; then
     echo "Skipping start process."
     exit 0

http://git-wip-us.apache.org/repos/asf/ambari/blob/afe469c9/ambari-logsearch/docker/bin/start.sh
----------------------------------------------------------------------
diff --git a/ambari-logsearch/docker/bin/start.sh b/ambari-logsearch/docker/bin/start.sh
index f2acf9b..6ba20fb 100644
--- a/ambari-logsearch/docker/bin/start.sh
+++ b/ambari-logsearch/docker/bin/start.sh
@@ -46,7 +46,7 @@ function create_logfeeder_configs() {
 }
 
 function create_logsearch_configs() {
-  mkdir /root/config/logsearch
+  mkdir -p /root/config/logsearch
   cp /root/test-config/logsearch/log4j.xml /root/config/logsearch/
   cp /root/test-config/logsearch/logsearch-env.sh /root/config/logsearch/
   cp $LOGSEARCH_SERVER_PATH/conf/user_pass.json /root/config/logsearch/user_pass.json
@@ -148,7 +148,7 @@ function main() {
   case $component in
     "solr")
       create_solr_configs
-      echo "Start Solr only.."
+      echo "Start Solr only ..."
       export COMPONENT_LOG="solr"
       generate_keys
       start_solr_d
@@ -156,17 +156,18 @@ function main() {
      ;;
     "logfeeder")
       create_logfeeder_configs
-      echo "Start Log Feeder only.."
+      echo "Start Log Feeder only ..."
       export COMPONENT_LOG="logfeeder"
       generate_keys
       start_logfeeder
      ;;
     "logsearch")
       create_logsearch_configs
-      echo "Start Log Search only.."
+      echo "Start Log Search only ..."
       export COMPONENT_LOG="logsearch"
       generate_keys
       start_logsearch
+      log
      ;;
      *)
       create_configs


[15/24] ambari git commit: AMBARI-22571. Handle passwords/sensitive data in Ambari configuration properties (Sandor Molnar via rlevas)

Posted by nc...@apache.org.
AMBARI-22571. Handle passwords/sensitive data in Ambari configuration properties (Sandor Molnar via rlevas)


Project: http://git-wip-us.apache.org/repos/asf/ambari/repo
Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/be0e87be
Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/be0e87be
Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/be0e87be

Branch: refs/heads/branch-feature-AMBARI-21674
Commit: be0e87bef52458955eddf1b824e6c5ddc6f31de6
Parents: afe469c
Author: Sandor Molnar <sm...@hortonworks.com>
Authored: Mon Dec 18 23:38:29 2017 -0500
Committer: Robert Levas <rl...@hortonworks.com>
Committed: Mon Dec 18 23:38:29 2017 -0500

----------------------------------------------------------------------
 ambari-server/pom.xml                           |   2 +-
 .../RootServiceComponentConfiguration.java      |  73 +++++++
 .../server/configuration/Configuration.java     |  11 +-
 .../ConfigurationPropertyType.java              |  22 +++
 .../AmbariServerConfigurationHandler.java       | 102 ++++++++--
 .../AmbariServerConfigurationUtils.java         |  78 ++++++++
 .../AmbariServerLDAPConfigurationHandler.java   |   9 +-
 ...ootServiceComponentConfigurationHandler.java |   7 +-
 ...eComponentConfigurationResourceProvider.java |  18 +-
 .../domain/AmbariLdapConfigurationKeys.java     |  77 ++++----
 ...ponentConfigurationResourceProviderTest.java | 192 +++++++++++++------
 11 files changed, 473 insertions(+), 118 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ambari/blob/be0e87be/ambari-server/pom.xml
----------------------------------------------------------------------
diff --git a/ambari-server/pom.xml b/ambari-server/pom.xml
index 2ecf435..5a0afb7 100644
--- a/ambari-server/pom.xml
+++ b/ambari-server/pom.xml
@@ -1169,7 +1169,7 @@
     <dependency>
       <groupId>commons-io</groupId>
       <artifactId>commons-io</artifactId>
-      <version>2.4</version>
+      <version>2.5</version>
     </dependency>
     <dependency>
       <groupId>org.apache.commons</groupId>

http://git-wip-us.apache.org/repos/asf/ambari/blob/be0e87be/ambari-server/src/main/java/org/apache/ambari/server/api/services/RootServiceComponentConfiguration.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/api/services/RootServiceComponentConfiguration.java b/ambari-server/src/main/java/org/apache/ambari/server/api/services/RootServiceComponentConfiguration.java
new file mode 100644
index 0000000..cd31c75
--- /dev/null
+++ b/ambari-server/src/main/java/org/apache/ambari/server/api/services/RootServiceComponentConfiguration.java
@@ -0,0 +1,73 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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 org.apache.ambari.server.api.services;
+
+import java.util.Map;
+import java.util.TreeMap;
+
+import org.apache.commons.lang3.builder.EqualsBuilder;
+import org.apache.commons.lang3.builder.HashCodeBuilder;
+import org.apache.commons.lang3.builder.ToStringBuilder;
+import org.apache.commons.lang3.builder.ToStringStyle;
+
+public class RootServiceComponentConfiguration {
+
+  private final Map<String, String> properties;
+  private final Map<String, String> propertyTypes;
+
+  public RootServiceComponentConfiguration() {
+    this(new TreeMap<>(), new TreeMap<>());
+  }
+
+  public RootServiceComponentConfiguration(Map<String, String> properties, Map<String, String> propertyTypes) {
+    this.properties = properties == null ? new TreeMap<>() : properties;
+    this.propertyTypes = propertyTypes == null ? new TreeMap<>() : propertyTypes;
+  }
+
+  public void addProperty(String propertyName, String propertyValue) {
+    properties.put(propertyName, propertyValue);
+  }
+
+  public void addPropertyType(String propertyName, String propertyType) {
+    propertyTypes.put(propertyName, propertyType);
+  }
+
+  public Map<String, String> getProperties() {
+    return properties;
+  }
+
+  public Map<String, String> getPropertyTypes() {
+    return propertyTypes;
+  }
+
+  @Override
+  public boolean equals(Object obj) {
+    return EqualsBuilder.reflectionEquals(this, obj);
+  }
+
+  @Override
+  public int hashCode() {
+    return HashCodeBuilder.reflectionHashCode(3, 19, this);
+  }
+
+  @Override
+  public String toString() {
+    return ToStringBuilder.reflectionToString(this, ToStringStyle.SHORT_PREFIX_STYLE);
+  }
+}

http://git-wip-us.apache.org/repos/asf/ambari/blob/be0e87be/ambari-server/src/main/java/org/apache/ambari/server/configuration/Configuration.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/configuration/Configuration.java b/ambari-server/src/main/java/org/apache/ambari/server/configuration/Configuration.java
index ea44a90..7003c98 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/configuration/Configuration.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/configuration/Configuration.java
@@ -2783,6 +2783,9 @@ public class Configuration {
   public static final ConfigurationProperty<String> DISPATCH_PROPERTY_SCRIPT_DIRECTORY = new ConfigurationProperty<>(
           "notification.dispatch.alert.script.directory",AmbariPath.getPath("/var/lib/ambari-server/resources/scripts"));
 
+  @Markdown(description = "Whether security password encryption is enabled or not. In case it is we store passwords in their own file(s); otherwise we store passwords in the Ambari credential store.")
+  public static final ConfigurationProperty<Boolean> SECURITY_PASSWORD_ENCRYPTON_ENABLED = new ConfigurationProperty<Boolean>("security.passwords.encryption.enabled", false);
+
 
   private static final Logger LOG = LoggerFactory.getLogger(
     Configuration.class);
@@ -5693,6 +5696,13 @@ public class Configuration {
   }
 
   /**
+   * @return  whether security password encryption is enabled or not (defaults to {@code false})
+   */
+  public boolean isSecurityPasswordEncryptionEnabled() {
+    return Boolean.parseBoolean(getProperty(SECURITY_PASSWORD_ENCRYPTON_ENABLED));
+  }
+
+  /**
    * Generates a markdown table which includes:
    * <ul>
    * <li>Property key name</li>
@@ -5869,7 +5879,6 @@ public class Configuration {
     private ConfigurationProperty(String key, T defaultValue) {
       m_key = key;
       m_defaultValue = defaultValue;
-
     }
 
     /**

http://git-wip-us.apache.org/repos/asf/ambari/blob/be0e87be/ambari-server/src/main/java/org/apache/ambari/server/configuration/ConfigurationPropertyType.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/configuration/ConfigurationPropertyType.java b/ambari-server/src/main/java/org/apache/ambari/server/configuration/ConfigurationPropertyType.java
new file mode 100644
index 0000000..2e61c19
--- /dev/null
+++ b/ambari-server/src/main/java/org/apache/ambari/server/configuration/ConfigurationPropertyType.java
@@ -0,0 +1,22 @@
+/*
+ * 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 org.apache.ambari.server.configuration;
+
+/**
+ * Constants representing types for AMBARI-level properties that are being stored in the DB
+ */
+public enum ConfigurationPropertyType {
+  PLAINTEXT, PASSWORD;
+}

http://git-wip-us.apache.org/repos/asf/ambari/blob/be0e87be/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/AmbariServerConfigurationHandler.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/AmbariServerConfigurationHandler.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/AmbariServerConfigurationHandler.java
index 34285d6..f3ff2dd 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/AmbariServerConfigurationHandler.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/AmbariServerConfigurationHandler.java
@@ -18,23 +18,33 @@
 
 package org.apache.ambari.server.controller.internal;
 
+import java.io.File;
+import java.io.IOException;
+import java.nio.charset.Charset;
 import java.util.HashMap;
+import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
-import java.util.TreeMap;
 
+import org.apache.ambari.server.AmbariException;
 import org.apache.ambari.server.StaticallyInject;
+import org.apache.ambari.server.api.services.RootServiceComponentConfiguration;
+import org.apache.ambari.server.configuration.Configuration;
 import org.apache.ambari.server.controller.spi.NoSuchResourceException;
 import org.apache.ambari.server.controller.spi.SystemException;
 import org.apache.ambari.server.events.AmbariConfigurationChangedEvent;
 import org.apache.ambari.server.events.publishers.AmbariEventPublisher;
 import org.apache.ambari.server.orm.dao.AmbariConfigurationDAO;
 import org.apache.ambari.server.orm.entities.AmbariConfigurationEntity;
+import org.apache.ambari.server.security.encryption.CredentialProvider;
+import org.apache.commons.io.FileUtils;
+import org.apache.commons.lang3.StringUtils;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 import com.google.inject.Inject;
 
+
 /**
  * AmbariServerConfigurationHandler handles Ambari server specific configuration properties.
  */
@@ -48,11 +58,15 @@ class AmbariServerConfigurationHandler extends RootServiceComponentConfiguration
   @Inject
   private static AmbariEventPublisher publisher;
 
+  @Inject
+  private static Configuration ambariConfiguration;
+
+  private CredentialProvider credentialProvider;
 
   @Override
-  public Map<String, Map<String, String>> getConfigurations(String categoryName)
+  public Map<String, RootServiceComponentConfiguration> getConfigurations(String categoryName)
       throws NoSuchResourceException {
-    Map<String, Map<String, String>> configurations = null;
+    Map<String, RootServiceComponentConfiguration> configurations = null;
 
     List<AmbariConfigurationEntity> entities = (categoryName == null)
         ? ambariConfigurationDAO.findAll()
@@ -60,17 +74,18 @@ class AmbariServerConfigurationHandler extends RootServiceComponentConfiguration
 
     if (entities != null) {
       configurations = new HashMap<>();
-
       for (AmbariConfigurationEntity entity : entities) {
         String category = entity.getCategoryName();
-        Map<String, String> properties = configurations.get(category);
-
-        if (properties == null) {
-          properties = new TreeMap<>();
-          configurations.put(category, properties);
+        RootServiceComponentConfiguration configuration = configurations.get(category);
+        if (configuration == null) {
+          configuration = new RootServiceComponentConfiguration();
+          configurations.put(category, configuration);
         }
 
-        properties.put(entity.getPropertyName(), entity.getPropertyValue());
+        configuration.addProperty(entity.getPropertyName(), entity.getPropertyValue());
+        if (categoryName != null) {
+          configuration.addPropertyType(entity.getPropertyName(), AmbariServerConfigurationUtils.getConfigurationPropertyTypeName(categoryName, entity.getPropertyName()));
+        }
       }
     }
 
@@ -94,13 +109,76 @@ class AmbariServerConfigurationHandler extends RootServiceComponentConfiguration
   }
 
   @Override
-  public void updateCategory(String categoryName, Map<String, String> properties, boolean removePropertiesIfNotSpecified) {
-    if (ambariConfigurationDAO.reconcileCategory(categoryName, properties, removePropertiesIfNotSpecified)) {
+  public void updateCategory(String categoryName, Map<String, String> properties, boolean removePropertiesIfNotSpecified) throws AmbariException {
+    boolean toBePublished = false;
+    final Iterator<Map.Entry<String, String>> propertiesIterator = properties.entrySet().iterator();
+    while (propertiesIterator.hasNext()) {
+      Map.Entry<String, String> property = propertiesIterator.next();
+      if (AmbariServerConfigurationUtils.isPassword(categoryName, property.getKey())) {
+        if (updatePasswordIfNeeded(categoryName, property.getKey(), property.getValue())) {
+          toBePublished = true;
+        }
+        propertiesIterator.remove(); //we do not need to change the any PASSWORD type configuration going forward
+      }
+    }
+
+    if (!properties.isEmpty()) {
+      toBePublished = ambariConfigurationDAO.reconcileCategory(categoryName, properties, removePropertiesIfNotSpecified) || toBePublished;
+    }
+
+    if (toBePublished) {
       // notify subscribers about the configuration changes
       publisher.publish(new AmbariConfigurationChangedEvent(categoryName));
     }
   }
 
+  private boolean updatePasswordIfNeeded(String categoryName, String propertyName, String newPassword) throws AmbariException {
+    if (newPassword != null) {
+      final String passwordFileOrCredentailStoreAlias = fetchPasswordFileNameOrCredentialStoreAlias(categoryName, propertyName);
+      if (!newPassword.equals(passwordFileOrCredentailStoreAlias)) { //we only need to do anything if the user-supplied password is a 'real' password
+        if (ambariConfiguration.isSecurityPasswordEncryptionEnabled()) {
+          getCredentialProvider().addAliasToCredentialStore(passwordFileOrCredentailStoreAlias, newPassword);
+        } else {
+          savePasswordInFile(passwordFileOrCredentailStoreAlias, newPassword);
+        }
+        return true;
+      }
+    }
+    return false;
+  }
+
+  /*
+   * If the configuration element is actually a PASSWORD type element then we either have a password file name stored in the DB
+   * or - in case security password encryption is enabled - a Credential Store alias.
+   */
+  private String fetchPasswordFileNameOrCredentialStoreAlias(String categoryName, String propertyName) {
+    for (AmbariConfigurationEntity entity : ambariConfigurationDAO.findByCategory(categoryName)) {
+      if (entity.getPropertyName().equals(propertyName)) {
+        return entity.getPropertyValue();
+      }
+    }
+
+    return null;
+  }
+
+  private CredentialProvider getCredentialProvider() throws AmbariException {
+    if (credentialProvider == null) {
+      credentialProvider = new CredentialProvider(null, ambariConfiguration.getMasterKeyLocation(),
+          ambariConfiguration.isMasterKeyPersisted(), ambariConfiguration.getMasterKeyStoreLocation());
+    }
+    return credentialProvider;
+  }
+
+  private void savePasswordInFile(String passwordFileName, String newPassword) throws AmbariException {
+    try {
+      if (StringUtils.isNotBlank(passwordFileName)) {
+        FileUtils.writeStringToFile(new File(passwordFileName), newPassword, Charset.defaultCharset());
+      }
+    } catch (IOException e) {
+      throw new AmbariException("Error while updating password file [" + passwordFileName + "]", e);
+    }
+  }
+
   @Override
   public OperationResult performOperation(String categoryName, Map<String, String> properties,
                                           boolean mergeExistingProperties, String operation,

http://git-wip-us.apache.org/repos/asf/ambari/blob/be0e87be/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/AmbariServerConfigurationUtils.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/AmbariServerConfigurationUtils.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/AmbariServerConfigurationUtils.java
new file mode 100644
index 0000000..ac05f93
--- /dev/null
+++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/AmbariServerConfigurationUtils.java
@@ -0,0 +1,78 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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 org.apache.ambari.server.controller.internal;
+
+import org.apache.ambari.server.configuration.ConfigurationPropertyType;
+import org.apache.ambari.server.ldap.domain.AmbariLdapConfigurationKeys;
+
+/**
+ * Provides useful utility methods for AMBARI-level configuration related tasks.
+ */
+public class AmbariServerConfigurationUtils {
+
+  /**
+   * @param category
+   *          the name of the category
+   * @param propertyName
+   *          the name of the property
+   * @return the type of the given category/property if such category/property
+   *         exists; {@code null} otherwise
+   * @throws IllegalStateException
+   *           if there is no property found with the given name
+   */
+  public static ConfigurationPropertyType getConfigurationPropertyType(String category, String propertyName) {
+    if (AmbariServerConfigurationCategory.LDAP_CONFIGURATION.getCategoryName().equals(category)) {
+      return AmbariLdapConfigurationKeys.fromKeyStr(propertyName).getConfigurationPropertyType();
+    }
+    return null;
+  }
+
+  /**
+   * @param category
+   *          the name of the category
+   * @param propertyName
+   *          the name of the property
+   * @return the String representation of the type if such category/property
+   *         exists; {@code null} otherwise * @throws IllegalStateException if
+   *         there is no property found with the given name
+   */
+  public static String getConfigurationPropertyTypeName(String category, String propertyName) {
+    final ConfigurationPropertyType configurationPropertyType = getConfigurationPropertyType(category, propertyName);
+    return configurationPropertyType == null ? null : configurationPropertyType.name();
+  }
+
+  /**
+   * Indicates whether the given property's type is
+   * 
+   * {@link ConfigurationPropertyType.PASSWORD}
+   *
+   * @param category
+   *          the name of the category
+   * @param propertyName
+   *          the name of the property
+   * @return {@code true} in case the given property's type is
+   *         {@link ConfigurationPropertyType.PASSWORD}; {@code false} otherwise
+   * @throws IllegalStateException
+   *           if there is no property found with the given name
+   */
+  public static boolean isPassword(String category, String propertyName) {
+    return ConfigurationPropertyType.PASSWORD.equals(getConfigurationPropertyType(category, propertyName));
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/ambari/blob/be0e87be/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/AmbariServerLDAPConfigurationHandler.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/AmbariServerLDAPConfigurationHandler.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/AmbariServerLDAPConfigurationHandler.java
index 6f16c49..c4dca80 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/AmbariServerLDAPConfigurationHandler.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/AmbariServerLDAPConfigurationHandler.java
@@ -24,6 +24,7 @@ import java.util.Map;
 import java.util.Set;
 
 import org.apache.ambari.server.StaticallyInject;
+import org.apache.ambari.server.api.services.RootServiceComponentConfiguration;
 import org.apache.ambari.server.controller.spi.NoSuchResourceException;
 import org.apache.ambari.server.controller.spi.SystemException;
 import org.apache.ambari.server.ldap.domain.AmbariLdapConfiguration;
@@ -44,7 +45,7 @@ class AmbariServerLDAPConfigurationHandler extends AmbariServerConfigurationHand
 
   @Inject
   private static LdapFacade ldapFacade;
-
+  
   @Override
   public OperationResult performOperation(String categoryName, Map<String, String> properties,
                                           boolean mergeExistingProperties, String operation, Map<String, Object> operationParameters) throws SystemException {
@@ -64,12 +65,12 @@ class AmbariServerLDAPConfigurationHandler extends AmbariServerConfigurationHand
     // to retrieve if. If one does not exist, that is ok.
     if (mergeExistingProperties) {
       try {
-        Map<String, Map<String, String>> _configurations = getConfigurations(categoryName);
+        Map<String, RootServiceComponentConfiguration> _configurations = getConfigurations(categoryName);
         if (_configurations != null) {
-          Map<String, String> _ldapProperties = _configurations.get(categoryName);
+          RootServiceComponentConfiguration _ldapProperties = _configurations.get(categoryName);
 
           if (_ldapProperties != null) {
-            ldapConfigurationProperties.putAll(_ldapProperties);
+            ldapConfigurationProperties.putAll(_ldapProperties.getProperties());
           }
         }
       } catch (NoSuchResourceException e) {

http://git-wip-us.apache.org/repos/asf/ambari/blob/be0e87be/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/RootServiceComponentConfigurationHandler.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/RootServiceComponentConfigurationHandler.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/RootServiceComponentConfigurationHandler.java
index 3b58ce1..e9e4c9e 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/RootServiceComponentConfigurationHandler.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/RootServiceComponentConfigurationHandler.java
@@ -20,6 +20,8 @@ package org.apache.ambari.server.controller.internal;
 
 import java.util.Map;
 
+import org.apache.ambari.server.AmbariException;
+import org.apache.ambari.server.api.services.RootServiceComponentConfiguration;
 import org.apache.ambari.server.controller.spi.NoSuchResourceException;
 import org.apache.ambari.server.controller.spi.SystemException;
 
@@ -35,7 +37,7 @@ abstract class RootServiceComponentConfigurationHandler {
    * @return a map of category names to properties (name/value pairs).
    * @throws NoSuchResourceException if the requested data is not found
    */
-  public abstract Map<String, Map<String, String>> getConfigurations(String categoryName) throws NoSuchResourceException;
+  public abstract Map<String, RootServiceComponentConfiguration> getConfigurations(String categoryName) throws NoSuchResourceException;
 
   /**
    * Delete the requested configuration.
@@ -58,8 +60,9 @@ abstract class RootServiceComponentConfigurationHandler {
    * @param properties                     a map of properties to set
    * @param removePropertiesIfNotSpecified <code>true</code> to ensure the set of properties are only those that have be explicitly specified;
    *                                       <code>false</code> to update the set of existing properties with the specified set of properties, adding missing properties but not removing any properties
+   * @throws AmbariException in case an error occurred while updating category's properties
    */
-  public abstract void updateCategory(String categoryName, Map<String, String> properties, boolean removePropertiesIfNotSpecified);
+  public abstract void updateCategory(String categoryName, Map<String, String> properties, boolean removePropertiesIfNotSpecified) throws AmbariException;
 
   /**
    * Preform some operation on the set of data for a category.

http://git-wip-us.apache.org/repos/asf/ambari/blob/be0e87be/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/RootServiceComponentConfigurationResourceProvider.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/RootServiceComponentConfigurationResourceProvider.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/RootServiceComponentConfigurationResourceProvider.java
index 74f8a4d..543cf94 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/RootServiceComponentConfigurationResourceProvider.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/RootServiceComponentConfigurationResourceProvider.java
@@ -26,6 +26,7 @@ import java.util.Map;
 import java.util.Set;
 
 import org.apache.ambari.server.AmbariException;
+import org.apache.ambari.server.api.services.RootServiceComponentConfiguration;
 import org.apache.ambari.server.api.services.RootServiceComponentConfigurationService;
 import org.apache.ambari.server.controller.spi.NoSuchParentResourceException;
 import org.apache.ambari.server.controller.spi.NoSuchResourceException;
@@ -50,6 +51,7 @@ public class RootServiceComponentConfigurationResourceProvider extends AbstractA
 
   public static final String CONFIGURATION_CATEGORY_PROPERTY_ID = PropertyHelper.getPropertyId(RESOURCE_KEY, "category");
   public static final String CONFIGURATION_PROPERTIES_PROPERTY_ID = PropertyHelper.getPropertyId(RESOURCE_KEY, "properties");
+  public static final String CONFIGURATION_PROPERTY_TYPES_PROPERTY_ID = PropertyHelper.getPropertyId(RESOURCE_KEY, "property_types");
   public static final String CONFIGURATION_COMPONENT_NAME_PROPERTY_ID = PropertyHelper.getPropertyId(RESOURCE_KEY, "component_name");
   public static final String CONFIGURATION_SERVICE_NAME_PROPERTY_ID = PropertyHelper.getPropertyId(RESOURCE_KEY, "service_name");
 
@@ -65,6 +67,7 @@ public class RootServiceComponentConfigurationResourceProvider extends AbstractA
     set.add(CONFIGURATION_COMPONENT_NAME_PROPERTY_ID);
     set.add(CONFIGURATION_CATEGORY_PROPERTY_ID);
     set.add(CONFIGURATION_PROPERTIES_PROPERTY_ID);
+    set.add(CONFIGURATION_PROPERTY_TYPES_PROPERTY_ID);
 
     PROPERTIES = Collections.unmodifiableSet(set);
 
@@ -202,12 +205,13 @@ public class RootServiceComponentConfigurationResourceProvider extends AbstractA
     return getRequestStatus(null, null, operationStatusMetadata);
   }
 
-  private Resource toResource(String serviceName, String componentName, String categoryName, Map<String, String> properties, Set<String> requestedIds) {
+  private Resource toResource(String serviceName, String componentName, String categoryName, Map<String, String> properties, Map<String, String> propertyTypes, Set<String> requestedIds) {
     Resource resource = new ResourceImpl(Resource.Type.RootServiceComponentConfiguration);
     setResourceProperty(resource, CONFIGURATION_SERVICE_NAME_PROPERTY_ID, serviceName, requestedIds);
     setResourceProperty(resource, CONFIGURATION_COMPONENT_NAME_PROPERTY_ID, componentName, requestedIds);
     setResourceProperty(resource, CONFIGURATION_CATEGORY_PROPERTY_ID, categoryName, requestedIds);
     setResourceProperty(resource, CONFIGURATION_PROPERTIES_PROPERTY_ID, properties, requestedIds);
+    setResourceProperty(resource, CONFIGURATION_PROPERTY_TYPES_PROPERTY_ID, propertyTypes, requestedIds);
     return resource;
   }
 
@@ -238,7 +242,11 @@ public class RootServiceComponentConfigurationResourceProvider extends AbstractA
 
         RootServiceComponentConfigurationHandler handler = rootServiceComponentConfigurationHandlerFactory.getInstance(requestDetails.serviceName, requestDetails.componentName, requestDetails.categoryName);
         if (handler != null) {
-          handler.updateCategory(requestDetails.categoryName, requestDetails.properties, removePropertiesIfNotSpecified);
+          try {
+            handler.updateCategory(requestDetails.categoryName, requestDetails.properties, removePropertiesIfNotSpecified);
+          } catch (AmbariException e) {
+            throw new SystemException(e.getMessage(), e.getCause());
+          }
         } else {
           throw new SystemException(String.format("Configurations may not be updated for the %s component of the root service, %s", requestDetails.serviceName, requestDetails.componentName));
         }
@@ -390,11 +398,11 @@ public class RootServiceComponentConfigurationResourceProvider extends AbstractA
     RootServiceComponentConfigurationHandler handler = rootServiceComponentConfigurationHandlerFactory.getInstance(serviceName, componentName, categoryName);
 
     if (handler != null) {
-      Map<String, Map<String, String>> configurations = handler.getConfigurations(categoryName);
+      Map<String, RootServiceComponentConfiguration> configurations = handler.getConfigurations(categoryName);
 
       if (configurations != null) {
-        for (Map.Entry<String, Map<String, String>> entry : configurations.entrySet()) {
-          resources.add(toResource(serviceName, componentName, entry.getKey(), entry.getValue(), requestedIds));
+        for (Map.Entry<String, RootServiceComponentConfiguration> entry : configurations.entrySet()) {
+          resources.add(toResource(serviceName, componentName, entry.getKey(), entry.getValue().getProperties(), entry.getValue().getPropertyTypes(), requestedIds));
         }
       }
     }

http://git-wip-us.apache.org/repos/asf/ambari/blob/be0e87be/ambari-server/src/main/java/org/apache/ambari/server/ldap/domain/AmbariLdapConfigurationKeys.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/ldap/domain/AmbariLdapConfigurationKeys.java b/ambari-server/src/main/java/org/apache/ambari/server/ldap/domain/AmbariLdapConfigurationKeys.java
index 2e1c36b..b7a713b 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/ldap/domain/AmbariLdapConfigurationKeys.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/ldap/domain/AmbariLdapConfigurationKeys.java
@@ -14,62 +14,73 @@
 
 package org.apache.ambari.server.ldap.domain;
 
+import static org.apache.ambari.server.configuration.ConfigurationPropertyType.PASSWORD;
+import static org.apache.ambari.server.configuration.ConfigurationPropertyType.PLAINTEXT;
+
+import org.apache.ambari.server.configuration.ConfigurationPropertyType;
+
 /**
  * Constants representing supported LDAP related property names
- * // todo extend this with validation information, description, defaults maybe
+ * // TODO: extend this with validation information, description, defaults maybe
  */
 public enum AmbariLdapConfigurationKeys {
 
-  LDAP_ENABLED("ambari.ldap.authentication.enabled"),
-  SERVER_HOST("ambari.ldap.connectivity.server.host"),
-  SERVER_PORT("ambari.ldap.connectivity.server.port"),
-  USE_SSL("ambari.ldap.connectivity.use_ssl"),
+  LDAP_ENABLED("ambari.ldap.authentication.enabled", PLAINTEXT),
+  SERVER_HOST("ambari.ldap.connectivity.server.host", PLAINTEXT),
+  SERVER_PORT("ambari.ldap.connectivity.server.port", PLAINTEXT),
+  USE_SSL("ambari.ldap.connectivity.use_ssl", PLAINTEXT),
 
-  TRUST_STORE("ambari.ldap.connectivity.trust_store"),
-  TRUST_STORE_TYPE("ambari.ldap.connectivity.trust_store.type"),
-  TRUST_STORE_PATH("ambari.ldap.connectivity.trust_store.path"),
-  TRUST_STORE_PASSWORD("ambari.ldap.connectivity.trust_store.password"),
-  ANONYMOUS_BIND("ambari.ldap.connectivity.anonymous_bind"),
+  TRUST_STORE("ambari.ldap.connectivity.trust_store", PLAINTEXT),
+  TRUST_STORE_TYPE("ambari.ldap.connectivity.trust_store.type", PLAINTEXT),
+  TRUST_STORE_PATH("ambari.ldap.connectivity.trust_store.path", PLAINTEXT),
+  TRUST_STORE_PASSWORD("ambari.ldap.connectivity.trust_store.password", PASSWORD),
+  ANONYMOUS_BIND("ambari.ldap.connectivity.anonymous_bind", PLAINTEXT),
 
-  BIND_DN("ambari.ldap.connectivity.bind_dn"),
-  BIND_PASSWORD("ambari.ldap.connectivity.bind_password"),
+  BIND_DN("ambari.ldap.connectivity.bind_dn", PLAINTEXT),
+  BIND_PASSWORD("ambari.ldap.connectivity.bind_password", PASSWORD),
 
-  ATTR_DETECTION("ambari.ldap.attributes.detection"), // manual | auto
+  ATTR_DETECTION("ambari.ldap.attributes.detection", PLAINTEXT), // manual | auto
 
-  DN_ATTRIBUTE("ambari.ldap.attributes.dn_attr"),
+  DN_ATTRIBUTE("ambari.ldap.attributes.dn_attr", PLAINTEXT),
 
-  USER_OBJECT_CLASS("ambari.ldap.attributes.user.object_class"),
-  USER_NAME_ATTRIBUTE("ambari.ldap.attributes.user.name_attr"),
-  USER_GROUP_MEMBER_ATTRIBUTE("ambari.ldap.attributes.user.group_member_attr"),
-  USER_SEARCH_BASE("ambari.ldap.attributes.user.search_base"),
+  USER_OBJECT_CLASS("ambari.ldap.attributes.user.object_class", PLAINTEXT),
+  USER_NAME_ATTRIBUTE("ambari.ldap.attributes.user.name_attr", PLAINTEXT),
+  USER_GROUP_MEMBER_ATTRIBUTE("ambari.ldap.attributes.user.group_member_attr", PLAINTEXT),
+  USER_SEARCH_BASE("ambari.ldap.attributes.user.search_base", PLAINTEXT),
 
-  GROUP_OBJECT_CLASS("ambari.ldap.attributes.group.object_class"),
-  GROUP_NAME_ATTRIBUTE("ambari.ldap.attributes.group.name_attr"),
-  GROUP_MEMBER_ATTRIBUTE("ambari.ldap.attributes.group.member_attr"),
-  GROUP_SEARCH_BASE("ambari.ldap.attributes.group.search_base"),
+  GROUP_OBJECT_CLASS("ambari.ldap.attributes.group.object_class", PLAINTEXT),
+  GROUP_NAME_ATTRIBUTE("ambari.ldap.attributes.group.name_attr", PLAINTEXT),
+  GROUP_MEMBER_ATTRIBUTE("ambari.ldap.attributes.group.member_attr", PLAINTEXT),
+  GROUP_SEARCH_BASE("ambari.ldap.attributes.group.search_base", PLAINTEXT),
 
-  USER_SEARCH_FILTER("ambari.ldap.advanced.user_search_filter"),
-  USER_MEMBER_REPLACE_PATTERN("ambari.ldap.advanced.user_member_replace_pattern"),
-  USER_MEMBER_FILTER("ambari.ldap.advanced.user_member_filter"),
+  USER_SEARCH_FILTER("ambari.ldap.advanced.user_search_filter", PLAINTEXT),
+  USER_MEMBER_REPLACE_PATTERN("ambari.ldap.advanced.user_member_replace_pattern", PLAINTEXT),
+  USER_MEMBER_FILTER("ambari.ldap.advanced.user_member_filter", PLAINTEXT),
 
-  GROUP_SEARCH_FILTER("ambari.ldap.advanced.group_search_filter"),
-  GROUP_MEMBER_REPLACE_PATTERN("ambari.ldap.advanced.group_member_replace_pattern"),
-  GROUP_MEMBER_FILTER("ambari.ldap.advanced.group_member_filter"),
+  GROUP_SEARCH_FILTER("ambari.ldap.advanced.group_search_filter", PLAINTEXT),
+  GROUP_MEMBER_REPLACE_PATTERN("ambari.ldap.advanced.group_member_replace_pattern", PLAINTEXT),
+  GROUP_MEMBER_FILTER("ambari.ldap.advanced.group_member_filter", PLAINTEXT),
 
-  FORCE_LOWERCASE_USERNAMES("ambari.ldap.advanced.force_lowercase_usernames"),
-  REFERRAL_HANDLING("ambari.ldap.advanced.referrals"), // folow
-  PAGINATION_ENABLED("ambari.ldap.advanced.pagination_enabled"); // true | false
+  FORCE_LOWERCASE_USERNAMES("ambari.ldap.advanced.force_lowercase_usernames", PLAINTEXT),
+  REFERRAL_HANDLING("ambari.ldap.advanced.referrals", PLAINTEXT), // folow
+  PAGINATION_ENABLED("ambari.ldap.advanced.pagination_enabled", PLAINTEXT); // true | false
 
   private String propertyName;
+  private ConfigurationPropertyType configurationPropertyType;
 
-  AmbariLdapConfigurationKeys(String propName) {
+  AmbariLdapConfigurationKeys(String propName, ConfigurationPropertyType configurationPropertyType) {
     this.propertyName = propName;
+    this.configurationPropertyType = configurationPropertyType;
   }
 
   public String key() {
     return this.propertyName;
   }
 
+  public ConfigurationPropertyType getConfigurationPropertyType() {
+    return configurationPropertyType;
+  }
+
   public static AmbariLdapConfigurationKeys fromKeyStr(String keyStr) {
     for (AmbariLdapConfigurationKeys key : values()) {
       if (key.key().equals(keyStr)) {
@@ -77,7 +88,7 @@ public enum AmbariLdapConfigurationKeys {
       }
     }
 
-    throw new IllegalStateException("invalid konfiguration key found!");
+    throw new IllegalStateException("invalid configuration key found!");
 
   }
 }

http://git-wip-us.apache.org/repos/asf/ambari/blob/be0e87be/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/RootServiceComponentConfigurationResourceProviderTest.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/RootServiceComponentConfigurationResourceProviderTest.java b/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/RootServiceComponentConfigurationResourceProviderTest.java
index 13c644a..bd0ff1d 100644
--- a/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/RootServiceComponentConfigurationResourceProviderTest.java
+++ b/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/RootServiceComponentConfigurationResourceProviderTest.java
@@ -25,6 +25,8 @@ import static org.easymock.EasyMock.expect;
 import static org.easymock.EasyMock.expectLastCall;
 import static org.easymock.EasyMock.newCapture;
 
+import java.io.File;
+import java.nio.charset.Charset;
 import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.HashSet;
@@ -36,6 +38,7 @@ import java.util.TreeMap;
 import javax.persistence.EntityManager;
 
 import org.apache.ambari.server.api.services.RootServiceComponentConfigurationService;
+import org.apache.ambari.server.configuration.Configuration;
 import org.apache.ambari.server.controller.RootComponent;
 import org.apache.ambari.server.controller.RootService;
 import org.apache.ambari.server.controller.predicate.AndPredicate;
@@ -47,14 +50,23 @@ import org.apache.ambari.server.controller.spi.SystemException;
 import org.apache.ambari.server.controller.utilities.PredicateBuilder;
 import org.apache.ambari.server.events.AmbariConfigurationChangedEvent;
 import org.apache.ambari.server.events.publishers.AmbariEventPublisher;
+import org.apache.ambari.server.ldap.domain.AmbariLdapConfigurationKeys;
 import org.apache.ambari.server.orm.dao.AmbariConfigurationDAO;
 import org.apache.ambari.server.orm.entities.AmbariConfigurationEntity;
 import org.apache.ambari.server.security.TestAuthenticationFactory;
 import org.apache.ambari.server.security.authorization.AuthorizationException;
+import org.apache.ambari.server.security.encryption.CredentialProvider;
+import org.apache.ambari.server.state.stack.OsFamily;
+import org.apache.commons.io.FileUtils;
 import org.easymock.Capture;
 import org.easymock.EasyMockSupport;
 import org.junit.After;
+import org.junit.Before;
 import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.powermock.api.easymock.PowerMock;
+import org.powermock.core.classloader.annotations.PrepareForTest;
+import org.powermock.modules.junit4.PowerMockRunner;
 import org.springframework.security.core.Authentication;
 import org.springframework.security.core.context.SecurityContextHolder;
 
@@ -64,11 +76,40 @@ import com.google.inject.Injector;
 
 import edu.emory.mathcs.backport.java.util.Collections;
 import junit.framework.Assert;
+import junit.framework.AssertionFailedError;
 
+@RunWith(PowerMockRunner.class)
+@PrepareForTest({FileUtils.class, AmbariServerConfigurationHandler.class})
 public class RootServiceComponentConfigurationResourceProviderTest extends EasyMockSupport {
 
   private static final String CATEGORY_NAME_1 = "test-category-1";
   private static final String CATEGORY_NAME_2 = "test-category-2";
+  private static final String LDAP_CONFIG_CATEGORY = AmbariServerConfigurationCategory.LDAP_CONFIGURATION.getCategoryName();
+
+  private Injector injector;
+  private Predicate predicate;
+  private ResourceProvider resourceProvider;
+  private RootServiceComponentConfigurationHandlerFactory factory;
+  private Request request;
+  private AmbariConfigurationDAO dao;
+  private Configuration configuration;
+  private AmbariEventPublisher publisher;
+  private Map<String, String> properties = new HashMap<>();
+  private Set<Map<String, Object>> propertySets = new HashSet<>();
+
+  @Before
+  public void init() throws Exception {
+    injector = createInjector();
+    resourceProvider = injector.getInstance(RootServiceComponentConfigurationResourceProvider.class);
+    predicate = createPredicate(RootService.AMBARI.name(), RootComponent.AMBARI_SERVER.name(), CATEGORY_NAME_1);
+    request = createMock(Request.class);
+    dao = injector.getInstance(AmbariConfigurationDAO.class);
+    configuration = injector.getInstance(Configuration.class);
+    factory = injector.getInstance(RootServiceComponentConfigurationHandlerFactory.class);
+    publisher = injector.getInstance(AmbariEventPublisher.class);
+    properties = new HashMap<>();
+    propertySets = new HashSet<>();
+  }
 
   @After
   public void clearAuthentication() {
@@ -126,21 +167,14 @@ public class RootServiceComponentConfigurationResourceProviderTest extends EasyM
   }
 
   private void testCreateResources(Authentication authentication, String opDirective) throws Exception {
-    Injector injector = createInjector();
-
-    ResourceProvider resourceProvider = injector.getInstance(RootServiceComponentConfigurationResourceProvider.class);
-
-    Set<Map<String, Object>> propertySets = new HashSet<>();
-
-    Map<String, String> properties1 = new HashMap<>();
-    properties1.put("property1a", "value1");
-    properties1.put("property2a", "value2");
-    propertySets.add(toRequestProperties(CATEGORY_NAME_1, properties1));
+    properties.put(Configuration.AMBARI_PYTHON_WRAP.getKey(), "value1");
+    properties.put(Configuration.AMBARI_DISPLAY_URL.getKey(), "value2");
+    propertySets.add(toRequestProperties(CATEGORY_NAME_1, properties));
 
     Map<String, String> properties2 = new HashMap<>();
     if (opDirective == null) {
-      properties2.put("property1b", "value1");
-      properties2.put("property2b", "value2");
+      properties2.put(Configuration.SSL_TRUSTSTORE_TYPE.getKey(), "value1");
+      properties2.put(Configuration.SSL_TRUSTSTORE_PATH.getKey(), "value2");
       propertySets.add(toRequestProperties(CATEGORY_NAME_2, properties2));
     }
 
@@ -151,7 +185,6 @@ public class RootServiceComponentConfigurationResourceProviderTest extends EasyM
       requestInfoProperties = Collections.singletonMap(RootServiceComponentConfigurationService.DIRECTIVE_OPERATION, opDirective);
     }
 
-    Request request = createMock(Request.class);
     expect(request.getProperties()).andReturn(propertySets).once();
     expect(request.getRequestInfoProperties()).andReturn(requestInfoProperties).once();
 
@@ -159,7 +192,6 @@ public class RootServiceComponentConfigurationResourceProviderTest extends EasyM
     Capture<Map<String, String>> capturedProperties2 = newCapture();
 
     if (opDirective == null) {
-      AmbariConfigurationDAO dao = injector.getInstance(AmbariConfigurationDAO.class);
       expect(dao.reconcileCategory(eq(CATEGORY_NAME_1), capture(capturedProperties1), eq(true)))
           .andReturn(true)
           .once();
@@ -168,12 +200,10 @@ public class RootServiceComponentConfigurationResourceProviderTest extends EasyM
           .once();
 
 
-      AmbariEventPublisher publisher = injector.getInstance(AmbariEventPublisher.class);
       publisher.publish(anyObject(AmbariConfigurationChangedEvent.class));
       expectLastCall().times(2);
     }
 
-    RootServiceComponentConfigurationHandlerFactory factory = injector.getInstance(RootServiceComponentConfigurationHandlerFactory.class);
     expect(factory.getInstance(RootService.AMBARI.name(), RootComponent.AMBARI_SERVER.name(), CATEGORY_NAME_1))
         .andReturn(new AmbariServerConfigurationHandler())
         .once();
@@ -205,7 +235,7 @@ public class RootServiceComponentConfigurationResourceProviderTest extends EasyM
     verifyAll();
 
     if (opDirective == null) {
-      validateCapturedProperties(properties1, capturedProperties1);
+      validateCapturedProperties(properties, capturedProperties1);
       validateCapturedProperties(properties2, capturedProperties2);
     } else {
       Assert.assertFalse(capturedProperties1.hasCaptured());
@@ -239,22 +269,11 @@ public class RootServiceComponentConfigurationResourceProviderTest extends EasyM
   }
 
   private void testDeleteResources(Authentication authentication) throws Exception {
-    Injector injector = createInjector();
-
-    ResourceProvider resourceProvider = injector.getInstance(RootServiceComponentConfigurationResourceProvider.class);
-
-    Predicate predicate = createPredicate(RootService.AMBARI.name(), RootComponent.AMBARI_SERVER.name(), CATEGORY_NAME_1);
-
-    Request request = createMock(Request.class);
-
-    AmbariConfigurationDAO dao = injector.getInstance(AmbariConfigurationDAO.class);
     expect(dao.removeByCategory(CATEGORY_NAME_1)).andReturn(1).once();
 
-    AmbariEventPublisher publisher = injector.getInstance(AmbariEventPublisher.class);
     publisher.publish(anyObject(AmbariConfigurationChangedEvent.class));
     expectLastCall().once();
 
-    RootServiceComponentConfigurationHandlerFactory factory = injector.getInstance(RootServiceComponentConfigurationHandlerFactory.class);
     expect(factory.getInstance(RootService.AMBARI.name(), RootComponent.AMBARI_SERVER.name(), CATEGORY_NAME_1))
         .andReturn(new AmbariServerConfigurationHandler())
         .once();
@@ -294,25 +313,15 @@ public class RootServiceComponentConfigurationResourceProviderTest extends EasyM
   }
 
   private void testGetResources(Authentication authentication) throws Exception {
-    Injector injector = createInjector();
-
-    ResourceProvider resourceProvider = injector.getInstance(RootServiceComponentConfigurationResourceProvider.class);
-
-    Predicate predicate = createPredicate(RootService.AMBARI.name(), RootComponent.AMBARI_SERVER.name(), CATEGORY_NAME_1);
-
-    Request request = createMock(Request.class);
     expect(request.getPropertyIds()).andReturn(null).anyTimes();
 
-    Map<String, String> properties = new HashMap<>();
-    properties.put("property1a", "value1");
-    properties.put("property2a", "value2");
+    properties.put(AmbariLdapConfigurationKeys.ANONYMOUS_BIND.key(), "value1");
+    properties.put(AmbariLdapConfigurationKeys.GROUP_MEMBER_ATTRIBUTE.key(), "value2");
 
-    AmbariConfigurationDAO dao = injector.getInstance(AmbariConfigurationDAO.class);
     expect(dao.findByCategory(CATEGORY_NAME_1)).andReturn(createEntities(CATEGORY_NAME_1, properties)).once();
 
-    RootServiceComponentConfigurationHandlerFactory factory = injector.getInstance(RootServiceComponentConfigurationHandlerFactory.class);
     expect(factory.getInstance(RootService.AMBARI.name(), RootComponent.AMBARI_SERVER.name(), CATEGORY_NAME_1))
-        .andReturn(new AmbariServerConfigurationHandler())
+        .andReturn(new AmbariServerLDAPConfigurationHandler())
         .once();
 
     replayAll();
@@ -330,16 +339,19 @@ public class RootServiceComponentConfigurationResourceProviderTest extends EasyM
     Assert.assertEquals(Resource.Type.RootServiceComponentConfiguration, resource.getType());
 
     Map<String, Map<String, Object>> propertiesMap = resource.getPropertiesMap();
-    Assert.assertEquals(2, propertiesMap.size());
+    Assert.assertEquals(3, propertiesMap.size());
 
     Assert.assertEquals(CATEGORY_NAME_1, propertiesMap.get(RootServiceComponentConfigurationResourceProvider.RESOURCE_KEY).get("category"));
 
-    Map<String, Object> retrievedProperties = propertiesMap.get(RootServiceComponentConfigurationResourceProvider.RESOURCE_KEY + "/properties");
+    Map<String, Object> retrievedProperties = propertiesMap.get(RootServiceComponentConfigurationResourceProvider.CONFIGURATION_PROPERTIES_PROPERTY_ID);
     Assert.assertEquals(2, retrievedProperties.size());
 
     for (Map.Entry<String, String> entry : properties.entrySet()) {
       Assert.assertEquals(entry.getValue(), retrievedProperties.get(entry.getKey()));
     }
+
+    Map<String, Object> retrievedPropertyTypes = propertiesMap.get(RootServiceComponentConfigurationResourceProvider.CONFIGURATION_PROPERTY_TYPES_PROPERTY_ID);
+    Assert.assertEquals(2, retrievedPropertyTypes.size());
   }
 
   @Test
@@ -393,18 +405,9 @@ public class RootServiceComponentConfigurationResourceProviderTest extends EasyM
   }
 
   private void testUpdateResources(Authentication authentication, String opDirective) throws Exception {
-    Injector injector = createInjector();
-
-    ResourceProvider resourceProvider = injector.getInstance(RootServiceComponentConfigurationResourceProvider.class);
-
-    Predicate predicate = createPredicate(RootService.AMBARI.name(), RootComponent.AMBARI_SERVER.name(), CATEGORY_NAME_1);
-
-    Set<Map<String, Object>> propertySets = new HashSet<>();
-
-    Map<String, String> properties1 = new HashMap<>();
-    properties1.put("property1a", "value1");
-    properties1.put("property2a", "value2");
-    propertySets.add(toRequestProperties(CATEGORY_NAME_1, properties1));
+    properties.put(Configuration.AMBARI_DISPLAY_URL.getKey(), "value1");
+    properties.put(Configuration.BOOTSTRAP_MASTER_HOSTNAME.getKey(), "value2");
+    propertySets.add(toRequestProperties(CATEGORY_NAME_1, properties));
 
     Map<String, String> requestInfoProperties;
     if (opDirective == null) {
@@ -413,24 +416,20 @@ public class RootServiceComponentConfigurationResourceProviderTest extends EasyM
       requestInfoProperties = Collections.singletonMap(RootServiceComponentConfigurationService.DIRECTIVE_OPERATION, opDirective);
     }
 
-    Request request = createMock(Request.class);
     expect(request.getProperties()).andReturn(propertySets).once();
     expect(request.getRequestInfoProperties()).andReturn(requestInfoProperties).once();
 
     Capture<Map<String, String>> capturedProperties1 = newCapture();
 
     if (opDirective == null) {
-      AmbariConfigurationDAO dao = injector.getInstance(AmbariConfigurationDAO.class);
       expect(dao.reconcileCategory(eq(CATEGORY_NAME_1), capture(capturedProperties1), eq(false)))
           .andReturn(true)
           .once();
 
-      AmbariEventPublisher publisher = injector.getInstance(AmbariEventPublisher.class);
       publisher.publish(anyObject(AmbariConfigurationChangedEvent.class));
       expectLastCall().times(1);
     }
 
-    RootServiceComponentConfigurationHandlerFactory factory = injector.getInstance(RootServiceComponentConfigurationHandlerFactory.class);
     expect(factory.getInstance(RootService.AMBARI.name(), RootComponent.AMBARI_SERVER.name(), CATEGORY_NAME_1))
         .andReturn(new AmbariServerConfigurationHandler())
         .once();
@@ -458,12 +457,83 @@ public class RootServiceComponentConfigurationResourceProviderTest extends EasyM
     verifyAll();
 
     if (opDirective == null) {
-      validateCapturedProperties(properties1, capturedProperties1);
+      validateCapturedProperties(properties, capturedProperties1);
     } else {
       Assert.assertFalse(capturedProperties1.hasCaptured());
     }
   }
 
+  @Test
+  public void shouldNotUpdatePasswordIfItHasNotBeenChanged() throws Exception {
+    SecurityContextHolder.getContext().setAuthentication(TestAuthenticationFactory.createAdministrator());
+    properties.put(AmbariLdapConfigurationKeys.BIND_PASSWORD.key(), "passwd");
+    propertySets.add(toRequestProperties(LDAP_CONFIG_CATEGORY, properties));
+    setupBasicExpectations(properties);
+    expect(configuration.isSecurityPasswordEncryptionEnabled()).andThrow(new AssertionFailedError()).anyTimes(); //this call should never have never been hit
+
+    replayAll();
+    resourceProvider.updateResources(request, predicate);
+    verifyAll();
+  }
+
+  @Test
+  public void shouldUpdatePasswordFileIfSecurityPasswordEncryptionIsDisabled() throws Exception {
+    SecurityContextHolder.getContext().setAuthentication(TestAuthenticationFactory.createAdministrator());
+    properties.put(AmbariLdapConfigurationKeys.BIND_PASSWORD.key(), "newPasswd");
+    propertySets.add(toRequestProperties(LDAP_CONFIG_CATEGORY, properties));
+    Map<String, String> expectedProperties = new HashMap<>();
+    expectedProperties.put(AmbariLdapConfigurationKeys.BIND_PASSWORD.key(), "currentPasswd");
+    setupBasicExpectations(expectedProperties);
+    expect(configuration.isSecurityPasswordEncryptionEnabled()).andReturn(false).once();
+    PowerMock.mockStatic(FileUtils.class);
+    FileUtils.writeStringToFile(new File("currentPasswd"), "newPasswd", Charset.defaultCharset());
+    PowerMock.expectLastCall().once();
+    PowerMock.replay(FileUtils.class);
+    publisher.publish(anyObject(AmbariConfigurationChangedEvent.class));
+    expectLastCall().once();
+
+    replayAll();
+    resourceProvider.updateResources(request, predicate);
+    verifyAll();
+  }
+
+  @Test
+  public void shouldUpdatePasswordInCredentialStoreIfSecurityPasswordEncryptionIsEnabled() throws Exception {
+    SecurityContextHolder.getContext().setAuthentication(TestAuthenticationFactory.createAdministrator());
+    properties.put(AmbariLdapConfigurationKeys.BIND_PASSWORD.key(), "newPasswd");
+    propertySets.add(toRequestProperties(LDAP_CONFIG_CATEGORY, properties));
+    Map<String, String> expectedProperties = new HashMap<>();
+    expectedProperties.put(AmbariLdapConfigurationKeys.BIND_PASSWORD.key(), "currentPasswd");
+    setupBasicExpectations(expectedProperties);
+    expect(configuration.isSecurityPasswordEncryptionEnabled()).andReturn(true).once();
+
+    File masterKeyLocation = createNiceMock(File.class);
+    File masterKeyStoreLocation = createNiceMock(File.class);
+    expect(configuration.getMasterKeyLocation()).andReturn(masterKeyLocation).once();
+    expect(configuration.isMasterKeyPersisted()).andReturn(false).once();
+    expect(configuration.getMasterKeyStoreLocation()).andReturn(masterKeyStoreLocation).once();
+    CredentialProvider credentialProvider = PowerMock.createMock(CredentialProvider.class);
+    PowerMock.expectNew(CredentialProvider.class, null, (String) null, masterKeyLocation, false, masterKeyStoreLocation).andReturn(credentialProvider);
+    credentialProvider.addAliasToCredentialStore("currentPasswd", "newPasswd");
+    PowerMock.expectLastCall().once();
+    PowerMock.replay(credentialProvider, CredentialProvider.class);
+
+    publisher.publish(anyObject(AmbariConfigurationChangedEvent.class));
+    expectLastCall().once();
+
+    replayAll();
+    resourceProvider.updateResources(request, predicate);
+    verifyAll();
+    PowerMock.verify(credentialProvider, CredentialProvider.class);
+  }
+
+  private void setupBasicExpectations(Map<String, String> expectedProperties) {
+    expect(request.getProperties()).andReturn(propertySets).once();
+    expect(request.getRequestInfoProperties()).andReturn(new HashMap<>());
+    expect(dao.findByCategory(LDAP_CONFIG_CATEGORY)).andReturn(createEntities(AmbariServerConfigurationCategory.LDAP_CONFIGURATION.getCategoryName(), expectedProperties)).once();
+    expect(factory.getInstance(RootService.AMBARI.name(), RootComponent.AMBARI_SERVER.name(), LDAP_CONFIG_CATEGORY)).andReturn(new AmbariServerLDAPConfigurationHandler()).once();
+  }
+
   private Predicate createPredicate(String serviceName, String componentName, String categoryName) {
     Predicate predicateService = new PredicateBuilder()
         .property(CONFIGURATION_SERVICE_NAME_PROPERTY_ID)
@@ -521,6 +591,8 @@ public class RootServiceComponentConfigurationResourceProviderTest extends EasyM
     return Guice.createInjector(new AbstractModule() {
       @Override
       protected void configure() {
+        bind(OsFamily.class).toInstance(createNiceMock(OsFamily.class));
+        bind(Configuration.class).toInstance(createNiceMock(Configuration.class));
         bind(EntityManager.class).toInstance(createNiceMock(EntityManager.class));
         bind(AmbariConfigurationDAO.class).toInstance(createMock(AmbariConfigurationDAO.class));
         bind(AmbariEventPublisher.class).toInstance(createMock(AmbariEventPublisher.class));