// Path: src/main/java/com/yiji/falcon/agent/exception/AgentArgumentException.java
// public class AgentArgumentException extends Exception {
// 
//     private String err;
// 
//     /**
//      * Constructs a new exception with the specified detail message.  The
//      * cause is not initialized, and may subsequently be initialized by
//      * a call to {@link #initCause}.
//      *
//      * @param err the detail message. The detail message is saved for
//      *            later retrieval by the {@link #getMessage()} method.
//      */
//     public AgentArgumentException(String err) {
//         super(err);
//         this.err = err;
//     }
// 
//     public String getErr() {
//         return err;
//     }
// 
// }
// 
// Path: src/main/java/com/yiji/falcon/agent/util/StringUtils.java
// public class StringUtils {
// 
//     /**
//      * 判断传入的String是否为空('' or null)
//      * @param str
//      * @return
//      */
//     public static boolean isEmpty(String str){
//         return str == null || str.length() == 0;
//     }
// 
//     /**
//      * 返回指定数字的字符串形式
//      * @param value
//      * @return
//      */
//     public static String getStringByInt(int value){
//         return String.valueOf(value).intern();
//     }
// 
// }
// 
// Path: src/main/java/com/yiji/falcon/agent/vo/snmp/SNMPV3UserInfo.java
// @Data
// public class SNMPV3UserInfo {
// 
//     /**
//      * 网络协议 如udp、tcp
//      */
//     private String protocol = "udp";
//     /**
//      * 网络设备的IP地址
//      */
//     private String address = "";
//     /**
//      * 网络设备的连接端口号
//      */
//     private String port = "161";
//     /**
//      * 用户名
//      */
//     private String username = "";
//     /**
//      * 认证算法,如 none,MD5,SHA
//      */
//     private String aythType = "";
//     /**
//      * 认证密码
//      */
//     private String authPswd = "";
//     /**
//      * 加密算法,如 none,DES,3DES,AES128,AES,AES192,AES256
//      */
//     private String privType = "";
//     /**
//      * 加密密码
//      */
//     private String privPswd = "";
//     /**
//      * endPoint
//      */
//     private String endPoint = "";
// 
//     /**
//      * 允许采集哪些名称的接口数据
//      * 注：只采集集合中的接口名称的数据。若为空，则不会采集接口数据
//      */
//     private List<String> ifCollectNameEnables;
// 
// }


import com.yiji.falcon.agent.exception.AgentArgumentException;
import com.yiji.falcon.agent.util.StringUtils;
import com.yiji.falcon.agent.vo.snmp.SNMPV3UserInfo;
import lombok.extern.slf4j.Slf4j;
import org.snmp4j.PDU;
import org.snmp4j.Snmp;
import org.snmp4j.UserTarget;
import org.snmp4j.mp.MPv3;
import org.snmp4j.mp.SnmpConstants;
import org.snmp4j.security.*;
import org.snmp4j.smi.GenericAddress;
import org.snmp4j.smi.OID;
import org.snmp4j.smi.OctetString;
import org.snmp4j.transport.DefaultUdpTransportMapping;
import java.io.IOException;
import java.util.List;
import java.util.concurrent.ConcurrentHashMap;
/*
 * www.yiji.com Inc.
 * Copyright (c) 2016 All Rights Reserved
 */
package com.yiji.falcon.agent.plugins.util;
/*
 * 修订记录:
 * guqiu@yiji.com 2016-07-12 10:47 创建
 */



/**
 * @author guqiu@yiji.com
 */
@Slf4j
public class SNMPV3Session {

//    private static final String cacheKey_equipmentName = "equipmentName";
    private static final String cacheKey_sysDesc = "sysDesc";
    private static final String cacheKey_sysVendor = "sysVendor";
    private static final String cacheKey_version = "version";

    private Snmp snmp;
    private UserTarget target;
    private SNMPV3UserInfo userInfo;
    //信息缓存
    private final ConcurrentHashMap<String,Object> infoCache = new ConcurrentHashMap<>();

    @Override
    public String toString() {
        return "SNMPV3Session{" +
                "snmp=" + snmp +
                ", target=" + target +
                ", userInfo=" + userInfo +
                '}';
    }

    /**
     * 创建SNMPV3会话
     * @param userInfo
     * @throws IOException
     * @throws AgentArgumentException
     */
    public SNMPV3Session(SNMPV3UserInfo userInfo) throws IOException, AgentArgumentException {
// Path: src/main/java/com/yiji/falcon/agent/exception/AgentArgumentException.java
// public class AgentArgumentException extends Exception {
// 
//     private String err;
// 
//     /**
//      * Constructs a new exception with the specified detail message.  The
//      * cause is not initialized, and may subsequently be initialized by
//      * a call to {@link #initCause}.
//      *
//      * @param err the detail message. The detail message is saved for
//      *            later retrieval by the {@link #getMessage()} method.
//      */
//     public AgentArgumentException(String err) {
//         super(err);
//         this.err = err;
//     }
// 
//     public String getErr() {
//         return err;
//     }
// 
// }
// 
// Path: src/main/java/com/yiji/falcon/agent/util/StringUtils.java
// public class StringUtils {
// 
//     /**
//      * 判断传入的String是否为空('' or null)
//      * @param str
//      * @return
//      */
//     public static boolean isEmpty(String str){
//         return str == null || str.length() == 0;
//     }
// 
//     /**
//      * 返回指定数字的字符串形式
//      * @param value
//      * @return
//      */
//     public static String getStringByInt(int value){
//         return String.valueOf(value).intern();
//     }
// 
// }
// 
// Path: src/main/java/com/yiji/falcon/agent/vo/snmp/SNMPV3UserInfo.java
// @Data
// public class SNMPV3UserInfo {
// 
//     /**
//      * 网络协议 如udp、tcp
//      */
//     private String protocol = "udp";
//     /**
//      * 网络设备的IP地址
//      */
//     private String address = "";
//     /**
//      * 网络设备的连接端口号
//      */
//     private String port = "161";
//     /**
//      * 用户名
//      */
//     private String username = "";
//     /**
//      * 认证算法,如 none,MD5,SHA
//      */
//     private String aythType = "";
//     /**
//      * 认证密码
//      */
//     private String authPswd = "";
//     /**
//      * 加密算法,如 none,DES,3DES,AES128,AES,AES192,AES256
//      */
//     private String privType = "";
//     /**
//      * 加密密码
//      */
//     private String privPswd = "";
//     /**
//      * endPoint
//      */
//     private String endPoint = "";
// 
//     /**
//      * 允许采集哪些名称的接口数据
//      * 注：只采集集合中的接口名称的数据。若为空，则不会采集接口数据
//      */
//     private List<String> ifCollectNameEnables;
// 
// }


// Path: src/main/java/com/yiji/falcon/agent/plugins/util/SNMPV3Session.java
import com.yiji.falcon.agent.exception.AgentArgumentException;
import com.yiji.falcon.agent.util.StringUtils;
import com.yiji.falcon.agent.vo.snmp.SNMPV3UserInfo;
import lombok.extern.slf4j.Slf4j;
import org.snmp4j.PDU;
import org.snmp4j.Snmp;
import org.snmp4j.UserTarget;
import org.snmp4j.mp.MPv3;
import org.snmp4j.mp.SnmpConstants;
import org.snmp4j.security.*;
import org.snmp4j.smi.GenericAddress;
import org.snmp4j.smi.OID;
import org.snmp4j.smi.OctetString;
import org.snmp4j.transport.DefaultUdpTransportMapping;
import java.io.IOException;
import java.util.List;
import java.util.concurrent.ConcurrentHashMap;

/*
 * www.yiji.com Inc.
 * Copyright (c) 2016 All Rights Reserved
 */
package com.yiji.falcon.agent.plugins.util;
/*
 * 修订记录:
 * guqiu@yiji.com 2016-07-12 10:47 创建
 */



/**
 * @author guqiu@yiji.com
 */
@Slf4j
public class SNMPV3Session {

//    private static final String cacheKey_equipmentName = "equipmentName";
    private static final String cacheKey_sysDesc = "sysDesc";
    private static final String cacheKey_sysVendor = "sysVendor";
    private static final String cacheKey_version = "version";

    private Snmp snmp;
    private UserTarget target;
    private SNMPV3UserInfo userInfo;
    //信息缓存
    private final ConcurrentHashMap<String,Object> infoCache = new ConcurrentHashMap<>();

    @Override
    public String toString() {
        return "SNMPV3Session{" +
                "snmp=" + snmp +
                ", target=" + target +
                ", userInfo=" + userInfo +
                '}';
    }

    /**
     * 创建SNMPV3会话
     * @param userInfo
     * @throws IOException
     * @throws AgentArgumentException
     */
    public SNMPV3Session(SNMPV3UserInfo userInfo) throws IOException, AgentArgumentException {
        if(StringUtils.isEmpty(userInfo.getAddress())){