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