Merge branch 'master' into Health-Check-UI

Conflicts:
	ui/css/cloudstack3.css
diff --git a/ui/css/cloudstack3.css b/ui/css/cloudstack3.css
index 7381715..7410568 100644
--- a/ui/css/cloudstack3.css
+++ b/ui/css/cloudstack3.css
@@ -1763,6 +1763,37 @@
 }
 
 .detail-group .main-groups table td.value .view-all:hover {
+   background-position: 100% -431px;
+ }
+
+/*List-view: subselect dropdown*/
+.list-view .subselect {
+  width: 116px;
+  display: block;
+  float: left;
+  background: url(../images/bg-gradients.png) 0px -42px;
+  padding: 0;
+  margin: 8px 0 1px 7px;
+  clear: both;
+  border: 1px solid #A8A7A7;
+  /*+border-radius:4px;*/
+  -moz-border-radius: 4px;
+  -webkit-border-radius: 4px;
+  -khtml-border-radius: 4px;
+  border-radius: 4px;
+}
+
+.list-view .subselect span {
+  margin: 4px 0 0 12px;
+}
+
+.list-view .subselect select {
+  width: 85%;
+ margin: 5px 0 4px;
+  font-size: 10px;
+}
+
+.detail-group .main-groups table td.value .view-all:hover {
   background-position: 100% -431px;
 }
 
@@ -7743,9 +7774,27 @@
   margin: 0 22px 0 0;
 }
 
+ /** Fix long table overflow*/
+.detail-view .multi-edit {
+  width: 100%;
+}
+
+.detail-view .multi-edit table {
+  width: 97%;
+  max-width: inherit;
+}
+
+.detail-view .multi-edit table tr th,
+.detail-view .multi-edit table tr td {
+  width: 87px !important;
+  min-width: 87px !important;
+  max-width: 87px !important;
+}
+
+ 
 /** Header fields*/
 .multi-edit .header-fields {
-  position: relative;
+  position: relative; 
   /*+placement:shift 14px 11px;*/
   position: relative;
   left: 14px;
@@ -10561,6 +10610,33 @@
   width: 65px;
 }
 
+/*HEALTH CHECK */
+
+div.ui-dialog div.health-check div.health-check-description {
+color: #808080;
+}
+
+div.ui-dialog div.health-check div.form-container form div.form-item { 
+width:58% margin-left:116px; margin-top:-16px; margin-bottom:30px; }
+
+div.ui-dialog div.health-check div.health-check-config-title { 
+float:left;
+color: #808080;
+font-size:17px;
+margin-left:15px;
+}
+
+div.ui-dialog div.health-check div.health-check-advanced-title { 
+float:left;
+color: #808080;
+font-size:17px;
+margin-left:15px;
+margin-top:-70px;
+}
+
+
+
+
 /*Autoscaler*/
 .ui-dialog div.autoscaler {
   overflow: auto;
diff --git a/ui/index.jsp b/ui/index.jsp
index d1e6bfa..3b8f378 100644
--- a/ui/index.jsp
+++ b/ui/index.jsp
@@ -1645,6 +1645,7 @@
     <script type="text/javascript" src="scripts/cloudStack.js?t=<%=now%>"></script>
     <script type="text/javascript" src="scripts/lbStickyPolicy.js?t=<%=now%>"></script>
     <script type="text/javascript" src="scripts/ui-custom/autoscaler.js?t=<%=now%>"></script>
+    <script type="text/javascript" src="scripts/ui-custom/healthCheck.js?t=<%=now%>"></script>
     <script type="text/javascript" src="scripts/autoscaler.js?t=<%=now%>"></script>
     <script type="text/javascript" src="scripts/ui-custom/zoneChart.js?t=<%=now%>"></script>
     <script type="text/javascript" src="scripts/ui-custom/dashboard.js?t=<%=now%>"></script>
diff --git a/ui/scripts/network.js b/ui/scripts/network.js
index 15ead8c..65be302 100755
--- a/ui/scripts/network.js
+++ b/ui/scripts/network.js
@@ -2609,6 +2609,17 @@
                           action: cloudStack.lbStickyPolicy.dialog()
                         }
                       },
+
+                     'health-check':{
+                          label:'Health Check',
+                          custom:{
+                             requireValidation: true ,
+                             buttonLabel:'Configure',
+                             action:cloudStack.uiCustom.healthCheck()
+
+                           }
+                        },
+
                       'autoScale': {
                         label: 'AutoScale',
                         custom: {
diff --git a/ui/scripts/ui-custom/healthCheck.js b/ui/scripts/ui-custom/healthCheck.js
new file mode 100644
index 0000000..c4c84e5
--- /dev/null
+++ b/ui/scripts/ui-custom/healthCheck.js
@@ -0,0 +1,342 @@
+// 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.
+
+(function($, cloudStack) {
+
+  cloudStack.uiCustom.healthCheck = function(args) {
+
+    // Place outer args here as local variables
+    // i.e, -- var dataProvider = args.dataProvider
+
+    return function(args){         		
+			if(args.context.multiRules == undefined) { //LB rule is not created yet
+			  cloudStack.dialog.notice({ message: _l('Health Check can only be configured on a created LB rule') });
+				return;
+			}
+			
+      var formData = args.formData;
+      var forms = $.extend(true, {}, args.forms);
+      var topFieldForm, bottomFieldForm , $topFieldForm , $bottomFieldForm;
+      var topfields = forms.topFields; 
+
+      var $healthCheckDesc = $('<div>Your load balancer will automatically perform health checks on your cloudstack instances and only route traffic to instances that pass the health check </div>').addClass('health-check-description');
+      var $healthCheckConfigTitle = $('<div><br><br>Configuration Options :</div>').addClass('health-check-config-title');
+      var $healthCheckAdvancedTitle = $('<div><br><br> Advanced Options : </div>').addClass('health-check-advanced-title');
+    
+      var $healthCheckDialog = $('<div>').addClass('health-check');
+      $healthCheckDialog.append($healthCheckDesc);
+      $healthCheckDialog.append($healthCheckConfigTitle);
+    	var $loadingOnDialog = $('<div>').addClass('loading-overlay');
+							
+      var policyObj = null;				
+			var pingpath1 = '/';
+			var responsetimeout1 = '2';
+			var healthinterval1 = '5';			
+			var healthythreshold1 = '2';
+			var unhealthythreshold1 = '1';
+			
+			$.ajax({
+			  url: createURL('listLBHealthCheckPolicies'),
+				data: {
+				  lbruleid: args.context.multiRules[0].id
+				},
+				async: false,
+				success: function(json) {		
+					if(json.listlbhealthcheckpoliciesresponse.healthcheckpolicies[0].healthcheckpolicy[0] !=	undefined) {
+					  policyObj = json.listlbhealthcheckpoliciesresponse.healthcheckpolicies[0].healthcheckpolicy[0];
+						pingpath1 = policyObj.pingpath; //API bug: API doesn't return it
+						responsetimeout1 = policyObj.responsetime;
+						healthinterval1 =	policyObj.healthcheckinterval;		
+						healthythreshold1 = policyObj.healthcheckthresshold;
+						unhealthythreshold1 =	policyObj.unhealthcheckthresshold;
+					}
+				}
+			});
+     
+      topFieldForm = cloudStack.dialog.createForm({
+          context: args.context,
+          noDialog: true, // Don't render a dialog, just return $formContainer
+          form: {
+            title: '',
+            fields:{               					 
+               pingpath: {label: 'Ping Path', docID:'helpAccountUsername' , validation: {required: false}, defaultValue: pingpath1}
+             }
+          }
+        });
+
+      $topFieldForm = topFieldForm.$formContainer;
+      $topFieldForm.appendTo($healthCheckDialog);
+
+      $healthCheckDialog.append($healthCheckAdvancedTitle);
+
+      bottomFieldForm = cloudStack.dialog.createForm ({
+        context:args.context,
+        noDialog:true,
+        form:{
+          title:'',
+          fields:{
+            responsetimeout: {label: 'Response Timeout (in sec)' , validation:{required:false}, defaultValue: responsetimeout1},
+            healthinterval: {label: 'Health Check Interval (in sec)',  validation:{required:false}, defaultValue: healthinterval1},                    
+            healthythreshold:  {label: 'Healthy Threshold', validation: {required:false}, defaultValue: healthythreshold1},
+					  unhealthythreshold: {label: 'Unhealthy Threshold' , validation: { required:false}, defaultValue: unhealthythreshold1}
+          }
+        }
+      });
+
+      $bottomFieldForm = bottomFieldForm.$formContainer;
+      $bottomFieldForm.appendTo($healthCheckDialog);
+					
+					
+			var buttons = [
+				{
+					text: _l('label.cancel'),
+					'class': 'cancel',
+					click: function() {
+						$healthCheckDialog.dialog('destroy');
+						 $('.overlay').remove();
+					}
+				}
+			];	
+			
+			if(policyObj == null) { //policy is not created yet
+			  buttons.push(				  
+          {
+            text: _l('Create'),
+            'class': 'ok',
+            click: function() {     
+              $loadingOnDialog.appendTo($healthCheckDialog);							
+						  var formData = cloudStack.serializeForm($healthCheckDialog.find('form'));							
+							var data = {
+							  lbruleid: args.context.multiRules[0].id, 					
+								pingpath: formData.pingpath,
+								responsetimeout: formData.responsetimeout,
+								intervaltime: formData.healthinterval,
+								healthythreshold: formData.healthythreshold,
+								unhealthythreshold: formData.unhealthythreshold								
+							};
+														
+							$.ajax({
+							  url: createURL('createLBHealthCheckPolicy'),
+								data: data,
+								success: function(json) {								  
+									var jobId = json.createlbhealthcheckpolicyresponse.jobid;
+									var createLBHealthCheckPolicyIntervalId = setInterval(function(){									  
+										$.ajax({
+										  url: createURL('queryAsyncJobResult'),
+											data: {
+											  jobid: jobId
+											},
+											success: function(json) {	
+												var result = json.queryasyncjobresultresponse;
+												if (result.jobstatus == 0) {
+													return; //Job has not completed
+												}
+												else {                                      
+													clearInterval(createLBHealthCheckPolicyIntervalId); 
+													
+													if (result.jobstatus == 1) {	
+													  cloudStack.dialog.notice({ message: _l('Health Check Policy has been created') });														
+                            $loadingOnDialog.remove();	
+														$healthCheckDialog.dialog('destroy');
+                            $('.overlay').remove();
+													}
+													else if (result.jobstatus == 2) {		
+													  cloudStack.dialog.notice({ message: _s(result.jobresult.errortext) });			
+                            $loadingOnDialog.remove();	
+														$healthCheckDialog.dialog('destroy');
+                            $('.overlay').remove();		
+													}
+												}																						
+											}
+										});										
+									}, g_queryAsyncJobResultInterval); 										
+								}
+							});
+            }
+          }					
+				);
+			}
+			else { //policy exists already			  
+				buttons.push(	
+          //Update Button (begin) - call delete API first, then create API				
+          {
+            text: _l('Update'),
+            'class': 'ok',
+            click: function() {    
+              $loadingOnDialog.appendTo($healthCheckDialog);
+						
+							$.ajax({
+							  url: createURL('deleteLBHealthCheckPolicy'),
+								data: {
+								  id : policyObj.id
+								},
+								success: function(json) {								  						
+									var jobId = json.deletelbhealthcheckpolicyresponse.jobid;
+									var deleteLBHealthCheckPolicyIntervalId = setInterval(function(){									  
+										$.ajax({
+										  url: createURL('queryAsyncJobResult'),
+											data: {
+											  jobid: jobId
+											},
+											success: function(json) {	
+												var result = json.queryasyncjobresultresponse;
+												if (result.jobstatus == 0) {
+													return; //Job has not completed
+												}
+												else {                                      
+													clearInterval(deleteLBHealthCheckPolicyIntervalId); 
+													
+													if (result.jobstatus == 1) {	
+														var formData = cloudStack.serializeForm($healthCheckDialog.find('form'));	                           										
+														var data = {
+															lbruleid: args.context.multiRules[0].id,					
+															pingpath: formData.pingpath,
+															responsetimeout: formData.responsetimeout,
+															intervaltime: formData.healthinterval,
+															healthythreshold: formData.healthythreshold,
+															unhealthythreshold: formData.unhealthythreshold								
+														};
+																					
+														$.ajax({
+															url: createURL('createLBHealthCheckPolicy'),
+															data: data,
+															success: function(json) {								  
+																var jobId = json.createlbhealthcheckpolicyresponse.jobid;
+																var createLBHealthCheckPolicyIntervalId = setInterval(function(){									  
+																	$.ajax({
+																		url: createURL('queryAsyncJobResult'),
+																		data: {
+																			jobid: jobId
+																		},
+																		success: function(json) {	
+																			var result = json.queryasyncjobresultresponse;
+																			if (result.jobstatus == 0) {
+																				return; //Job has not completed
+																			}
+																			else {                                      
+																				clearInterval(createLBHealthCheckPolicyIntervalId); 
+																				
+																				if (result.jobstatus == 1) {	   
+																					cloudStack.dialog.notice({ message: _l('Health Check Policy has been updated') });
+																					$loadingOnDialog.remove();	
+																					$healthCheckDialog.dialog('destroy');
+																					$('.overlay').remove();																					
+																				}
+																				else if (result.jobstatus == 2) {																				  
+																					cloudStack.dialog.notice({ message: _s(result.jobresult.errortext) });		
+                                          $loadingOnDialog.remove();	
+																					$healthCheckDialog.dialog('destroy');
+																					$('.overlay').remove();																										
+																				}
+																			}																						
+																		}
+																	});										
+																}, g_queryAsyncJobResultInterval); 										
+															}
+														});														
+													}
+													else if (result.jobstatus == 2) {													  
+														cloudStack.dialog.notice({ message: _s(result.jobresult.errortext) });	
+                            $loadingOnDialog.remove();	
+														$healthCheckDialog.dialog('destroy');
+														$('.overlay').remove();																
+													}
+												}																						
+											}
+										});										
+									}, g_queryAsyncJobResultInterval); 										
+								}
+							});												
+            }
+          }
+					//Update Button (end) 
+					,					
+					//Delete Button (begin) - call delete API 		
+          {
+            text: _l('Delete'),
+            'class': 'delete',
+            click: function() {    
+              $loadingOnDialog.appendTo($healthCheckDialog);
+						
+							$.ajax({
+							  url: createURL('deleteLBHealthCheckPolicy'),
+								data: {
+								  id : policyObj.id
+								},
+								success: function(json) {								  						
+									var jobId = json.deletelbhealthcheckpolicyresponse.jobid;
+									var deleteLBHealthCheckPolicyIntervalId = setInterval(function(){									  
+										$.ajax({
+										  url: createURL('queryAsyncJobResult'),
+											data: {
+											  jobid: jobId
+											},
+											success: function(json) {	
+												var result = json.queryasyncjobresultresponse;
+												if (result.jobstatus == 0) {
+													return; //Job has not completed
+												}
+												else {                                      
+													clearInterval(deleteLBHealthCheckPolicyIntervalId); 
+													
+													if (result.jobstatus == 1) {															
+														cloudStack.dialog.notice({ message: _l('Health Check Policy has been deleted') });														
+                            $loadingOnDialog.remove();	
+														$healthCheckDialog.dialog('destroy');
+                            $('.overlay').remove();																										
+													}
+													else if (result.jobstatus == 2) {													  
+														cloudStack.dialog.notice({ message: _s(result.jobresult.errortext) });	
+                            $loadingOnDialog.remove();	
+														$healthCheckDialog.dialog('destroy');
+														$('.overlay').remove();																
+													}
+												}																						
+											}
+										});										
+									}, g_queryAsyncJobResultInterval); 										
+								}
+							});												
+            }
+          }
+					//Delete Button (end) 
+				);				
+			}
+						
+      $healthCheckDialog.dialog({
+        title: 'Health Check Wizard',
+        width: 600,
+        height: 600,
+        draggable: true,
+        closeonEscape: false,
+        overflow:'auto',
+        open:function() {
+          $("button").each(function(){
+            $(this).attr("style", "left: 400px; position: relative; margin-right: 5px; ");
+          });
+       
+          $('.ui-dialog .delete').css('left','140px');
+
+        },
+        buttons: buttons
+      }).closest('.ui-dialog').overlay();
+
+    }
+  }
+ }(jQuery, cloudStack));
+
+
diff --git a/ui/scripts/ui/widgets/toolTip.js b/ui/scripts/ui/widgets/toolTip.js
index af6c2aa..6967acc 100644
--- a/ui/scripts/ui/widgets/toolTip.js
+++ b/ui/scripts/ui/widgets/toolTip.js
@@ -156,7 +156,7 @@
 
     // Fix overlay
     setTimeout(function() {
-      $('.tooltip-box').zIndex($(':ui-dialog').zIndex() + 1);  });
+      $('.tooltip-box').zIndex($(':ui-dialog').zIndex() + 10);  });
 
   };