001/* 002 * The contents of this file are subject to the terms of the Common Development and 003 * Distribution License (the License). You may not use this file except in compliance with the 004 * License. 005 * 006 * You can obtain a copy of the License at legal/CDDLv1.0.txt. See the License for the 007 * specific language governing permission and limitations under the License. 008 * 009 * When distributing Covered Software, include this CDDL Header Notice in each file and include 010 * the License file at legal/CDDLv1.0.txt. If applicable, add the following below the CDDL 011 * Header, with the fields enclosed by brackets [] replaced by your own identifying 012 * information: "Portions Copyright [year] [name of copyright owner]". 013 * 014 * Copyright 2009-2010 Sun Microsystems, Inc. 015 * Portions Copyright 2014-2015 ForgeRock AS. 016 */ 017package org.opends.guitools.controlpanel.ui; 018 019import static org.opends.messages.AdminToolMessages.*; 020 021import java.awt.Component; 022import java.awt.GridBagConstraints; 023import java.awt.GridBagLayout; 024import java.awt.Insets; 025import java.awt.event.ActionEvent; 026import java.awt.event.ActionListener; 027import java.awt.event.ItemEvent; 028import java.awt.event.ItemListener; 029import java.awt.event.KeyEvent; 030import java.net.InetAddress; 031import java.util.Collections; 032import java.util.Comparator; 033import java.util.HashSet; 034import java.util.LinkedHashSet; 035import java.util.Set; 036import java.util.SortedSet; 037import java.util.TreeSet; 038 039import javax.swing.BorderFactory; 040import javax.swing.Box; 041import javax.swing.DefaultComboBoxModel; 042import javax.swing.JCheckBoxMenuItem; 043import javax.swing.JComboBox; 044import javax.swing.JLabel; 045import javax.swing.JMenu; 046import javax.swing.JMenuBar; 047import javax.swing.JMenuItem; 048import javax.swing.JPanel; 049import javax.swing.JScrollPane; 050import javax.swing.JTable; 051import javax.swing.SwingUtilities; 052import javax.swing.table.DefaultTableCellRenderer; 053 054import org.opends.guitools.controlpanel.datamodel.BasicMonitoringAttributes; 055import org.opends.guitools.controlpanel.datamodel.CategorizedComboBoxElement; 056import org.opends.guitools.controlpanel.datamodel.ConnectionHandlerDescriptor; 057import org.opends.guitools.controlpanel.datamodel. 058 ConnectionHandlersMonitoringTableModel; 059import org.opends.guitools.controlpanel.datamodel.ControlPanelInfo; 060import org.opends.guitools.controlpanel.datamodel.CustomSearchResult; 061import org.opends.guitools.controlpanel.datamodel.MonitoringAttributes; 062import org.opends.guitools.controlpanel.datamodel.ServerDescriptor; 063import org.opends.guitools.controlpanel.datamodel.ConnectionHandlerDescriptor. 064 Protocol; 065import org.opends.guitools.controlpanel.datamodel.ConnectionHandlerDescriptor. 066 State; 067import org.opends.guitools.controlpanel.event.ConfigurationChangeEvent; 068import org.opends.guitools.controlpanel.ui.renderer. 069 NoLeftInsetCategoryComboBoxRenderer; 070import org.opends.guitools.controlpanel.util.Utilities; 071import org.opends.guitools.controlpanel.util.ViewPositions; 072import org.forgerock.i18n.LocalizableMessage; 073import org.forgerock.i18n.LocalizableMessageBuilder; 074 075/** 076 * Class that displays the monitoring information of connection handlers. 077 * 078 */ 079public class ConnectionHandlerMonitoringPanel extends StatusGenericPanel 080{ 081 private static final long serialVersionUID = -6462932160985559830L; 082 083 private MonitoringAttributesViewPanel<MonitoringAttributes> 084 operationViewPanel; 085 private GenericDialog operationViewDlg; 086 087 private JComboBox connectionHandlers; 088 089 private JTable connectionHandlersTable; 090 private JScrollPane connectionHandlersScroll; 091 private ConnectionHandlersMonitoringTableModel connectionHandlersTableModel; 092 093 private JLabel lNoConnectionHandlers = Utilities.createPrimaryLabel( 094 INFO_CTRL_PANEL_NO_CONNECTION_HANDLER_FOUND.get()); 095 096 private boolean firstRealDataSet; 097 098 private JCheckBoxMenuItem showAveragesMenu; 099 100 private ConnectionHandlerMonitoringMenuBar menuBar; 101 102 private LinkedHashSet<MonitoringAttributes> chOperations = new LinkedHashSet<>(); 103 { 104 chOperations.add(BasicMonitoringAttributes.ADD_REQUESTS); 105 chOperations.add(BasicMonitoringAttributes.BIND_REQUESTS); 106 chOperations.add(BasicMonitoringAttributes.DELETE_REQUESTS); 107 chOperations.add(BasicMonitoringAttributes.MOD_REQUESTS); 108 chOperations.add(BasicMonitoringAttributes.MOD_DN_REQUESTS); 109 chOperations.add(BasicMonitoringAttributes.SEARCH_REQUESTS); 110 } 111 private LinkedHashSet<MonitoringAttributes> allowedChOperations = new LinkedHashSet<>(); 112 { 113 allowedChOperations.addAll(chOperations); 114 allowedChOperations.add(BasicMonitoringAttributes.ADD_RESPONSES); 115 allowedChOperations.add(BasicMonitoringAttributes.BIND_RESPONSES); 116 allowedChOperations.add(BasicMonitoringAttributes.COMPARE_RESPONSES); 117 allowedChOperations.add(BasicMonitoringAttributes.DELETE_RESPONSES); 118 allowedChOperations.add(BasicMonitoringAttributes.EXTENDED_REQUESTS); 119 allowedChOperations.add(BasicMonitoringAttributes.EXTENDED_RESPONSES); 120 allowedChOperations.add(BasicMonitoringAttributes.MOD_DN_RESPONSES); 121 allowedChOperations.add(BasicMonitoringAttributes.MOD_RESPONSES); 122 allowedChOperations.add(BasicMonitoringAttributes.SEARCH_DONE); 123 allowedChOperations.add(BasicMonitoringAttributes.UNBIND_REQUESTS); 124 } 125 126 private LocalizableMessage ALL_CONNECTION_HANDLERS = 127 INFO_CTRL_PANEL_ALL_CONNECTION_HANDLERS.get(); 128 129 /** 130 * Default constructor. 131 * 132 */ 133 public ConnectionHandlerMonitoringPanel() 134 { 135 super(); 136 createLayout(); 137 } 138 139 /** 140 * Creates the layout of the panel (but the contents are not populated here). 141 */ 142 private void createLayout() 143 { 144 GridBagConstraints gbc = new GridBagConstraints(); 145 gbc.gridx = 0; 146 gbc.gridy = 0; 147 gbc.fill = GridBagConstraints.BOTH; 148 gbc.gridwidth = 1; 149 gbc.weightx = 1.0; 150 gbc.anchor = GridBagConstraints.NORTHWEST; 151 addErrorPane(gbc); 152 gbc.weighty = 1.0; 153 JPanel viewOptions = new JPanel(new GridBagLayout()); 154 viewOptions.setBackground(ColorAndFontConstants.greyBackground); 155 viewOptions.setBorder(BorderFactory.createMatteBorder(0, 0, 1, 0, 156 ColorAndFontConstants.defaultBorderColor)); 157 gbc.gridwidth = 1; 158 JLabel l = Utilities.createPrimaryLabel( 159 INFO_CTRL_PANEL_CONNECTION_HANDLERS_LABEL.get()); 160 gbc.gridy = 0; 161 gbc.gridx = 0; 162 gbc.weightx = 0.0; 163 gbc.insets = new Insets(10, 10, 10, 0); 164 viewOptions.add(l, gbc); 165 gbc.insets.left = 5; 166 gbc.insets.right = 10; 167 connectionHandlers = new JComboBox( 168 new DefaultComboBoxModel(new String[]{"fakeconnectionhandlername"})); 169 connectionHandlers.addItemListener( 170 new IgnoreItemListener(connectionHandlers)); 171 connectionHandlers.addItemListener(new ItemListener() 172 { 173 public void itemStateChanged(ItemEvent ev) 174 { 175 if (ev.getStateChange() == ItemEvent.SELECTED) 176 { 177 updateConnectionHandlersPanel( 178 getInfo().getServerDescriptor(), 179 errorPane.isVisible()); 180 } 181 } 182 }); 183 connectionHandlers.setRenderer( 184 new NoLeftInsetCategoryComboBoxRenderer(connectionHandlers)); 185 gbc.gridx ++; 186 viewOptions.add(connectionHandlers, gbc); 187 gbc.gridx ++; 188 gbc.weightx = 1.0; 189 gbc.insets.left = 0; 190 gbc.insets.right = 0; 191 gbc.fill = GridBagConstraints.HORIZONTAL; 192 viewOptions.add(Box.createHorizontalGlue(), gbc); 193 194 gbc.gridy = 1; 195 gbc.gridx = 0; 196 gbc.gridwidth = 1; 197 gbc.insets.left = 0; 198 gbc.weighty = 0.0; 199 gbc.insets = new Insets(0, 0, 0, 0); 200 add(viewOptions, gbc); 201 202 connectionHandlersTableModel = new ConnectionHandlersMonitoringTableModel(); 203 // Add some fake data. 204 String[] names = {"First Connection Handler", "Second Connection Handler", 205 "Third Connection Handler", "Fourth Connection Handler", 206 "Fifth Connection Handler", "Connection Handler with a long name"}; 207 208 Set<ConnectionHandlerDescriptor> fakeData = new HashSet<>(); 209 connectionHandlersTableModel.setAttributes(chOperations, false); 210 try 211 { 212 Set<InetAddress> addresses = new HashSet<>(); 213 addresses.add(InetAddress.getLocalHost()); 214 Set<CustomSearchResult> emptySet = Collections.emptySet(); 215 for (String name : names) 216 { 217 fakeData.add(new ConnectionHandlerDescriptor( 218 addresses, 1389, Protocol.LDAP, State.ENABLED, name, emptySet)); 219 } 220 connectionHandlersTableModel.setData(fakeData, 0); 221 } 222 catch (Throwable t) 223 { 224 // Ignore 225 } 226 connectionHandlersTable = Utilities.createSortableTable( 227 connectionHandlersTableModel, 228 new DefaultTableCellRenderer()); 229 connectionHandlersScroll = Utilities.createScrollPane( 230 connectionHandlersTable); 231 gbc.insets = new Insets(10, 10, 10, 10); 232 gbc.gridy ++; 233 gbc.weighty = 1.0; 234 gbc.fill = GridBagConstraints.BOTH; 235 gbc.weightx = 1.0; 236 gbc.fill = GridBagConstraints.BOTH; 237 add(connectionHandlersScroll, gbc); 238 gbc.fill = GridBagConstraints.VERTICAL; 239 gbc.anchor = GridBagConstraints.CENTER; 240 add(lNoConnectionHandlers, gbc); 241 updateTableSizes(); 242 } 243 244 /** {@inheritDoc} */ 245 @Override 246 public LocalizableMessage getTitle() 247 { 248 return INFO_CTRL_PANEL_CONNECTION_HANDLER_MONITORING_TITLE.get(); 249 } 250 251 /** {@inheritDoc} */ 252 @Override 253 public JMenuBar getMenuBar() 254 { 255 if (menuBar == null) 256 { 257 menuBar = 258 new ConnectionHandlerMonitoringMenuBar(getInfo()); 259 } 260 return menuBar; 261 } 262 263 /** {@inheritDoc} */ 264 public void configurationChanged(ConfigurationChangeEvent ev) 265 { 266 final ServerDescriptor server = ev.getNewDescriptor(); 267 LinkedHashSet<Object> newElements = new LinkedHashSet<>(); 268 269 newElements.add(new CategorizedComboBoxElement(ALL_CONNECTION_HANDLERS, 270 CategorizedComboBoxElement.Type.REGULAR)); 271 Set<ConnectionHandlerDescriptor> chs = server.getConnectionHandlers(); 272 273 SortedSet<ConnectionHandlerDescriptor> sortedChs = 274 new TreeSet<>( 275 new Comparator<ConnectionHandlerDescriptor>() 276 { 277 public int compare(ConnectionHandlerDescriptor desc1, 278 ConnectionHandlerDescriptor desc2) 279 { 280 int compare = 0; 281 if (desc1.getAddresses().equals(desc2.getAddresses())) 282 { 283 Integer port1 = Integer.valueOf(desc1.getPort()); 284 Integer port2 = Integer.valueOf(desc2.getPort()); 285 compare = port1.compareTo(port2); 286 } 287 else 288 { 289 compare = getConnectionHandlerLabel(desc1).compareTo( 290 getConnectionHandlerLabel(desc2)); 291 } 292 return compare; 293 } 294 }); 295 for (ConnectionHandlerDescriptor ch : chs) 296 { 297 if (protocolHasMonitoring(ch)) 298 { 299 sortedChs.add(ch); 300 } 301 } 302 // Add the administration connector 303 sortedChs.add(server.getAdminConnector()); 304 305 newElements.add(COMBO_SEPARATOR); 306 307 for (ConnectionHandlerDescriptor ch : sortedChs) 308 { 309 String connectionHandlerLabel = getConnectionHandlerLabel(ch); 310 newElements.add(new CategorizedComboBoxElement( 311 connectionHandlerLabel, CategorizedComboBoxElement.Type.REGULAR)); 312 } 313 updateComboBoxModel(newElements, 314 (DefaultComboBoxModel)connectionHandlers.getModel()); 315 316 boolean displayErrorPane = false; 317 LocalizableMessage errorTitle = LocalizableMessage.EMPTY; 318 LocalizableMessage errorDetails = LocalizableMessage.EMPTY; 319 ServerDescriptor.ServerStatus status = server.getStatus(); 320 if (status == ServerDescriptor.ServerStatus.STARTED) 321 { 322 if (!server.isAuthenticated()) 323 { 324 LocalizableMessageBuilder mb = new LocalizableMessageBuilder(); 325 mb.append( 326 INFO_CTRL_PANEL_AUTH_REQUIRED_TO_SEE_TRAFFIC_MONITORING_SUMMARY. 327 get()); 328 mb.append("<br><br>").append(getAuthenticateHTML()); 329 errorDetails = mb.toMessage(); 330 errorTitle = INFO_CTRL_PANEL_AUTHENTICATION_REQUIRED_SUMMARY.get(); 331 332 displayErrorPane = true; 333 } 334 } 335 else if (status == ServerDescriptor.ServerStatus.NOT_CONNECTED_TO_REMOTE) 336 { 337 LocalizableMessageBuilder mb = new LocalizableMessageBuilder(); 338 mb.append(INFO_CTRL_PANEL_CANNOT_CONNECT_TO_REMOTE_DETAILS.get( 339 server.getHostname())); 340 mb.append("<br><br>").append(getAuthenticateHTML()); 341 errorDetails = mb.toMessage(); 342 errorTitle = INFO_CTRL_PANEL_CANNOT_CONNECT_TO_REMOTE_SUMMARY.get(); 343 displayErrorPane = true; 344 } 345 else 346 { 347 errorTitle = INFO_CTRL_PANEL_SERVER_NOT_RUNNING_SUMMARY.get(); 348 LocalizableMessageBuilder mb = new LocalizableMessageBuilder(); 349 mb.append( 350 INFO_CTRL_PANEL_SERVER_MUST_RUN_TO_SEE_TRAFFIC_MONITORING_SUMMARY. 351 get()); 352 mb.append("<br><br>"); 353 mb.append(getStartServerHTML()); 354 errorDetails = mb.toMessage(); 355 displayErrorPane = true; 356 } 357 final boolean fDisplayErrorPane = displayErrorPane; 358 final LocalizableMessage fErrorTitle = errorTitle; 359 final LocalizableMessage fErrorDetails = errorDetails; 360 SwingUtilities.invokeLater(new Runnable() 361 { 362 /** {@inheritDoc} */ 363 public void run() 364 { 365 ViewPositions pos = Utilities.getViewPositions( 366 ConnectionHandlerMonitoringPanel.this); 367 errorPane.setVisible(fDisplayErrorPane); 368 if (fDisplayErrorPane) 369 { 370 updateErrorPane(errorPane, fErrorTitle, 371 ColorAndFontConstants.errorTitleFont, fErrorDetails, 372 ColorAndFontConstants.defaultFont); 373 } 374 // TODO: complete update the other table 375 if (!firstRealDataSet) 376 { 377 updateTableSizes(); 378 firstRealDataSet = true; 379 } 380 updateConnectionHandlersPanel(server, fDisplayErrorPane); 381 Utilities.updateViewPositions(pos); 382 } 383 }); 384 } 385 386 /** {@inheritDoc} */ 387 @Override 388 public Component getPreferredFocusComponent() 389 { 390 return connectionHandlers; 391 } 392 393 /** {@inheritDoc} */ 394 @Override 395 public void okClicked() 396 { 397 // No ok button 398 } 399 400 /** {@inheritDoc} */ 401 @Override 402 public GenericDialog.ButtonType getButtonType() 403 { 404 return GenericDialog.ButtonType.CLOSE; 405 } 406 407 408 /** {@inheritDoc} */ 409 @Override 410 public boolean requiresBorder() 411 { 412 return false; 413 } 414 415 /** {@inheritDoc} */ 416 @Override 417 public boolean requiresScroll() 418 { 419 return false; 420 } 421 422 private void setChOperationsToDisplay( 423 LinkedHashSet<MonitoringAttributes> operations, 424 boolean showAverages) 425 { 426 connectionHandlersTableModel.setAttributes(operations, showAverages); 427 connectionHandlersTableModel.forceDataStructureChange(); 428 } 429 430 private String getConnectionHandlerLabel(ConnectionHandlerDescriptor ch) 431 { 432 StringBuilder sb = new StringBuilder(); 433 if (ch.getProtocol() == Protocol.ADMINISTRATION_CONNECTOR) 434 { 435 sb.append(INFO_CTRL_PANEL_ADMINISTRATION_CONNECTOR_NAME.get( 436 ch.getPort())); 437 } 438 else 439 { 440 sb.append(ch.getPort()); 441 sb.append(" - "); 442 switch (ch.getProtocol()) 443 { 444 case OTHER: 445 sb.append(ch.getName()); 446 break; 447 default: 448 sb.append(ch.getProtocol().getDisplayMessage()); 449 break; 450 } 451 } 452 return sb.toString(); 453 } 454 455 /** 456 * Displays a dialog allowing the user to select which operations to display. 457 * 458 */ 459 private void operationViewClicked() 460 { 461 if (operationViewDlg == null) 462 { 463 operationViewPanel = 464 MonitoringAttributesViewPanel.createMonitoringAttributesInstance( 465 allowedChOperations); 466 operationViewDlg = new GenericDialog(Utilities.getFrame(this), 467 operationViewPanel); 468 Utilities.centerGoldenMean(operationViewDlg, 469 Utilities.getParentDialog(this)); 470 operationViewDlg.setModal(true); 471 } 472 operationViewPanel.setSelectedAttributes(chOperations); 473 operationViewDlg.setVisible(true); 474 if (!operationViewPanel.isCanceled()) 475 { 476 boolean showAverages = showAveragesMenu.isSelected(); 477 chOperations = operationViewPanel.getAttributes(); 478 setChOperationsToDisplay(chOperations, showAverages); 479 updateTableSizes(); 480 } 481 } 482 483 /** 484 * Updates the contents of the tables depending on whether the averages 485 * must be displayed or not. 486 * 487 */ 488 private void showAverageClicked() 489 { 490 boolean showAverages = showAveragesMenu.isSelected(); 491 setChOperationsToDisplay(chOperations, showAverages); 492 updateTableSizes(); 493 } 494 495 private void updateTableSizes() 496 { 497 Utilities.updateTableSizes(connectionHandlersTable, 8); 498 Utilities.updateScrollMode(connectionHandlersScroll, 499 connectionHandlersTable); 500 } 501 502 private void updateConnectionHandlersPanel(ServerDescriptor server, 503 boolean errorOccurred) 504 { 505 Set<ConnectionHandlerDescriptor> cch = 506 getFilteredConnectionHandlers(server); 507 connectionHandlersTableModel.setData(cch, server.getRunningTime()); 508 connectionHandlersScroll.setVisible(!cch.isEmpty() && !errorOccurred); 509 lNoConnectionHandlers.setVisible(cch.isEmpty() && !errorOccurred); 510 } 511 512 private Set<ConnectionHandlerDescriptor> getFilteredConnectionHandlers( 513 ServerDescriptor server) 514 { 515 Set<ConnectionHandlerDescriptor> cchs = new HashSet<>(); 516 if (server != null) 517 { 518 Object o = connectionHandlers.getSelectedItem(); 519 if (o instanceof CategorizedComboBoxElement) 520 { 521 Object value = ((CategorizedComboBoxElement)o).getValue(); 522 if (value.equals(ALL_CONNECTION_HANDLERS)) 523 { 524 for (ConnectionHandlerDescriptor ch : server.getConnectionHandlers()) 525 { 526 if (protocolHasMonitoring(ch)) 527 { 528 cchs.add(ch); 529 } 530 } 531 cchs.add(server.getAdminConnector()); 532 } 533 else 534 { 535 String name = value.toString(); 536 for (ConnectionHandlerDescriptor ch : server.getConnectionHandlers()) 537 { 538 if (getConnectionHandlerLabel(ch).equals(name)) 539 { 540 cchs.add(ch); 541 break; 542 } 543 } 544 if (cchs.isEmpty()) 545 { 546 ConnectionHandlerDescriptor adminCh = 547 server.getAdminConnector(); 548 if (getConnectionHandlerLabel(adminCh).equals(name)) 549 { 550 cchs.add(adminCh); 551 } 552 } 553 } 554 } 555 } 556 return cchs; 557 } 558 559 private boolean protocolHasMonitoring(ConnectionHandlerDescriptor ch) 560 { 561 return ch.getState() != State.DISABLED 562 && (ch.getProtocol() == Protocol.LDAP 563 || ch.getProtocol() == Protocol.LDAPS 564 || ch.getProtocol() == Protocol.LDAP_STARTTLS 565 || ch.getProtocol() == Protocol.OTHER); 566 } 567 568 /** 569 * The specific menu bar of this panel. 570 * 571 */ 572 class ConnectionHandlerMonitoringMenuBar extends MainMenuBar 573 { 574 private static final long serialVersionUID = 505187831116443370L; 575 576 /** 577 * Constructor. 578 * @param info the control panel info. 579 */ 580 public ConnectionHandlerMonitoringMenuBar(ControlPanelInfo info) 581 { 582 super(info); 583 } 584 585 /** {@inheritDoc} */ 586 @Override 587 protected void addMenus() 588 { 589 add(createViewMenuBar()); 590 add(createHelpMenuBar()); 591 } 592 593 /** 594 * Creates the view menu bar. 595 * @return the view menu bar. 596 */ 597 @Override 598 protected JMenu createViewMenuBar() 599 { 600 JMenu menu = Utilities.createMenu( 601 INFO_CTRL_PANEL_CONNECTION_HANDLER_VIEW_MENU.get(), 602 INFO_CTRL_PANEL_CONNECTION_HANDLER_VIEW_MENU_DESCRIPTION.get()); 603 menu.setMnemonic(KeyEvent.VK_V); 604 final JMenuItem viewOperations = Utilities.createMenuItem( 605 INFO_CTRL_PANEL_OPERATIONS_VIEW.get()); 606 menu.add(viewOperations); 607 viewOperations.addActionListener(new ActionListener() 608 { 609 public void actionPerformed(ActionEvent ev) 610 { 611 operationViewClicked(); 612 } 613 }); 614 showAveragesMenu = new JCheckBoxMenuItem( 615 INFO_CTRL_PANEL_SHOW_AVERAGES.get().toString()); 616 showAveragesMenu.setSelected(false); 617 menu.add(showAveragesMenu); 618 showAveragesMenu.addActionListener(new ActionListener() 619 { 620 public void actionPerformed(ActionEvent ev) 621 { 622 showAverageClicked(); 623 } 624 }); 625 return menu; 626 } 627 } 628} 629