001 /* 002 @license.text@ 003 */ 004 package biz.hammurapi.metrics.persistent; 005 006 import java.io.File; 007 import java.util.Properties; 008 009 import org.w3c.dom.Element; 010 import org.w3c.dom.Node; 011 import org.w3c.dom.NodeList; 012 013 import biz.hammurapi.config.Component; 014 import biz.hammurapi.config.ConfigurationException; 015 import biz.hammurapi.config.Context; 016 import biz.hammurapi.config.DomConfigurable; 017 import biz.hammurapi.config.MapContext; 018 import biz.hammurapi.metrics.Slice; 019 import biz.hammurapi.metrics.SliceConsumer; 020 import biz.hammurapi.sql.ConnectionPerThreadDataSource; 021 import biz.hammurapi.sql.IdentityManager; 022 import biz.hammurapi.sql.SQLProcessor; 023 import biz.hammurapi.xml.dom.AbstractDomObject; 024 import biz.hammurapi.xml.dom.DOMUtils; 025 026 027 /** 028 * @author Pavel Vlasov 029 */ 030 public class PersistingSliceConsumerDomConfigurableAdapter implements DomConfigurable, Component, SliceConsumer { 031 private SliceConsumer master; 032 private ConnectionPerThreadDataSource ds; 033 private SQLProcessor processor; 034 private long from; 035 036 public void start() throws ConfigurationException { 037 from=System.currentTimeMillis(); 038 try { 039 ds=new ConnectionPerThreadDataSource( 040 AbstractDomObject.getElementText(configElement, "driver-class"), 041 AbstractDomObject.getElementText(configElement, "database-url"), 042 AbstractDomObject.getElementText(configElement, "user"), 043 AbstractDomObject.getElementText(configElement, "password"), 044 null); // TODO - connection initialization nested elements??? 045 046 Properties properties=new Properties(); 047 NodeList nl=DOMUtils.selectNodeList(configElement, "name-map"); 048 for (int i=0, l=nl.getLength(); i<l; ++i) { 049 Element nme = (Element) nl.item(i); 050 properties.setProperty(nme.getAttribute("key"), DOMUtils.getElementText(nme)); 051 } 052 053 processor=new SQLProcessor(ds, new MapContext(properties)); 054 055 // String kmValue=AbstractDomObject.getElementText(configElement, "keep-measurements", cxpa); 056 // boolean keepMeasurements = kmValue==null ? false : "yes".equalsIgnoreCase(kmValue); 057 // 058 // String maxQueueValue=AbstractDomObject.getElementText(configElement, "max-queue", cxpa); 059 // int maxQueue = maxQueueValue==null ? 1000 : Integer.parseInt(maxQueueValue); 060 061 String root=AbstractDomObject.getElementText(configElement, "root-category"); 062 063 String historyValue=AbstractDomObject.getElementText(configElement, "history"); 064 long history = historyValue==null ? PersistingSliceConsumer.DAY : toTime(historyValue); 065 066 String miValue=AbstractDomObject.getElementText(configElement, "maintenance-interval"); 067 long maintenanceInterval = miValue==null ? 10*PersistingSliceConsumer.MINUTE : toTime(miValue); 068 069 String imValue=AbstractDomObject.getElementText(configElement, "identity-manager"); 070 IdentityManager identityManager = imValue==null ? null : (IdentityManager) Class.forName(imValue).newInstance(); 071 072 master = new PersistingSliceConsumer( 073 root, 074 history, 075 maintenanceInterval, 076 processor, 077 identityManager); 078 079 if (master instanceof Component) { 080 ((Component) master).start(); 081 } 082 } catch (Exception e) { 083 throw new ConfigurationException(e); 084 } 085 } 086 087 /** 088 * @param historyValue 089 * @return 090 */ 091 static long toTime(String timeValue) throws ConfigurationException { 092 String[] tva=timeValue.trim().split(" "); 093 long ret=Long.parseLong(tva[0]); 094 if (tva.length==1) { 095 return ret; 096 } else if (tva.length==2) { 097 if ("sec".equalsIgnoreCase(tva[1])) { 098 return ret*PersistingSliceConsumer.SECOND; 099 } else if ("min".equalsIgnoreCase(tva[1])) { 100 return ret*PersistingSliceConsumer.MINUTE; 101 } else if ("hour".equalsIgnoreCase(tva[1]) || "hours".equalsIgnoreCase(tva[1])) { 102 return ret*PersistingSliceConsumer.MONTH; 103 } else if ("day".equalsIgnoreCase(tva[1]) || "days".equalsIgnoreCase(tva[1])) { 104 return ret*PersistingSliceConsumer.DAY; 105 } else if ("week".equalsIgnoreCase(tva[1]) || "weeks".equalsIgnoreCase(tva[1])) { 106 return ret*PersistingSliceConsumer.WEEK; 107 } else if ("month".equalsIgnoreCase(tva[1]) || "months".equalsIgnoreCase(tva[1])) { 108 return ret*PersistingSliceConsumer.MONTH; 109 } else if ("year".equalsIgnoreCase(tva[1]) || "years".equalsIgnoreCase(tva[1])) { 110 return ret*PersistingSliceConsumer.YEAR; 111 } else { 112 throw new ConfigurationException("Invalid time: "+timeValue); 113 } 114 } else { 115 throw new ConfigurationException("Invalid time: "+timeValue); 116 } 117 } 118 119 public void stop() throws ConfigurationException { 120 if (master instanceof Component) { 121 ((Component) master).stop(); 122 } 123 124 if (ds!=null) { 125 try { 126 if (DOMUtils.selectSingleNode(configElement, "output-dir")!=null) { 127 PeriodFactory factory=new PeriodFactory(processor); 128 SyntheticPeriod root; 129 root=factory.getRootPeriod( 130 from, 131 System.currentTimeMillis(), 132 Integer.parseInt(DOMUtils.getSingleNonBlankElementText((Element) configElement, "slices")), false); 133 134 PeriodVisualizer.generateHtmlDoc( 135 root, 136 new File(DOMUtils.getSingleNonBlankElementText((Element) configElement, "output-dir")), 137 Integer.parseInt(DOMUtils.getSingleNonBlankElementText((Element) configElement, "width")), 138 Integer.parseInt(DOMUtils.getSingleNonBlankElementText((Element) configElement, "height"))); 139 } 140 141 ds.shutdown(); 142 } catch (Exception e) { 143 throw new ConfigurationException(e); 144 } 145 } 146 } 147 148 private Element configElement; 149 150 public void configure(Node configNode, Context context) throws ConfigurationException { 151 configElement=(Element) configNode; 152 } 153 154 public boolean consumeSlice(String category, Slice slice) { 155 return master.consumeSlice(category, slice); 156 } 157 158 public void setOwner(Object owner) { 159 // Ignore 160 } 161 }