| /* |
| * Copyright (c) 2003, 2006, Oracle and/or its affiliates. All rights reserved. |
| * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
| * |
| * This code is free software; you can redistribute it and/or modify it |
| * under the terms of the GNU General Public License version 2 only, as |
| * published by the Free Software Foundation. Oracle designates this |
| * particular file as subject to the "Classpath" exception as provided |
| * by Oracle in the LICENSE file that accompanied this code. |
| * |
| * This code 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 |
| * version 2 for more details (a copy is included in the LICENSE file that |
| * accompanied this code). |
| * |
| * You should have received a copy of the GNU General Public License version |
| * 2 along with this work; if not, write to the Free Software Foundation, |
| * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. |
| * |
| * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
| * or visit www.oracle.com if you need additional information or have any |
| * questions. |
| */ |
| package sun.management.snmp.jvminstr; |
| |
| // java imports |
| // |
| import java.util.Hashtable; |
| import java.util.List; |
| import java.util.ArrayList; |
| import java.util.Iterator; |
| import java.lang.ref.WeakReference; |
| |
| // jmx imports |
| // |
| import javax.management.MBeanServer; |
| import javax.management.ObjectName; |
| import javax.management.InstanceAlreadyExistsException; |
| import javax.management.NotificationEmitter; |
| import javax.management.NotificationListener; |
| import javax.management.Notification; |
| import javax.management.ListenerNotFoundException; |
| import javax.management.openmbean.CompositeData; |
| |
| // jdmk imports |
| // |
| import com.sun.jmx.snmp.agent.SnmpMib; |
| import com.sun.jmx.snmp.daemon.SnmpAdaptorServer; |
| import com.sun.jmx.snmp.SnmpPeer; |
| import com.sun.jmx.snmp.SnmpParameters; |
| |
| import com.sun.jmx.snmp.SnmpOidTable; |
| import com.sun.jmx.snmp.SnmpOid; |
| import com.sun.jmx.snmp.SnmpVarBindList; |
| import com.sun.jmx.snmp.SnmpVarBind; |
| import com.sun.jmx.snmp.SnmpCounter; |
| import com.sun.jmx.snmp.SnmpCounter64; |
| import com.sun.jmx.snmp.SnmpString; |
| import com.sun.jmx.snmp.SnmpInt; |
| import com.sun.jmx.snmp.Enumerated; |
| import com.sun.jmx.snmp.agent.SnmpMibTable; |
| |
| import sun.management.snmp.jvmmib.JVM_MANAGEMENT_MIBOidTable; |
| import sun.management.snmp.jvmmib.JVM_MANAGEMENT_MIB; |
| import sun.management.snmp.jvmmib.JvmMemoryMeta; |
| import sun.management.snmp.jvmmib.JvmThreadingMeta; |
| import sun.management.snmp.jvmmib.JvmRuntimeMeta; |
| import sun.management.snmp.jvmmib.JvmClassLoadingMeta; |
| import sun.management.snmp.jvmmib.JvmCompilationMeta; |
| import sun.management.snmp.util.MibLogger; |
| import sun.management.snmp.util.SnmpCachedData; |
| import sun.management.snmp.util.SnmpTableHandler; |
| |
| //java management imports |
| import java.lang.management.ManagementFactory; |
| import java.lang.management.MemoryPoolMXBean; |
| import java.lang.management.MemoryNotificationInfo; |
| import java.lang.management.MemoryType; |
| |
| public class JVM_MANAGEMENT_MIB_IMPL extends JVM_MANAGEMENT_MIB { |
| private static final long serialVersionUID = -8104825586888859831L; |
| |
| private static final MibLogger log = |
| new MibLogger(JVM_MANAGEMENT_MIB_IMPL.class); |
| |
| private static WeakReference<SnmpOidTable> tableRef; |
| |
| public static SnmpOidTable getOidTable() { |
| SnmpOidTable table = null; |
| if(tableRef == null) { |
| table = new JVM_MANAGEMENT_MIBOidTable(); |
| tableRef = new WeakReference<SnmpOidTable>(table); |
| return table; |
| } |
| |
| table = tableRef.get(); |
| if(table == null) { |
| table = new JVM_MANAGEMENT_MIBOidTable(); |
| tableRef = new WeakReference<SnmpOidTable>(table); |
| } |
| |
| return table; |
| } |
| |
| /** |
| * Handler waiting for memory <CODE>Notification</CODE>. |
| * Translate each JMX notification in SNMP trap. |
| */ |
| private class NotificationHandler implements NotificationListener { |
| public void handleNotification(Notification notification, |
| Object handback) { |
| log.debug("handleNotification", "Received notification [ " + |
| notification.getType() + "]"); |
| |
| String type = notification.getType(); |
| if (type.equals(MemoryNotificationInfo.MEMORY_THRESHOLD_EXCEEDED) || |
| type.equals(MemoryNotificationInfo. |
| MEMORY_COLLECTION_THRESHOLD_EXCEEDED)) { |
| MemoryNotificationInfo minfo = MemoryNotificationInfo. |
| from((CompositeData) notification.getUserData()); |
| SnmpCounter64 count = new SnmpCounter64(minfo.getCount()); |
| SnmpCounter64 used = |
| new SnmpCounter64(minfo.getUsage().getUsed()); |
| SnmpString poolName = new SnmpString(minfo.getPoolName()); |
| SnmpOid entryIndex = |
| getJvmMemPoolEntryIndex(minfo.getPoolName()); |
| |
| if (entryIndex == null) { |
| log.error("handleNotification", |
| "Error: Can't find entry index for Memory Pool: " |
| + minfo.getPoolName() +": " + |
| "No trap emitted for " + type); |
| return; |
| } |
| |
| SnmpOid trap = null; |
| |
| final SnmpOidTable mibTable = getOidTable(); |
| try { |
| SnmpOid usedOid = null; |
| SnmpOid countOid = null; |
| |
| if (type.equals(MemoryNotificationInfo. |
| MEMORY_THRESHOLD_EXCEEDED)) { |
| trap = new SnmpOid(mibTable. |
| resolveVarName("jvmLowMemoryPoolUsageNotif").getOid()); |
| usedOid = |
| new SnmpOid(mibTable. |
| resolveVarName("jvmMemPoolUsed").getOid() + |
| "." + entryIndex); |
| countOid = |
| new SnmpOid(mibTable. |
| resolveVarName("jvmMemPoolThreshdCount").getOid() |
| + "." + entryIndex); |
| } else if (type.equals(MemoryNotificationInfo. |
| MEMORY_COLLECTION_THRESHOLD_EXCEEDED)) { |
| trap = new SnmpOid(mibTable. |
| resolveVarName("jvmLowMemoryPoolCollectNotif"). |
| getOid()); |
| usedOid = |
| new SnmpOid(mibTable. |
| resolveVarName("jvmMemPoolCollectUsed").getOid() + |
| "." + entryIndex); |
| countOid = |
| new SnmpOid(mibTable. |
| resolveVarName("jvmMemPoolCollectThreshdCount"). |
| getOid() + |
| "." + entryIndex); |
| } |
| |
| //Datas |
| SnmpVarBindList list = new SnmpVarBindList(); |
| SnmpOid poolNameOid = |
| new SnmpOid(mibTable. |
| resolveVarName("jvmMemPoolName").getOid() + |
| "." + entryIndex); |
| |
| SnmpVarBind varCount = new SnmpVarBind(countOid, count); |
| SnmpVarBind varUsed = new SnmpVarBind(usedOid, used); |
| SnmpVarBind varPoolName = new SnmpVarBind(poolNameOid, |
| poolName); |
| |
| list.add(varPoolName); |
| list.add(varCount); |
| list.add(varUsed); |
| |
| sendTrap(trap, list); |
| }catch(Exception e) { |
| log.error("handleNotification", |
| "Exception occured : " + e); |
| } |
| } |
| } |
| } |
| |
| /** |
| * List of notification targets. |
| */ |
| private ArrayList<NotificationTarget> notificationTargets = |
| new ArrayList<NotificationTarget>(); |
| private final NotificationEmitter emitter; |
| private final NotificationHandler handler; |
| |
| |
| /** |
| * Instantiate a JVM MIB intrusmentation. |
| * A <CODE>NotificationListener</CODE> is added to the <CODE>MemoryMXBean</CODE> |
| * <CODE>NotificationEmitter</CODE> |
| */ |
| public JVM_MANAGEMENT_MIB_IMPL() { |
| handler = new NotificationHandler(); |
| emitter = (NotificationEmitter) ManagementFactory.getMemoryMXBean(); |
| emitter.addNotificationListener(handler, null, null); |
| } |
| |
| private synchronized void sendTrap(SnmpOid trap, SnmpVarBindList list) { |
| final Iterator iterator = notificationTargets.iterator(); |
| final SnmpAdaptorServer adaptor = |
| (SnmpAdaptorServer) getSnmpAdaptor(); |
| |
| if (adaptor == null) { |
| log.error("sendTrap", "Cannot send trap: adaptor is null."); |
| return; |
| } |
| |
| if (!adaptor.isActive()) { |
| log.config("sendTrap", "Adaptor is not active: trap not sent."); |
| return; |
| } |
| |
| while(iterator.hasNext()) { |
| NotificationTarget target = null; |
| try { |
| target = (NotificationTarget) iterator.next(); |
| SnmpPeer peer = |
| new SnmpPeer(target.getAddress(), target.getPort()); |
| SnmpParameters p = new SnmpParameters(); |
| p.setRdCommunity(target.getCommunity()); |
| peer.setParams(p); |
| log.debug("handleNotification", "Sending trap to " + |
| target.getAddress() + ":" + target.getPort()); |
| adaptor.snmpV2Trap(peer, trap, list, null); |
| }catch(Exception e) { |
| log.error("sendTrap", |
| "Exception occured while sending trap to [" + |
| target + "]. Exception : " + e); |
| log.debug("sendTrap",e); |
| } |
| } |
| } |
| |
| /** |
| * Add a notification target. |
| * @param target The target to add |
| * @throws IllegalArgumentException If target parameter is null. |
| */ |
| public synchronized void addTarget(NotificationTarget target) |
| throws IllegalArgumentException { |
| if(target == null) |
| throw new IllegalArgumentException("Target is null"); |
| |
| notificationTargets.add(target); |
| } |
| |
| /** |
| * Remove notification listener. |
| */ |
| public void terminate() { |
| try { |
| emitter.removeNotificationListener(handler); |
| }catch(ListenerNotFoundException e) { |
| log.error("terminate", "Listener Not found : " + e); |
| } |
| } |
| |
| /** |
| * Add notification targets. |
| * @param targets A list of |
| * <CODE>sun.management.snmp.jvminstr.NotificationTarget</CODE> |
| * @throws IllegalArgumentException If targets parameter is null. |
| */ |
| public synchronized void addTargets(List<NotificationTarget> targets) |
| throws IllegalArgumentException { |
| if(targets == null) |
| throw new IllegalArgumentException("Target list is null"); |
| |
| notificationTargets.addAll(targets); |
| } |
| |
| /** |
| * Factory method for "JvmMemory" group MBean. |
| * |
| * You can redefine this method if you need to replace the default |
| * generated MBean class with your own customized class. |
| * |
| * @param groupName Name of the group ("JvmMemory") |
| * @param groupOid OID of this group |
| * @param groupObjname ObjectName for this group (may be null) |
| * @param server MBeanServer for this group (may be null) |
| * |
| * @return An instance of the MBean class generated for the |
| * "JvmMemory" group (JvmMemory) |
| * |
| * Note that when using standard metadata, |
| * the returned object must implement the "JvmMemoryMBean" |
| * interface. |
| **/ |
| protected Object createJvmMemoryMBean(String groupName, |
| String groupOid, ObjectName groupObjname, |
| MBeanServer server) { |
| |
| // Note that when using standard metadata, |
| // the returned object must implement the "JvmMemoryMBean" |
| // interface. |
| // |
| if (server != null) |
| return new JvmMemoryImpl(this,server); |
| else |
| return new JvmMemoryImpl(this); |
| } |
| |
| /** |
| * Factory method for "JvmMemory" group metadata class. |
| * |
| * You can redefine this method if you need to replace the default |
| * generated metadata class with your own customized class. |
| * |
| * @param groupName Name of the group ("JvmMemory") |
| * @param groupOid OID of this group |
| * @param groupObjname ObjectName for this group (may be null) |
| * @param server MBeanServer for this group (may be null) |
| * |
| * @return An instance of the metadata class generated for the |
| * "JvmMemory" group (JvmMemoryMeta) |
| * |
| **/ |
| protected JvmMemoryMeta createJvmMemoryMetaNode(String groupName, |
| String groupOid, |
| ObjectName groupObjname, |
| MBeanServer server) { |
| return new JvmMemoryMetaImpl(this, objectserver); |
| } |
| |
| /** |
| * Factory method for "JvmThreading" group metadata class. |
| * |
| * You can redefine this method if you need to replace the default |
| * generated metadata class with your own customized class. |
| * |
| * @param groupName Name of the group ("JvmThreading") |
| * @param groupOid OID of this group |
| * @param groupObjname ObjectName for this group (may be null) |
| * @param server MBeanServer for this group (may be null) |
| * |
| * @return An instance of the metadata class generated for the |
| * "JvmThreading" group (JvmThreadingMeta) |
| * |
| **/ |
| protected JvmThreadingMeta createJvmThreadingMetaNode(String groupName, |
| String groupOid, |
| ObjectName groupObjname, |
| MBeanServer server) { |
| return new JvmThreadingMetaImpl(this, objectserver); |
| } |
| |
| /** |
| * Factory method for "JvmThreading" group MBean. |
| * |
| * You can redefine this method if you need to replace the default |
| * generated MBean class with your own customized class. |
| * |
| * @param groupName Name of the group ("JvmThreading") |
| * @param groupOid OID of this group |
| * @param groupObjname ObjectName for this group (may be null) |
| * @param server MBeanServer for this group (may be null) |
| * |
| * @return An instance of the MBean class generated for the |
| * "JvmThreading" group (JvmThreading) |
| * |
| * Note that when using standard metadata, |
| * the returned object must implement the "JvmThreadingMBean" |
| * interface. |
| **/ |
| protected Object createJvmThreadingMBean(String groupName, |
| String groupOid, |
| ObjectName groupObjname, |
| MBeanServer server) { |
| |
| // Note that when using standard metadata, |
| // the returned object must implement the "JvmThreadingMBean" |
| // interface. |
| // |
| if (server != null) |
| return new JvmThreadingImpl(this,server); |
| else |
| return new JvmThreadingImpl(this); |
| } |
| |
| /** |
| * Factory method for "JvmRuntime" group metadata class. |
| * |
| * You can redefine this method if you need to replace the default |
| * generated metadata class with your own customized class. |
| * |
| * @param groupName Name of the group ("JvmRuntime") |
| * @param groupOid OID of this group |
| * @param groupObjname ObjectName for this group (may be null) |
| * @param server MBeanServer for this group (may be null) |
| * |
| * @return An instance of the metadata class generated for the |
| * "JvmRuntime" group (JvmRuntimeMeta) |
| * |
| **/ |
| protected JvmRuntimeMeta createJvmRuntimeMetaNode(String groupName, |
| String groupOid, |
| ObjectName groupObjname, |
| MBeanServer server) { |
| return new JvmRuntimeMetaImpl(this, objectserver); |
| } |
| |
| /** |
| * Factory method for "JvmRuntime" group MBean. |
| * |
| * You can redefine this method if you need to replace the default |
| * generated MBean class with your own customized class. |
| * |
| * @param groupName Name of the group ("JvmRuntime") |
| * @param groupOid OID of this group |
| * @param groupObjname ObjectName for this group (may be null) |
| * @param server MBeanServer for this group (may be null) |
| * |
| * @return An instance of the MBean class generated for the |
| * "JvmRuntime" group (JvmRuntime) |
| * |
| * Note that when using standard metadata, |
| * the returned object must implement the "JvmRuntimeMBean" |
| * interface. |
| **/ |
| protected Object createJvmRuntimeMBean(String groupName, |
| String groupOid, |
| ObjectName groupObjname, |
| MBeanServer server) { |
| |
| // Note that when using standard metadata, |
| // the returned object must implement the "JvmRuntimeMBean" |
| // interface. |
| // |
| if (server != null) |
| return new JvmRuntimeImpl(this,server); |
| else |
| return new JvmRuntimeImpl(this); |
| } |
| |
| /** |
| * Factory method for "JvmCompilation" group metadata class. |
| * |
| * You can redefine this method if you need to replace the default |
| * generated metadata class with your own customized class. |
| * |
| * @param groupName Name of the group ("JvmCompilation") |
| * @param groupOid OID of this group |
| * @param groupObjname ObjectName for this group (may be null) |
| * @param server MBeanServer for this group (may be null) |
| * |
| * @return An instance of the metadata class generated for the |
| * "JvmCompilation" group (JvmCompilationMeta) |
| * |
| **/ |
| protected JvmCompilationMeta |
| createJvmCompilationMetaNode(String groupName, |
| String groupOid, |
| ObjectName groupObjname, |
| MBeanServer server) { |
| // If there is no compilation system, the jvmCompilation will not |
| // be instantiated. |
| // |
| if (ManagementFactory.getCompilationMXBean() == null) return null; |
| return super.createJvmCompilationMetaNode(groupName,groupOid, |
| groupObjname,server); |
| } |
| |
| /** |
| * Factory method for "JvmCompilation" group MBean. |
| * |
| * You can redefine this method if you need to replace the default |
| * generated MBean class with your own customized class. |
| * |
| * @param groupName Name of the group ("JvmCompilation") |
| * @param groupOid OID of this group |
| * @param groupObjname ObjectName for this group (may be null) |
| * @param server MBeanServer for this group (may be null) |
| * |
| * @return An instance of the MBean class generated for the |
| * "JvmCompilation" group (JvmCompilation) |
| * |
| * Note that when using standard metadata, |
| * the returned object must implement the "JvmCompilationMBean" |
| * interface. |
| **/ |
| protected Object createJvmCompilationMBean(String groupName, |
| String groupOid, ObjectName groupObjname, MBeanServer server) { |
| |
| // Note that when using standard metadata, |
| // the returned object must implement the "JvmCompilationMBean" |
| // interface. |
| // |
| if (server != null) |
| return new JvmCompilationImpl(this,server); |
| else |
| return new JvmCompilationImpl(this); |
| } |
| |
| /** |
| * Factory method for "JvmOS" group MBean. |
| * |
| * You can redefine this method if you need to replace the default |
| * generated MBean class with your own customized class. |
| * |
| * @param groupName Name of the group ("JvmOS") |
| * @param groupOid OID of this group |
| * @param groupObjname ObjectName for this group (may be null) |
| * @param server MBeanServer for this group (may be null) |
| * |
| * @return An instance of the MBean class generated for the |
| * "JvmOS" group (JvmOS) |
| * |
| * Note that when using standard metadata, |
| * the returned object must implement the "JvmOSMBean" |
| * interface. |
| **/ |
| protected Object createJvmOSMBean(String groupName, |
| String groupOid, ObjectName groupObjname, MBeanServer server) { |
| |
| // Note that when using standard metadata, |
| // the returned object must implement the "JvmOSMBean" |
| // interface. |
| // |
| if (server != null) |
| return new JvmOSImpl(this,server); |
| else |
| return new JvmOSImpl(this); |
| } |
| |
| |
| /** |
| * Factory method for "JvmClassLoading" group MBean. |
| * |
| * You can redefine this method if you need to replace the default |
| * generated MBean class with your own customized class. |
| * |
| * @param groupName Name of the group ("JvmClassLoading") |
| * @param groupOid OID of this group |
| * @param groupObjname ObjectName for this group (may be null) |
| * @param server MBeanServer for this group (may be null) |
| * |
| * @return An instance of the MBean class generated for the |
| * "JvmClassLoading" group (JvmClassLoading) |
| * |
| * Note that when using standard metadata, |
| * the returned object must implement the "JvmClassLoadingMBean" |
| * interface. |
| **/ |
| protected Object createJvmClassLoadingMBean(String groupName, |
| String groupOid, |
| ObjectName groupObjname, |
| MBeanServer server) { |
| |
| // Note that when using standard metadata, |
| // the returned object must implement the "JvmClassLoadingMBean" |
| // interface. |
| // |
| if (server != null) |
| return new JvmClassLoadingImpl(this,server); |
| else |
| return new JvmClassLoadingImpl(this); |
| } |
| |
| static String validDisplayStringTC(String str) { |
| |
| if(str == null) return ""; |
| |
| if(str.length() > DISPLAY_STRING_MAX_LENGTH) { |
| return str.substring(0, DISPLAY_STRING_MAX_LENGTH); |
| } |
| else |
| return str; |
| } |
| |
| static String validJavaObjectNameTC(String str) { |
| |
| if(str == null) return ""; |
| |
| if(str.length() > JAVA_OBJECT_NAME_MAX_LENGTH) { |
| return str.substring(0, JAVA_OBJECT_NAME_MAX_LENGTH); |
| } |
| else |
| return str; |
| } |
| |
| static String validPathElementTC(String str) { |
| |
| if(str == null) return ""; |
| |
| if(str.length() > PATH_ELEMENT_MAX_LENGTH) { |
| return str.substring(0, PATH_ELEMENT_MAX_LENGTH); |
| } |
| else |
| return str; |
| } |
| static String validArgValueTC(String str) { |
| |
| if(str == null) return ""; |
| |
| if(str.length() > ARG_VALUE_MAX_LENGTH) { |
| return str.substring(0, ARG_VALUE_MAX_LENGTH); |
| } |
| else |
| return str; |
| } |
| |
| /** |
| * WARNING: This should probably be moved to JvmMemPoolTableMetaImpl |
| **/ |
| private SnmpTableHandler getJvmMemPoolTableHandler(Object userData) { |
| final SnmpMibTable meta = |
| getRegisteredTableMeta("JvmMemPoolTable"); |
| if (! (meta instanceof JvmMemPoolTableMetaImpl)) { |
| final String err = ((meta==null)?"No metadata for JvmMemPoolTable": |
| "Bad metadata class for JvmMemPoolTable: " + |
| meta.getClass().getName()); |
| log.error("getJvmMemPoolTableHandler", err); |
| return null; |
| } |
| final JvmMemPoolTableMetaImpl memPoolTable = |
| (JvmMemPoolTableMetaImpl) meta; |
| return memPoolTable.getHandler(userData); |
| } |
| |
| /** |
| * WARNING: This should probably be moved to JvmMemPoolTableMetaImpl |
| **/ |
| private int findInCache(SnmpTableHandler handler, |
| String poolName) { |
| |
| if (!(handler instanceof SnmpCachedData)) { |
| if (handler != null) { |
| final String err = "Bad class for JvmMemPoolTable datas: " + |
| handler.getClass().getName(); |
| log.error("getJvmMemPoolEntry", err); |
| } |
| return -1; |
| } |
| |
| final SnmpCachedData data = (SnmpCachedData)handler; |
| final int len = data.datas.length; |
| for (int i=0; i < data.datas.length ; i++) { |
| final MemoryPoolMXBean pool = (MemoryPoolMXBean) data.datas[i]; |
| if (poolName.equals(pool.getName())) return i; |
| } |
| return -1; |
| } |
| |
| /** |
| * WARNING: This should probably be moved to JvmMemPoolTableMetaImpl |
| **/ |
| private SnmpOid getJvmMemPoolEntryIndex(SnmpTableHandler handler, |
| String poolName) { |
| final int index = findInCache(handler,poolName); |
| if (index < 0) return null; |
| return ((SnmpCachedData)handler).indexes[index]; |
| } |
| |
| private SnmpOid getJvmMemPoolEntryIndex(String poolName) { |
| return getJvmMemPoolEntryIndex(getJvmMemPoolTableHandler(null), |
| poolName); |
| } |
| |
| // cache validity |
| // |
| // Should we define a property for this? Should we have different |
| // cache validity periods depending on which table we cache? |
| // |
| public long validity() { |
| return DEFAULT_CACHE_VALIDITY_PERIOD; |
| } |
| |
| // Defined in RFC 2579 |
| private final static int DISPLAY_STRING_MAX_LENGTH=255; |
| private final static int JAVA_OBJECT_NAME_MAX_LENGTH=1023; |
| private final static int PATH_ELEMENT_MAX_LENGTH=1023; |
| private final static int ARG_VALUE_MAX_LENGTH=1023; |
| private final static int DEFAULT_CACHE_VALIDITY_PERIOD=1000; |
| } |