001    /**
002     *  Licensed to the Apache Software Foundation (ASF) under one or more
003     *  contributor license agreements.  See the NOTICE file distributed with
004     *  this work for additional information regarding copyright ownership.
005     *  The ASF licenses this file to You under the Apache License, Version 2.0
006     *  (the "License"); you may not use this file except in compliance with
007     *  the License.  You may obtain a copy of the License at
008     *
009     *     http://www.apache.org/licenses/LICENSE-2.0
010     *
011     *  Unless required by applicable law or agreed to in writing, software
012     *  distributed under the License is distributed on an "AS IS" BASIS,
013     *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014     *  See the License for the specific language governing permissions and
015     *  limitations under the License.
016     */
017    
018    package org.apache.geronimo.j2ee.management.impl;
019    
020    import java.lang.management.ManagementFactory;
021    import java.lang.management.MemoryMXBean;
022    import java.lang.management.MemoryUsage;
023    import java.lang.management.RuntimeMXBean;
024    import java.net.InetAddress;
025    import java.net.UnknownHostException;
026    import java.util.Date;
027    import java.util.Hashtable;
028    import java.util.Properties;
029    
030    import javax.management.ObjectName;
031    import javax.management.j2ee.statistics.Stats;
032    
033    import org.apache.geronimo.gbean.GBeanInfo;
034    import org.apache.geronimo.gbean.GBeanInfoBuilder;
035    import org.apache.geronimo.j2ee.j2eeobjectnames.NameFactory;
036    import org.apache.geronimo.kernel.Kernel;
037    import org.apache.geronimo.kernel.ObjectNameUtil;
038    import org.apache.geronimo.management.StatisticsProvider;
039    import org.apache.geronimo.management.geronimo.JVM;
040    import org.apache.geronimo.management.stats.BoundedRangeStatisticImpl;
041    import org.apache.geronimo.management.stats.CountStatisticImpl;
042    import org.apache.geronimo.management.stats.JVMStatsImpl;
043    import org.apache.geronimo.system.logging.SystemLog;
044    
045    /**
046     *
047     *
048     * @version $Rev: 561093 $ $Date: 2007-07-30 15:04:51 -0400 (Mon, 30 Jul 2007) $
049     */
050    public class JVMImpl implements JVM, StatisticsProvider {
051        public static final String JAVA_VERSION = System.getProperty("java.version");
052        public static final String JAVA_VENDOR = System.getProperty("java.vendor");
053        public static final String NODE;
054        private static final Runtime runtime = Runtime.getRuntime();
055    
056        static {
057            String node;
058            try {
059                node = InetAddress.getLocalHost().toString();
060            } catch (UnknownHostException e) {
061                node = null;
062            }
063            NODE = node;
064        }
065    
066        private final String objectName;
067        private final Kernel kernel;
068        private final SystemLog systemLog;
069        private JVMStatsImpl stats;
070    
071        public JVMImpl(String objectName, Kernel kernel, SystemLog systemLog) {
072            this.objectName = objectName;
073            this.kernel = kernel;
074            this.systemLog = systemLog;
075            ObjectName myObjectName = ObjectNameUtil.getObjectName(this.objectName);
076            verifyObjectName(myObjectName);
077        }
078    
079        /**
080         * ObjectName must match this pattern:
081         * <p/>
082         * domain:j2eeType=JVM,name=MyName
083         */
084        private void verifyObjectName(ObjectName objectName) {
085            if (objectName.isPattern()) {
086                throw new InvalidObjectNameException("ObjectName can not be a pattern", objectName);
087            }
088            Hashtable keyPropertyList = objectName.getKeyPropertyList();
089            if (!"JVM".equals(keyPropertyList.get("j2eeType"))) {
090                throw new InvalidObjectNameException("JVM object name j2eeType property must be 'JVM'", objectName);
091            }
092            if (!keyPropertyList.containsKey("name")) {
093                throw new InvalidObjectNameException("JVM object must contain a name property", objectName);
094            }
095            if (!keyPropertyList.containsKey("J2EEServer")) {
096                throw new InvalidObjectNameException("JVM object must contain a J2EEServer property", objectName);
097            }
098            if (keyPropertyList.size() != 3) {
099                throw new InvalidObjectNameException("JVM object name can only have J2EEServer, j2eeType, and name", objectName);
100            }
101        }
102    
103        public String getObjectName() {
104            return objectName;
105        }
106    
107        public boolean isStateManageable() {
108            return true;
109        }
110    
111        public boolean isStatisticsProvider() {
112            return true;
113        }
114    
115        public boolean isEventProvider() {
116            return true;
117        }
118    
119        /**
120         * The version of the JVMImpl we are running on.
121         * This is the value of java.version system property
122         * @see "JSR77.3.4.1.1"
123         * @return the JVMImpl version
124         */
125        public String getJavaVersion() {
126            return JAVA_VERSION;
127        }
128    
129        /**
130         * The vendor of the JVMImpl we are running on.
131         * This is the value of java.vendor system property
132         * @see "JSR77.3.4.1.2"
133         * @return the JVMImpl version
134         */
135        public String getJavaVendor() {
136            return JAVA_VENDOR;
137        }
138    
139        /**
140         * The node we are running on.
141         * This is the fully qualified host name returned for InetAddress.getLocalHost.toString();
142         * we return null if there is no network
143         * @see "JSR77.3.4.1.3"
144         * @return the node we are running on
145         */
146        public String getNode() {
147            return NODE;
148        }
149    
150        public int getAvailableProcessors() {
151            return runtime.availableProcessors();
152        }
153    
154        public Date getKernelBootTime() {
155            return kernel.getBootTime();
156        }
157    
158        public Stats getStats() {
159            RuntimeMXBean runmxbean = ManagementFactory.getRuntimeMXBean();
160            MemoryMXBean memmxbean = ManagementFactory.getMemoryMXBean();
161            MemoryUsage memUsage = memmxbean.getHeapMemoryUsage();
162            CountStatisticImpl upTime;
163            BoundedRangeStatisticImpl heapSize;
164            
165            if (stats == null) {
166                stats = new JVMStatsImpl();
167                // setup UpTime CountStatistic
168                upTime = stats.getUpTimeImpl();
169                upTime.setStartTime(runmxbean.getStartTime());
170                upTime.setCount(runmxbean.getUptime());
171                // setup Heap BoundedRangeStatistic
172                heapSize = stats.getHeapSizeImpl();
173                heapSize.setStartTime(runmxbean.getStartTime());
174                heapSize.setBounds(0, memUsage.getMax());
175                heapSize.setCurrent(memUsage.getUsed());
176                heapSize.setLowWaterMark(memUsage.getUsed());
177                heapSize.setHighWaterMark(memUsage.getUsed());
178            } else {
179                // update UpTime CountStatistic
180                upTime = stats.getUpTimeImpl();
181                upTime.setCount(runmxbean.getUptime());
182                // update Heap BoundedRangeStatistic
183                heapSize = stats.getHeapSizeImpl();
184                heapSize.setBounds(0, memUsage.getMax());
185                heapSize.setCurrent(memUsage.getUsed());
186            }
187            long now = upTime.getStartTime() + upTime.getCount();
188            upTime.setLastSampleTime(now);
189            heapSize.setLastSampleTime(now);
190    
191            return stats;
192        }
193    
194        public void resetStats() {
195            // TODO
196        }
197    
198        public Properties getSystemProperties() {
199            return System.getProperties();
200        }
201    
202        public SystemLog getSystemLog() {
203            return systemLog;
204        }
205    
206        public static final GBeanInfo GBEAN_INFO;
207    
208        static {
209            GBeanInfoBuilder infoFactory = GBeanInfoBuilder.createStatic(JVMImpl.class, NameFactory.JVM);
210            infoFactory.addReference("SystemLog", SystemLog.class);
211            infoFactory.setConstructor(new String[] {"objectName", "kernel", "SystemLog"});
212            GBEAN_INFO = infoFactory.getBeanInfo();
213        }
214    
215        public static GBeanInfo getGBeanInfo() {
216            return GBEAN_INFO;
217        }
218    }