385N/A/*
385N/A * CDDL HEADER START
385N/A *
385N/A * The contents of this file are subject to the terms of the
385N/A * Common Development and Distribution License (the "License").
385N/A * You may not use this file except in compliance with the License.
385N/A *
385N/A * See LICENSE.txt included in this distribution for the specific
385N/A * language governing permissions and limitations under the License.
385N/A *
385N/A * When distributing Covered Code, include this CDDL HEADER in each
385N/A * file and include the License file at LICENSE.txt.
385N/A * If applicable, add the following below this CDDL HEADER, with the
385N/A * fields enclosed by brackets "[]" replaced with your own identifying
385N/A * information: Portions Copyright [yyyy] [name of copyright owner]
385N/A *
385N/A * CDDL HEADER END
385N/A */
407N/A
1043N/A/*
1043N/A * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
1043N/A */
1043N/A
385N/Apackage org.opensolaris.opengrok.management.client;
385N/A
385N/Aimport java.awt.event.ActionEvent;
385N/Aimport java.awt.event.ActionListener;
385N/Aimport java.io.IOException;
385N/Aimport java.net.MalformedURLException;
385N/Aimport java.util.HashMap;
385N/Aimport java.util.logging.Level;
385N/Aimport java.util.logging.Logger;
385N/Aimport javax.management.InstanceNotFoundException;
385N/Aimport javax.management.MBeanServerConnection;
385N/Aimport javax.management.MalformedObjectNameException;
385N/Aimport javax.management.Notification;
385N/Aimport javax.management.NotificationListener;
385N/Aimport javax.management.ObjectName;
385N/Aimport javax.management.remote.JMXConnector;
385N/Aimport javax.management.remote.JMXConnectorFactory;
385N/Aimport javax.management.remote.JMXServiceURL;
385N/A
385N/A/**
385N/A * Class to handle the connection and methods to the OpenGrok Agent
385N/A * @author Jan S Berg
385N/A */
385N/Apublic class AgentConnection implements NotificationListener {
385N/A
385N/A private MBeanServerConnection server = null;
456N/A private final ObjectName objName;
457N/A private static final String objStrName = "OGA:name=AgentIndexRunner,source=timer";
421N/A private static final Logger logger = Logger.getLogger("org.opensolaris.opengrok");
385N/A private String agenturl = "";
460N/A private JMXConnector jmxconn = null;
385N/A private boolean connected = false;
385N/A private ActionListener actionListener = null;
385N/A private boolean listenerRegistered = false;
1238N/A private static final long RECONNECT_SLEEPTIME = 5000;
1238N/A public static final String JAVA_LANG_STRING = "java.lang.String";
1238N/A public static final String JAVA_LANG_OBJECT = "java.lang.Object";
385N/A private StringBuilder filesInfo = new StringBuilder();
385N/A /** MAX size of the filesInfo buffer */
1238N/A private static final int FILESINFOMAX = 50000;
385N/A private long starttime = 0;
385N/A private long endtime = 0;
385N/A
385N/A /**
385N/A * Constructor for AgentConnection to OpenGrok JMX Agent
1043N/A * @param url The JMX url for the agent to connect to
385N/A * @throws java.net.MalformedURLException if url is not in correct format
385N/A * @throws java.io.IOException if a connection error occurs
385N/A * @throws javax.management.MalformedObjectNameException if the JMX object name is not correct
385N/A */
385N/A public AgentConnection(String url) throws MalformedURLException, IOException, MalformedObjectNameException {
385N/A agenturl = url;
385N/A objName = new ObjectName(objStrName);
385N/A }
385N/A
385N/A public MBeanServerConnection getMBeanServerConnection() {
653N/A if (!isConnected()) {
653N/A try {
653N/A reconnect(1);
653N/A } catch (IOException ex) {
653N/A Logger.getLogger(AgentConnection.class.getName()).log(Level.SEVERE, null, ex);
653N/A }
653N/A }
385N/A return server;
385N/A }
385N/A
385N/A public String getAgentURL() {
385N/A return agenturl;
385N/A }
385N/A
385N/A public void setActionListener(ActionListener listener) {
385N/A actionListener = listener;
385N/A }
385N/A
385N/A public String getFilesInfo() {
385N/A return filesInfo.toString();
385N/A }
385N/A
385N/A public void clearFilesInfo() {
385N/A filesInfo = new StringBuilder();
385N/A }
385N/A
385N/A public long getStartTime() {
385N/A return starttime;
385N/A }
385N/A
385N/A public long getEndTime() {
385N/A return endtime;
385N/A }
385N/A
385N/A void setUrl(String property) {
385N/A agenturl = property;
385N/A }
385N/A
1190N/A public void handleNotification(Notification notification, java.lang.Object handback) {
585N/A StringBuilder sb = new StringBuilder();
585N/A sb.append("Notification type: '");
585N/A sb.append(notification.getType());
585N/A sb.append("', seq nr: '");
585N/A sb.append(notification.getSequenceNumber());
585N/A sb.append("', message: '");
585N/A sb.append(notification.getMessage());
585N/A sb.append("', user data: '");
585N/A sb.append(notification.getUserData());
585N/A sb.append("'");
585N/A
585N/A String notif = "Notification: '" + notification + "'";
585N/A String source = "Notification: source: '" + notification.getSource() + "'";
1190N/A
1190N/A
385N/A if (notification.getType().equals("ogaaction")) {
385N/A if (handback instanceof String) {
585N/A logger.fine(sb.toString());
585N/A logger.finest(notif);
585N/A logger.finest(source);
385N/A } else if (handback instanceof ObjectName) {
588N/A handleObjectName(sb, notification, handback);
385N/A }
385N/A } else if (notification.getType().equals("ogainfostring")) {
385N/A if (handback instanceof String) {
585N/A logger.finest(sb.toString());
585N/A logger.finest(notif);
585N/A logger.finest(source);
385N/A } else if (handback instanceof ObjectName) {
385N/A ObjectName pingBean = (ObjectName) handback;
585N/A logger.finest("Received notification from '" + pingBean + "' " + sb.toString());
385N/A }
385N/A } else if (notification.getType().equals("ogainfolong")) {
385N/A if (handback instanceof String) {
585N/A logger.finest(sb.toString());
585N/A logger.finest(notif);
585N/A logger.finest(source);
385N/A } else if (handback instanceof ObjectName) {
385N/A ObjectName pingBean = (ObjectName) handback;
585N/A logger.info("Received notification from '" + pingBean + "' " + sb.toString());
385N/A if ("StartIndexing".equals(notification.getMessage())) {
385N/A starttime = ((Long) notification.getUserData()).longValue();
385N/A } else if ("FinishedIndexing".equals(notification.getMessage())) {
385N/A endtime = ((Long) notification.getUserData()).longValue();
385N/A } else {
385N/A logger.warning("Unknown message " + notification.getMessage());
385N/A }
385N/A }
385N/A } else {
585N/A logger.info(sb.toString());
585N/A logger.finest(notif);
585N/A logger.finest(source);
385N/A }
385N/A }
385N/A
588N/A private void handleObjectName(StringBuilder sb, Notification notification, Object handback) {
588N/A ObjectName pingBean = (ObjectName) handback;
588N/A logger.fine("Received notification from '" + pingBean + "' " + sb.toString());
588N/A if (filesInfo.length() < FILESINFOMAX) {
588N/A //filesInfo.append(notification.getMessage());
588N/A filesInfo.append(notification.getUserData().toString());
588N/A if (actionListener != null) {
588N/A actionListener.actionPerformed(new ActionEvent(this, ActionEvent.ACTION_PERFORMED, "OpenGrok fileevent"));
588N/A }
588N/A }
588N/A }
588N/A
385N/A public void registerListener() throws IOException,
385N/A InstanceNotFoundException {
385N/A logger.fine("Registering listener: " + this.getClass().getName() + " for ObjectName: " + objName);
385N/A server.addNotificationListener(objName, this, null, objName);
385N/A logger.fine("Listener Registered");
385N/A listenerRegistered = true;
385N/A }
385N/A
385N/A public void reconnect(int retrytimes) throws MalformedURLException, IOException {
385N/A logger.fine("Doing reconnect on '" + agenturl + "'");
385N/A boolean notconnected = true;
385N/A int triednumtimes = 0;
385N/A while (notconnected) {
385N/A triednumtimes++;
385N/A if (jmxconn != null) {
385N/A try {
385N/A jmxconn.close();
385N/A } catch (Exception ex) {
385N/A logger.warning("Exception during close " + ex);
385N/A }
385N/A }
385N/A try {
1190N/A connect();
385N/A notconnected = false;
385N/A } catch (MalformedURLException ex) {
385N/A logger.log(Level.SEVERE, null, ex);
385N/A throw ex;
385N/A } catch (IOException ex) {
385N/A logger.log(Level.SEVERE, null, ex);
385N/A
385N/A notconnected = true;
385N/A
385N/A if (triednumtimes <= retrytimes) {
385N/A logger.info("retry connect did try " + triednumtimes + ", retrying " +
385N/A retrytimes + " times, waiting " + RECONNECT_SLEEPTIME + " before" +
385N/A " next try.");
385N/A try {
385N/A Thread.sleep(RECONNECT_SLEEPTIME);
385N/A } catch (Exception sleepex) {
385N/A logger.finest("Thread.sleep exception " + sleepex);
385N/A }
385N/A
385N/A } else {
385N/A throw ex;
385N/A }
385N/A }
385N/A
385N/A }
385N/A }
385N/A
385N/A protected void connect() throws MalformedURLException, IOException {
1043N/A JMXServiceURL url = new JMXServiceURL(agenturl);
385N/A logger.info("jmx url " + url);
385N/A HashMap<String, Object> env = new HashMap<String, Object>();
385N/A jmxconn = JMXConnectorFactory.connect(url, env);
385N/A logger.finer("jmx connect ok");
385N/A server = jmxconn.getMBeanServerConnection();
385N/A logger.info("JMX connection ok");
385N/A connected = true;
385N/A }
385N/A
385N/A public boolean isConnected() {
385N/A return connected;
385N/A }
385N/A
385N/A public void unregister() {
385N/A if ((server != null) && (objName != null) && listenerRegistered) {
385N/A try {
385N/A logger.fine("Unregistering listener: " + this.getClass().getName() + " for ObjectName: " + objName);
385N/A server.removeNotificationListener(objName, this, null, objName);
385N/A listenerRegistered = false;
385N/A } catch (Exception remnlex) {
385N/A logger.severe("Exception unregister notif listener: '" + this.getClass().getName() + "' for ObjectName: " + objName + "'");
385N/A }
385N/A }
385N/A
385N/A try {
385N/A
385N/A if (jmxconn != null) {
385N/A logger.fine("Closing connection");
385N/A jmxconn.close();
385N/A jmxconn = null;
385N/A server = null;
385N/A }
385N/A } catch (Exception e) {
385N/A logger.log(Level.SEVERE, "Exception disconnecting " + e.getMessage(), e);
385N/A }
385N/A
385N/A }
385N/A}
385N/A