com.clustercontrol.notify.util.SendSyslog.java Source code

Java tutorial

Introduction

Here is the source code for com.clustercontrol.notify.util.SendSyslog.java

Source

/*
    
Copyright (C) 2006 NTT DATA Corporation
    
This program is free software; you can redistribute it and/or
Modify it under the terms of the GNU General Public License
as published by the Free Software Foundation, version 2.
    
This program is distributed in the hope that it will be
useful, but WITHOUT ANY WARRANTY; without even the implied
warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
PURPOSE.  See the GNU General Public License for more details.
    
 */

package com.clustercontrol.notify.util;

import java.io.IOException;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.net.SocketException;
import java.net.UnknownHostException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
import java.util.Map;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import com.clustercontrol.bean.HinemosModuleConstant;
import com.clustercontrol.bean.PriorityConstant;
import com.clustercontrol.commons.util.JpaTransactionManager;
import com.clustercontrol.fault.NotifyNotFound;
import com.clustercontrol.maintenance.util.HinemosPropertyUtil;
import com.clustercontrol.notify.bean.ExecFacilityConstant;
import com.clustercontrol.notify.bean.NotifyRequestMessage;
import com.clustercontrol.notify.bean.OutputBasicInfo;
import com.clustercontrol.notify.bean.SyslogFacilityConstant;
import com.clustercontrol.notify.bean.SyslogSeverityConstant;
import com.clustercontrol.notify.entity.NotifyLogEscalateInfoData;
import com.clustercontrol.notify.model.NotifyLogEscalateInfo;
import com.clustercontrol.repository.bean.FacilityTreeAttributeConstant;
import com.clustercontrol.repository.model.FacilityInfo;
import com.clustercontrol.repository.model.NodeInfo;
import com.clustercontrol.repository.session.RepositoryControllerBean;
import com.clustercontrol.repository.util.FacilityUtil;
import com.clustercontrol.util.HinemosTime;
import com.clustercontrol.util.MessageConstant;
import com.clustercontrol.util.StringBinder;
import com.clustercontrol.util.apllog.AplLogger;

/**
 * syslog???<BR>
 *
 * @version 3.0.0
 * @since 3.0.0
 */
public class SendSyslog implements Notifier {
    private static final String PROP_HOSTNAME = "notify.log.escalate.manager.hostname";
    private static final String PROP_PROTOCOL = "notify.log.escalate.manager.protocol";
    private static final String PROP_RETRY_COUNT = "notify.log.escalate.manager.retry.count";
    private static final String PROP_RETRY_INTERVAL = "notify.log.escalate.manager.retry.interval";
    private static final String PROP_TCP_TIMEOUT = "notify.log.escalate.manager.tcp.timeout";

    /** ? */
    private static Log m_log = LogFactory.getLog(SendSyslog.class);

    /** Syslog */
    public static final String HEADER_DATE_FORMAT = "MMM dd HH:mm:ss";

    /** Syslog?HOSTNAME */
    private static int MODE_HOSTNAME;
    private static String HOSTNAME_DEFINED = null;
    private static String HOSTNAME_SERVER = "unknownhost";

    private static final int MODE_HOSTNAME_DEFAULT = 0;
    private static final int MODE_HOSTNAME_DEFINED = 1;
    private static final int MODE_HOSTNAME_FACILITYID = 2;
    private static final int MODE_HOSTNAME_NODENAME = 3;

    private static int LIMIT_SIZE = 1024;

    @Override
    public void notify(NotifyRequestMessage requestMessage) throws NotifyNotFound {
        if (m_log.isDebugEnabled()) {
            m_log.debug("notify() " + requestMessage);
        }
        OutputBasicInfo outputInfo = requestMessage.getOutputInfo();
        String notifyId = requestMessage.getNotifyId();

        if (m_log.isDebugEnabled()) {
            m_log.debug("sendlog() " + outputInfo);
        }
        // ??????
        NotifyLogEscalateInfo logEscalateInfo = QueryUtil.getNotifyLogEscalateInfoPK(notifyId);

        NotifyLogEscalateInfoData escalateInfoData = new NotifyLogEscalateInfoData();
        escalateInfoData.setNotifyId(logEscalateInfo.getNotifyId());

        switch (outputInfo.getPriority()) {
        case PriorityConstant.TYPE_INFO:
            escalateInfoData.setValidFlg(logEscalateInfo.getInfoValidFlg());
            escalateInfoData.setEscalateMessage(logEscalateInfo.getInfoEscalateMessage());
            escalateInfoData.setSyslogPriority(logEscalateInfo.getInfoSyslogPriority());
            escalateInfoData.setSyslogFacility(logEscalateInfo.getInfoSyslogFacility());
            break;
        case PriorityConstant.TYPE_WARNING:
            escalateInfoData.setValidFlg(logEscalateInfo.getWarnValidFlg());
            escalateInfoData.setEscalateMessage(logEscalateInfo.getWarnEscalateMessage());
            escalateInfoData.setSyslogPriority(logEscalateInfo.getWarnSyslogPriority());
            escalateInfoData.setSyslogFacility(logEscalateInfo.getWarnSyslogFacility());
            break;
        case PriorityConstant.TYPE_CRITICAL:
            escalateInfoData.setValidFlg(logEscalateInfo.getCriticalValidFlg());
            escalateInfoData.setEscalateMessage(logEscalateInfo.getCriticalEscalateMessage());
            escalateInfoData.setSyslogPriority(logEscalateInfo.getCriticalSyslogPriority());
            escalateInfoData.setSyslogFacility(logEscalateInfo.getCriticalSyslogFacility());
            break;
        case PriorityConstant.TYPE_UNKNOWN:
            escalateInfoData.setValidFlg(logEscalateInfo.getUnknownValidFlg());
            escalateInfoData.setEscalateMessage(logEscalateInfo.getUnknownEscalateMessage());
            escalateInfoData.setSyslogPriority(logEscalateInfo.getUnknownSyslogPriority());
            escalateInfoData.setSyslogFacility(logEscalateInfo.getUnknownSyslogFacility());
            break;
        default:
            break;
        }

        escalateInfoData.setEscalateFacilityFlg(logEscalateInfo.getEscalateFacilityFlg());
        escalateInfoData.setEscalateFacility(logEscalateInfo.getEscalateFacility());
        escalateInfoData.setEscalatePort(logEscalateInfo.getEscalatePort());
        escalateInfoData.setOwnerRoleId(logEscalateInfo.getNotifyInfoEntity().getOwnerRoleId());

        // syslog??
        String message = getMessage(outputInfo, logEscalateInfo);

        /**
         * 
         */
        List<InetAddress> ipAddresses = getIpAddresses(outputInfo, escalateInfoData);
        if (ipAddresses == null) {
            String detailMsg = "IP Address is empty.";
            m_log.info(detailMsg);
            internalErrorNotify(PriorityConstant.TYPE_CRITICAL, notifyId, MessageConstant.MESSAGE_SYS_007_NOTIFY,
                    detailMsg);
        }

        // ?TIMESTAMP?
        SimpleDateFormat sdf = new SimpleDateFormat(HEADER_DATE_FORMAT, Locale.US);
        sdf.setTimeZone(HinemosTime.getTimeZone());
        String headerTimeStamp = sdf.format(HinemosTime.getDateInstance());
        if (m_log.isDebugEnabled()) {
            m_log.debug("sendlog() target message. notifyId = " + escalateInfoData.getNotifyId()
                    + ", headerTimeStamp = " + headerTimeStamp + ", facilityId = " + outputInfo.getFacilityId()
                    + ", message = " + message);
        }

        for (InetAddress address : ipAddresses) {
            try {
                sendMsgWithRetry(address, escalateInfoData.getEscalatePort(),
                        escalateInfoData.getSyslogPriority() + escalateInfoData.getSyslogFacility(),
                        headerTimeStamp, getSyslogHeaderHost(outputInfo.getFacilityId()), message);
            } catch (IOException e) {
                String detailMsg = e.getMessage() + " IP Address = " + address;
                m_log.info("sendlog() " + detailMsg + " : " + e.getClass().getSimpleName() + ", " + e.getMessage());
                internalErrorNotify(PriorityConstant.TYPE_CRITICAL, notifyId,
                        MessageConstant.MESSAGE_SYS_007_NOTIFY, detailMsg);
                // ???IP??
            }
        }
    }

    /**
     * ???syslog?????
     * NotifyLogEscalateInfoData ? EscalateFacilityFlg ?ExecFacilityConstant.TYPE_GENERATION??
     * ?????outputInfo?null??????????
     *
     * @param outputInfo 
     * @param logEscalateInfo 
     * @return ??IP
     */
    private List<InetAddress> getIpAddresses(OutputBasicInfo outputInfo,
            NotifyLogEscalateInfoData logEscalateInfo) {

        // ?
        ArrayList<InetAddress> ipAddresses = new ArrayList<InetAddress>();
        //?(RepositoryControllerLocal)?
        try {
            String facilityId = null;

            // 
            if (logEscalateInfo.getEscalateFacilityFlg() == ExecFacilityConstant.TYPE_FIX) {
                // ??????ID?????
                facilityId = logEscalateInfo.getEscalateFacility();
            } else {
                // ???
                if (outputInfo == null) {
                    // NotifyLogEscalateInfoData ? EscalateFacilityFlg ?ExecFacilityConstant.TYPE_GENERATION??
                    // ?????outputInfo?null??????????
                    return ipAddresses;
                } else {
                    facilityId = outputInfo.getFacilityId();
                }
            }

            ArrayList<String> facilityIdList = new RepositoryControllerBean()
                    .getExecTargetFacilityIdList(facilityId, logEscalateInfo.getOwnerRoleId());

            for (String targetFacilityId : facilityIdList) {
                FacilityInfo facility = new RepositoryControllerBean().getFacilityEntityByPK(targetFacilityId);
                try {
                    ipAddresses.add(getInetAdress(facility));
                } catch (UnknownHostException e) {
                    m_log.info("getIpAddresses() : " + e.getClass().getSimpleName() + ", " + e.getMessage());
                    // ?????
                }
            }

            return ipAddresses;
        } catch (Exception e) {
            m_log.warn("getIpAddresses() : " + e.getClass().getSimpleName() + ", " + e.getMessage(), e);
            // ????????
            return null;
        }
    }

    // ??
    private String getMessage(OutputBasicInfo outputInfo, NotifyLogEscalateInfo logEscalateInfo) {
        // ??
        String message = "";
        switch (outputInfo.getPriority()) {
        case PriorityConstant.TYPE_INFO:
            message = logEscalateInfo.getInfoEscalateMessage();
            break;
        case PriorityConstant.TYPE_WARNING:
            message = logEscalateInfo.getWarnEscalateMessage();
            break;
        case PriorityConstant.TYPE_CRITICAL:
            message = logEscalateInfo.getCriticalEscalateMessage();
            break;
        case PriorityConstant.TYPE_UNKNOWN:
            message = logEscalateInfo.getUnknownEscalateMessage();
            break;
        default:
            break;
        }

        try {
            Map<String, String> param = NotifyUtil.createParameter(outputInfo,
                    logEscalateInfo.getNotifyInfoEntity());
            StringBinder binder = new StringBinder(param);

            return binder.bindParam(message);
        } catch (Exception e) {
            m_log.warn("getMessage() : " + e.getClass().getSimpleName() + ", " + e.getMessage(), e);
            // ??????????
            return message;
        }
    }

    private InetAddress getInetAdress(FacilityInfo facility) throws UnknownHostException {
        if (!(facility instanceof NodeInfo))
            return InetAddress.getByName(null);

        NodeInfo node = (NodeInfo) facility;

        InetAddress ret = null;

        // IP??
        int version;
        if (node.getIpAddressVersion() != null) {
            version = ((NodeInfo) facility).getIpAddressVersion();
        } else {
            version = 4;
        }
        // ???????IP??
        if (version == 4) {
            ret = InetAddress.getByName(node.getIpAddressV4());
        } else {
            ret = InetAddress.getByName(node.getIpAddressV6());
        }

        return ret;
    }

    /**
     * syslog??(ShelfCheckTask?AplLogger)
     * ?????????syslog??<br>
     *
     * @param ipAddress
     * @param port
     * @param facility
     * @param severity
     * @param facilityId
     * @param message
     * @param timeStamp
     */
    public void sendAfterConvertHostname(String ipAddress, int port, String facility, String severity,
            String facilityId, String message, String timeStamp) {
        // 
        String hostname = "";

        // ?
        hostname = getSyslogHeaderHost(facilityId);
        InetAddress inetAddress = null;

        int facilityInt = -1;
        int severityInt = -1;
        int priority = -1;

        // ?
        try {
            // generate InetAddress
            inetAddress = InetAddress.getByName(ipAddress);

            // generate priority of header
            facilityInt = SyslogFacilityConstant.stringToType(facility);
            severityInt = SyslogSeverityConstant.stringToType(severity);
            if (facilityInt == -1 || severityInt == -1) {
                m_log.info("send() sending syslog failure. facility(" + facility + ") or severity(" + severity
                        + ") is invalid.");
                return;
            }
            priority = facilityInt + severityInt;

            sendMsgWithRetry(inetAddress, port, priority, timeStamp, hostname, message);

        } catch (UnknownHostException e) {
            m_log.info("sending syslog failure. syslog's host(" + ipAddress + ") is invalid."
                    + e.getClass().getSimpleName() + ", " + e.getMessage());
        } catch (SocketException e) {
            m_log.info("sending syslog failure." + e.getClass().getSimpleName() + ", " + e.getMessage());
        } catch (IOException e) {
            m_log.info("sending syslog failure." + e.getClass().getSimpleName() + ", " + e.getMessage());
        }
    }

    /**
     * ????syslog?????????
     * @param facilityId ?ID
     * @return
     */
    private static String getSyslogHeaderHost(String facilityId) {
        JpaTransactionManager jtm = null;
        // 
        String hostname = HinemosPropertyUtil.getHinemosPropertyStr(PROP_HOSTNAME, null);

        if (hostname == null) {
            // undef hostname of syglog header
            MODE_HOSTNAME = MODE_HOSTNAME_DEFAULT;
        } else if ("".equals(hostname)) {
            // invalid hostname of syslog header
            MODE_HOSTNAME = MODE_HOSTNAME_DEFAULT;
        } else if ("#[FACILITY_ID]".equals(hostname)) {
            // use facility_id as hostname of syslog header
            MODE_HOSTNAME = MODE_HOSTNAME_FACILITYID;
        } else if ("#[NODE]".equals(hostname)) {
            // use nodename as hostname of syslog header
            MODE_HOSTNAME = MODE_HOSTNAME_NODENAME;
        } else {
            MODE_HOSTNAME = MODE_HOSTNAME_DEFINED;
            HOSTNAME_DEFINED = hostname;
        }
        try {
            HOSTNAME_SERVER = InetAddress.getLocalHost().getHostName();
        } catch (Exception e) {
            m_log.warn("static() : " + e.getClass().getSimpleName() + ", " + e.getMessage(), e);
        }

        m_log.debug("syslog sender. (mode = " + MODE_HOSTNAME + ", hostname=" + HOSTNAME_DEFINED + ")");

        int mode = MODE_HOSTNAME;
        boolean isBuildinScope = false;

        // ?
        if (m_log.isDebugEnabled())
            m_log.debug("converting syslog hostname for '" + facilityId + "'. (mode = " + MODE_HOSTNAME + ")");

        if (FacilityTreeAttributeConstant.isBuiltinScope(facilityId)) {
            // ???????????
            if (m_log.isDebugEnabled())
                m_log.debug("facility '" + facilityId + "' is buildin scope.");
            isBuildinScope = true;
        }

        switch (mode) {
        case MODE_HOSTNAME_DEFINED:
            hostname = HOSTNAME_DEFINED;
            break;
        case MODE_HOSTNAME_FACILITYID:
            hostname = isBuildinScope ? HOSTNAME_SERVER : facilityId;
            break;
        case MODE_HOSTNAME_NODENAME:
            try {
                jtm = new JpaTransactionManager();
                jtm.begin();

                FacilityInfo facility = new RepositoryControllerBean().getFacilityEntityByPK(facilityId);
                if (FacilityUtil.isNode(facility)) {
                    hostname = isBuildinScope ? HOSTNAME_SERVER
                            : (facility instanceof NodeInfo ? ((NodeInfo) facility).getNodeName() : null);
                } else {
                    if (m_log.isDebugEnabled())
                        m_log.debug("facility '" + facilityId + "' is not node.");
                    hostname = HOSTNAME_SERVER;
                }
                jtm.commit();
            } catch (Exception e) {
                hostname = HOSTNAME_SERVER;
                m_log.warn("getSyslogHeaderHost() use '" + hostname
                        + "' for hostname of syslog header. (facility not found : " + facilityId + ") : "
                        + e.getClass().getSimpleName() + ", " + e.getMessage(), e);
                if (jtm != null)
                    jtm.rollback();
            } finally {
                if (jtm != null)
                    jtm.close();
            }
            break;
        default:
            hostname = HOSTNAME_SERVER;
        }

        if (m_log.isDebugEnabled())
            m_log.debug("use syslog hostname '" + hostname + "' for '" + facilityId + "'.");
        return hostname;
    }

    private void sendMsgWithRetry(InetAddress ipAddress, int port, int syslogPriority, String headerTimestamp,
            String hostname, String message) throws IOException {

        String protocol = HinemosPropertyUtil.getHinemosPropertyStr(PROP_PROTOCOL, "udp");

        String sendMessage = "<" + syslogPriority + ">" + headerTimestamp + " " + hostname + " " + message;

        // 1024?????1024??????????
        if (sendMessage.getBytes().length > LIMIT_SIZE) {
            byte[] buf = sendMessage.getBytes();
            sendMessage = new String(buf, 0, LIMIT_SIZE);
        }

        m_log.debug("sendMsgWithRetry. (ipAddresss=" + ipAddress + ", port=" + port + ", sendMessage=" + sendMessage
                + ")");

        int retryCount = HinemosPropertyUtil.getHinemosPropertyNum(PROP_RETRY_COUNT, Long.valueOf(1)).intValue();
        int retryInterval = HinemosPropertyUtil.getHinemosPropertyNum(PROP_RETRY_INTERVAL, Long.valueOf(10000))
                .intValue();
        IOException lastException = null;
        int retrytime;
        for (retrytime = 0; retrytime < retryCount; retrytime++) {
            try {
                if ("udp".equals(protocol)) {
                    sendUdpMsg(ipAddress, port, sendMessage);
                } else {
                    sendTcpMsg(ipAddress, port, sendMessage);
                }

                break;
            } catch (IOException e) {
                m_log.warn("sendMsgWithRetry() : " + e.getClass().getSimpleName() + ", retried time="
                        + (retrytime + 1) + ", protocol=" + protocol + ", message=" + e.getMessage());

                lastException = e;

                try {
                    Thread.sleep(retryInterval);
                } catch (InterruptedException e1) {
                }
            }
        }

        if (retrytime == retryCount && lastException != null) {
            throw lastException;
        }
    }

    private void sendTcpMsg(InetAddress ipAddress, int port, String msg) throws IOException {

        Socket socket = null;
        OutputStream os = null;
        PrintWriter writer = null;
        try {
            InetSocketAddress endpoint = new InetSocketAddress(ipAddress, port);
            socket = new Socket();
            socket.connect(endpoint,
                    HinemosPropertyUtil.getHinemosPropertyNum(PROP_TCP_TIMEOUT, Long.valueOf(3000)).intValue());

            os = socket.getOutputStream();
            writer = new PrintWriter(socket.getOutputStream(), true);
            writer.println(msg);
            writer.flush();
        } finally {
            if (writer != null) {
                writer.close();
            }
            if (os != null) {
                os.close();
            }
            if (socket != null) {
                socket.close();
            }
        }
    }

    private void sendUdpMsg(InetAddress ipAddress, int port, String msg) throws IOException {
        DatagramSocket soc = null;
        try {
            // ??????
            soc = new DatagramSocket(); // ??
            DatagramPacket sendPacket = null; // 

            sendPacket = new DatagramPacket(msg.getBytes(), msg.getBytes().length, ipAddress, port);
            soc.send(sendPacket);
        } finally {
            if (soc != null) {
                soc.close();
            }
        }
    }

    /**
     * ????
     */
    @Override
    public void internalErrorNotify(int priority, String notifyId, MessageConstant msgCode, String detailMsg) {
        String[] args = { notifyId };
        // 
        AplLogger.put(priority, HinemosModuleConstant.PLATFORM_NOTIFY, msgCode, args, detailMsg);
    }
}