Blogs

Blogs

Where am I? (how to know which cluster node you're on)

When working with a cluster you pretty quickly come to a point where you want/need to know what cluster node you're on.

Liferay already has a simple way to show you this. You just need to add the following line to your portal-ext.properties and hey presto! it shows the current web server node ID in a blue box at the bottom of the page:

web.server.display.node=true

While this works perfectly it has one drawback: customers don't really want to see this in production, while we need it at times to be able to debug a problem. There are a number of ways to solve this catch 22 type of situation:

  • Leave the property turned on but hide the blue box using CSS. This allows you to check the value by using the inspect element functionality found in most browsers these days.
  • Turn off the property and add a hidden page that contains a web content display portlet that uses a simple Velocity/Freemarker template to show the same value (which according to the file Liferay uses, /html/portal/layout/view/common.jspf, is PortalUtil.getComputerName()).

I want to present a 3rd option: extend the dockbar with a new icon that allows you to display the node ID (and other cluster node specific data). For this we'll need to override /html/portlet/dockbar/view.jsp and add some code to it.

First is the button which we'll add right before the Toggle Edit Controls button:

<c:if test="<%= showEditControls %>">
   <portlet:renderURL var="editLayoutURL" windowState="<%= LiferayWindowState.EXCLUSIVE.toString() %>">
      <portlet:param name="struts_action" value="/dockbar/edit_layout_panel" />
      <portlet:param name="closeRedirect" value="<%= PortalUtil.getLayoutURL(layout, themeDisplay) %>" />
      <portlet:param name="selPlid" value="<%= String.valueOf(plid) %>" />
   </portlet:renderURL>

   <aui:nav-item anchorId="editLayoutPanel" cssClass="page-edit-controls" data-panelURL="<%= editLayoutURL %>" href="javascript:;" iconCssClass="icon-edit" label="edit" />
</c:if>

<c:if test="<%= PropsValues.WEB_SERVER_DISPLAY_NODE %>">
   <aui:nav-item cssClass="toggle-cluster-link" iconCssClass="icon-map-marker" />
</c:if>

<c:if test="<%= showToggleControls %>">
   <aui:nav-item anchorCssClass="toggle-controls-link" cssClass="toggle-controls" iconCssClass='<%= "controls-state-icon " + (toggleControlsState.equals("visible") ? "icon-eye-open" : "icon-eye-close") %>' id="toggleControls" />
</c:if>

Secondly we'll need some CSS and Javascript (which we add to the existing aui:script tag) to be able to add an action to our new button that will show a popover with the information we want:

<style type="text/css">
   .popover, .aui .popover.right .arrow {
      z-index: 1000 !important;
   }
</style>

<%
   StringBuilder nodeInfo = new StringBuilder();
   nodeInfo.append("<ul>");
   nodeInfo.append("<li>Host: " + PortalUtil.getComputerName() + "</li>");
   nodeInfo.append("<li>ID: " + com.liferay.portal.kernel.cluster.ClusterExecutorUtil.getLocalClusterNode().getClusterNodeId() + "</li>");
   nodeInfo.append("<li>IP: " + com.liferay.portal.kernel.cluster.ClusterExecutorUtil.getLocalClusterNode().getInetAddress() + "</li>");
   nodeInfo.append("</ul>");
%>

<aui:script position="inline" use="liferay-dockbar,aui-popover">
   Liferay.Dockbar.init('#<portlet:namespace />dockbar');

   var customizableColumns = A.all('.portlet-column-content.customizable');

   if (customizableColumns.size() > 0) {
      customizableColumns.get('parentNode').addClass('customizable');
   }

   // Add cluster node ID
   var trigger = A.one('.toggle-cluster-link');
   if (trigger != null) {
       var popover = new A.Popover(
         {
           align: {
             node: trigger,
             points:[A.WidgetPositionAlign.LC, A.WidgetPositionAlign.RC]
           },
           bodyContent: '<%= nodeInfo %>',
           position: 'right',
           visible: false
         }
       ).render();

       trigger.on(
         'click',
         function() {
           popover.set('visible', !popover.get('visible'));
         }
       );

      A.one('body').on(
          'key',
          function() {
             // http://keycode.info/
              popover.set('visible', !popover.get('visible'));
          },
          'down:78+shift'
       );
   }

</aui:script>

The Javascript code above also adds a keyboard shortcut, SHIFT+N, to the button so that you can even show the popover without even needing to click the button. You can find the complete file here: https://gist.github.com/planetsizebrain/3f9788a78224be73d80b. This will give you the following result:

If you want something similar, but don't want to add a button to the dockbar, you could use similar code to make the existing blue bar appear/disappear when a shortcut is pressed.

Blogs
Very interesting !
I choose second option.

Thanks !

Hi Jan,

 

After overriding the  /html/portlet/dockbar/view.jsp file, do we still need to hide the  blue bar through CSS? I am able to achieve the dockbar button. But commenting the property web.server.display.node=true in portal-ext.properties removes this dockbar button also.  How do i get ride of the blue bar. Any help is much appreciated.

Answering to my question, we were able to hide the blue bar in all the pages except control panel by adding below CSS under Control Panel -> Sites -> <My sites> -> "Insert custom CSS that will be loaded after the theme."

 

#content .alert.alert-info {     display: none; }