/* * Autopsy Forensic Browser * * Copyright 2018-2021 Basis Technology Corp. * Contact: carrier sleuthkit org * * 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.sleuthkit.autopsy.experimental.autoingest; import com.google.common.util.concurrent.ThreadFactoryBuilder; import java.awt.Cursor; import java.awt.EventQueue; import java.awt.GridBagConstraints; import java.awt.Insets; import java.util.Observable; import java.util.Observer; import java.util.concurrent.ScheduledThreadPoolExecutor; import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicBoolean; import org.sleuthkit.autopsy.healthmonitor.HealthMonitorDashboard; /** * A dashboard for monitoring the existing AutoIngestNodes and their status. */ @SuppressWarnings("PMD.SingularField") // UI widgets cause lots of false positives final class AinStatusDashboard extends javax.swing.JPanel implements Observer { private static final long serialVersionUID = 1L; private final AutoIngestMonitor autoIngestMonitor; private final AinStatusPanel nodesPanel; private final static String AIN_REFRESH_THREAD_NAME = "AID-refresh-jobs-%d"; private final static int AIN_REFRESH_INTERVAL_SECS = 30; private final static int AIN_DELAY_BEFORE_FIRST_REFRESH = 0; private final ScheduledThreadPoolExecutor scheduledRefreshThreadPoolExecutor; private AtomicBoolean scheduledRefreshStarted = new AtomicBoolean(false); /** * Creates new form AutoIngestNodeStatus */ AinStatusDashboard(AutoIngestMonitor monitor) { initComponents(); scheduledRefreshThreadPoolExecutor = new ScheduledThreadPoolExecutor(1, new ThreadFactoryBuilder().setNameFormat(AIN_REFRESH_THREAD_NAME).build()); autoIngestMonitor = monitor; nodesPanel = new AinStatusPanel(); GridBagConstraints gridBagConstraints = new java.awt.GridBagConstraints(); gridBagConstraints.gridx = 0; gridBagConstraints.gridy = 1; gridBagConstraints.fill = GridBagConstraints.BOTH; gridBagConstraints.weightx = 1; gridBagConstraints.weighty = 1; gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST; gridBagConstraints.insets = new Insets(0, 10, 0, 10); mainPanel.add(nodesPanel, gridBagConstraints); refreshTables(); } /** * Adds this panel as an observer of AutoIngestMonitor. */ void startUp() { autoIngestMonitor.addObserver(this); } AutoIngestMonitor getMonitor() { return autoIngestMonitor; } AinStatusPanel getNodesStatusPanel() { return nodesPanel; } /** * This method is called from within the constructor to initialize the form. * WARNING: Do NOT modify this code. The content of this method is always * regenerated by the Form Editor. */ @SuppressWarnings("unchecked") // //GEN-BEGIN:initComponents private void initComponents() { java.awt.GridBagConstraints gridBagConstraints; javax.swing.JScrollPane mainScrollPane = new javax.swing.JScrollPane(); mainPanel = new javax.swing.JPanel(); nodeStatusTableTitle = new javax.swing.JLabel(); buttonPanel = new javax.swing.JPanel(); refreshButton = new javax.swing.JButton(); clusterMetricsButton = new javax.swing.JButton(); healthMonitorButton = new javax.swing.JButton(); filler1 = new javax.swing.Box.Filler(new java.awt.Dimension(0, 0), new java.awt.Dimension(0, 0), new java.awt.Dimension(32767, 0)); setLayout(new java.awt.BorderLayout()); mainPanel.setLayout(new java.awt.GridBagLayout()); nodeStatusTableTitle.setFont(nodeStatusTableTitle.getFont().deriveFont(nodeStatusTableTitle.getFont().getSize()+3f)); org.openide.awt.Mnemonics.setLocalizedText(nodeStatusTableTitle, org.openide.util.NbBundle.getMessage(AinStatusDashboard.class, "AinStatusDashboard.nodeStatusTableTitle.text")); // NOI18N gridBagConstraints = new java.awt.GridBagConstraints(); gridBagConstraints.gridx = 0; gridBagConstraints.gridy = 0; gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL; gridBagConstraints.insets = new java.awt.Insets(10, 10, 5, 10); mainPanel.add(nodeStatusTableTitle, gridBagConstraints); buttonPanel.setLayout(new java.awt.GridBagLayout()); org.openide.awt.Mnemonics.setLocalizedText(refreshButton, org.openide.util.NbBundle.getMessage(AinStatusDashboard.class, "AinStatusDashboard.refreshButton.text")); // NOI18N refreshButton.setToolTipText(org.openide.util.NbBundle.getMessage(AinStatusDashboard.class, "AinStatusDashboard.refreshButton.toolTipText")); // NOI18N refreshButton.setPreferredSize(new java.awt.Dimension(133, 23)); refreshButton.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { refreshButtonActionPerformed(evt); } }); gridBagConstraints = new java.awt.GridBagConstraints(); gridBagConstraints.gridx = 0; gridBagConstraints.gridy = 0; gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST; buttonPanel.add(refreshButton, gridBagConstraints); org.openide.awt.Mnemonics.setLocalizedText(clusterMetricsButton, org.openide.util.NbBundle.getMessage(AinStatusDashboard.class, "AinStatusDashboard.clusterMetricsButton.text")); // NOI18N clusterMetricsButton.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { clusterMetricsButtonActionPerformed(evt); } }); gridBagConstraints = new java.awt.GridBagConstraints(); gridBagConstraints.gridx = 3; gridBagConstraints.gridy = 0; gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST; buttonPanel.add(clusterMetricsButton, gridBagConstraints); org.openide.awt.Mnemonics.setLocalizedText(healthMonitorButton, org.openide.util.NbBundle.getMessage(AinStatusDashboard.class, "AinStatusDashboard.healthMonitorButton.text")); // NOI18N healthMonitorButton.setPreferredSize(new java.awt.Dimension(133, 23)); healthMonitorButton.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { healthMonitorButtonActionPerformed(evt); } }); gridBagConstraints = new java.awt.GridBagConstraints(); gridBagConstraints.gridx = 2; gridBagConstraints.gridy = 0; gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST; buttonPanel.add(healthMonitorButton, gridBagConstraints); gridBagConstraints = new java.awt.GridBagConstraints(); gridBagConstraints.gridx = 1; gridBagConstraints.gridy = 0; gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL; gridBagConstraints.weightx = 1.0; buttonPanel.add(filler1, gridBagConstraints); gridBagConstraints = new java.awt.GridBagConstraints(); gridBagConstraints.gridx = 0; gridBagConstraints.gridy = 2; gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL; gridBagConstraints.weightx = 1.0; gridBagConstraints.insets = new java.awt.Insets(10, 10, 10, 10); mainPanel.add(buttonPanel, gridBagConstraints); mainScrollPane.setViewportView(mainPanel); add(mainScrollPane, java.awt.BorderLayout.CENTER); }// //GEN-END:initComponents private void refreshButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_refreshButtonActionPerformed setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR)); refreshTables(); setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR)); }//GEN-LAST:event_refreshButtonActionPerformed private void refreshTables() { nodesPanel.refresh(autoIngestMonitor); } private void clusterMetricsButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_clusterMetricsButtonActionPerformed new AutoIngestMetricsDialog(this.getTopLevelAncestor()); }//GEN-LAST:event_clusterMetricsButtonActionPerformed private void healthMonitorButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_healthMonitorButtonActionPerformed new HealthMonitorDashboard(this.getTopLevelAncestor()).display(); }//GEN-LAST:event_healthMonitorButtonActionPerformed // Variables declaration - do not modify//GEN-BEGIN:variables private javax.swing.JPanel buttonPanel; private javax.swing.JButton clusterMetricsButton; private javax.swing.Box.Filler filler1; private javax.swing.JButton healthMonitorButton; private javax.swing.JPanel mainPanel; private javax.swing.JLabel nodeStatusTableTitle; private javax.swing.JButton refreshButton; // End of variables declaration//GEN-END:variables @Override public void update(Observable o, Object arg) { if (!scheduledRefreshStarted.getAndSet(true)) { scheduledRefreshThreadPoolExecutor.scheduleWithFixedDelay(() -> { EventQueue.invokeLater(() -> { refreshTables(); }); }, AIN_DELAY_BEFORE_FIRST_REFRESH, AIN_REFRESH_INTERVAL_SECS, TimeUnit.SECONDS); } } }