1 2 12 package com.versant.core.jdo; 13 14 import com.versant.core.common.config.ConfigInfo; 15 import com.versant.core.util.BeanUtils; 16 import com.versant.core.util.StringListParser; 17 import com.versant.core.util.PropertiesLoader; 18 import com.versant.core.util.classhelper.ClassHelper; 19 import com.versant.core.common.BindingSupportImpl; 20 import com.versant.core.metric.*; 21 import com.versant.core.metric.HasMetrics; 22 import com.versant.core.logging.LogEvent; 23 import com.versant.core.storagemanager.StorageManagerFactory; 24 import com.versant.core.storagemanager.StorageManagerFactoryBuilder; 25 26 import javax.jdo.PersistenceManagerFactory; 27 import java.util.*; 28 import java.io.IOException ; 29 30 33 public class PersistenceManagerFactoryImp 34 extends PersistenceManagerFactoryBase implements HasMetrics { 35 36 protected Map hyperdriveBytecode; 37 protected int hyperdriveBytecodeMaxSize; 38 protected VersantBackgroundTask logDownloader; 39 protected Thread logDownloaderThread; 40 protected PMFServer[] pmfServers; 41 protected boolean releaseHyperdriveBytecode; 42 43 protected MetricSnapshotStore metricSnapshotStore; 44 protected HashMap userMetricIndexMap; 45 protected BaseMetric[] userMetrics; 46 protected int[] userMetricValues; 47 48 public static final String PMF_SERVER = "pmf.server"; 49 public static final String RELEASE_HYPERDRIVE_BYTECODE = 50 "versant.releaseHyperdriveBytecode"; 51 52 private static final String CAT_GENERAL = "General"; 53 54 private final BaseMetric metricEvents = 55 new BaseMetric("Events", "Events", CAT_GENERAL, 56 "Number of events logged", 3, Metric.CALC_DELTA_PER_SECOND); 57 private final BaseMetric metricLastEventId = 58 new BaseMetric("LastEventId", "Last Event ID", CAT_GENERAL, 59 "Approximate ID of the last event logged", 0, 60 Metric.CALC_RAW); 61 62 private static final String CAT_PM = "PM"; 63 64 private final BaseMetric metricPMCreated = 65 new BaseMetric("PMCreated", "PM Created", CAT_PM, 66 "Number of local PMs created", 3, 67 Metric.CALC_DELTA_PER_SECOND); 68 private final BaseMetric metricPMClosed = 69 new BaseMetric("PMClosed", "PM Closed", CAT_PM, 70 "Number of PMs closed (local and remote)", 3, 71 Metric.CALC_DELTA_PER_SECOND); 72 private final BaseMetric metricPMClosedAuto = 73 new BaseMetric("PMClosedAuto", "PM Closed Auto", CAT_PM, 74 "Number of PMs closed automatically (local and remote)", 0, 75 Metric.CALC_RAW); 76 private final BaseMetric metricPMClosedAutoTx = 77 new BaseMetric("PMClosedAutoTx", "PM Closed Auto Tx", CAT_PM, 78 "Number of PMs closed automatically with active datastore transaction (BAD)", 79 0, Metric.CALC_RAW); 80 private final BaseMetric metricPMCount = 81 new BaseMetric("PMCount", "PM Count", CAT_PM, 82 "Number of open PMs", 0, 83 Metric.CALC_AVERAGE); 84 85 89 public static PersistenceManagerFactory getPersistenceManagerFactory( 90 Properties props) { 91 return new PersistenceManagerFactoryImp(props, 92 PersistenceManagerFactoryImp.class.getClassLoader()); 93 } 94 95 public PersistenceManagerFactoryImp(Properties props, 96 ClassLoader loader) { 97 super(props, loader); 98 boolean ok = false; 99 try { 100 initLogDownloader(config, loader); 101 initMetrics(config); 102 if (pmfServers != null) { 103 for (int i = 0; i < pmfServers.length; i++) { 104 PMFServer s = pmfServers[i]; 105 s.init(this); 106 if (s instanceof HasMetrics) { 107 metricSnapshotStore.addSource((HasMetrics)s); 108 } 109 } 110 } 111 startLogDownloader(config); 112 metricSnapshotStore.start(config.url); 113 if (pmfServers != null) { 114 for (int i = 0; i < pmfServers.length; i++) { 115 try { 116 pmfServers[i].start(); 117 } catch (Exception e) { 118 throw handleException(e); 119 } 120 } 121 } 122 ok = true; 123 } finally { 124 if (!ok) { 125 try { 126 close(); 127 } catch (Throwable e) { 128 } 130 } 131 } 132 } 133 134 137 protected StorageManagerFactory createStorageManagerFactory() { 138 createPMFServers(); 139 releaseHyperdriveBytecode = pmfServers == null 140 && "true".equals(props.getProperty(RELEASE_HYPERDRIVE_BYTECODE)); 141 StorageManagerFactoryBuilder b = new StorageManagerFactoryBuilder(); 142 b.setLogEventStore(pes); 143 b.setConfig(config); 144 b.setLoader(loader); 145 b.setCache(cache); 146 b.setKeepHyperdriveBytecode(!releaseHyperdriveBytecode); 147 StorageManagerFactory ans = b.createStorageManagerFactory(); 148 hyperdriveBytecode = b.getHyperdriveBytecode(); 149 hyperdriveBytecodeMaxSize = b.getHyperdriveBytecodeMaxSize(); 150 return ans; 151 } 152 153 public void addPMFServer(PMFServer pmfServer) { 154 if (releaseHyperdriveBytecode && config.hyperdrive) { 155 throw BindingSupportImpl.getInstance().invalidOperation( 156 "Unable to add PMFServer as versant.releaseHyperdriveBytecode " + 157 "property is true"); 158 } 159 addPMFServerImp(pmfServer); 160 if (pmfServer instanceof HasMetrics) { 161 metricSnapshotStore.addSource((HasMetrics)pmfServer); 162 } 163 } 164 165 protected void addPMFServerImp(PMFServer pmfServer) { 166 if (pmfServers == null) { 167 pmfServers = new PMFServer[]{pmfServer}; 168 } else { 169 int n = pmfServers.length; 170 PMFServer[] a = new PMFServer[n + 1]; 171 System.arraycopy(pmfServers, 0, a, 0, n); 172 a[n] = pmfServer; 173 pmfServers = a; 174 } 175 } 176 177 180 protected void createPMFServers() { 181 String ra = config.remoteAccess; 182 if (ra == null || "true".equals(ra)) { 183 ra = "socket"; 184 } else if ("false".equals(ra)) { 185 return; 186 } 187 boolean defaultProtocol = "socket".equals(ra); 188 for (StringListParser lp = new StringListParser(ra); 189 lp.hasNext(); ) { 190 String protocol = lp.nextString(); 191 PMFServer pmfServer = createPMFServer(protocol, defaultProtocol); 192 if (pmfServer != null) { 193 addPMFServerImp(pmfServer); 194 } 195 } 196 } 197 198 205 private PMFServer createPMFServer(String protocol, 206 boolean defaultProtocol) { 207 Properties p; 208 try { 209 p = PropertiesLoader.loadProperties(loader, 210 "openaccess-remote", protocol); 211 } catch (IOException e) { 212 if (defaultProtocol) { 213 return null; 214 } 215 throw BindingSupportImpl.getInstance().invalidOperation( 216 e.toString(), e); 217 } 218 String clsName = p.getProperty(PMF_SERVER); 219 if (clsName == null) { 220 throw BindingSupportImpl.getInstance().internal( 221 PMF_SERVER + " not found in resource " + 222 p.getProperty(PropertiesLoader.RES_NAME_PROP)); 223 } 224 try { 225 Class cls = ClassHelper.get().classForName(clsName, true, loader); 226 return (PMFServer)cls.newInstance(); 227 } catch (Exception e) { 228 throw BindingSupportImpl.getInstance().internal(e.toString(), e); 229 } 230 } 231 232 protected void initMetrics(ConfigInfo config) { 233 int n = config.userBaseMetrics.size(); 234 if (n > 0) { 235 userMetricValues = new int[n]; 236 userMetricIndexMap = new HashMap(n * 2); 237 userMetrics = new BaseMetric[n]; 238 for (int i = 0; i < n; i++) { 239 ConfigInfo.UserBaseMetric u = 240 (ConfigInfo.UserBaseMetric)config.userBaseMetrics.get(i); 241 BaseMetric m = new BaseMetric(u.name, u.displayName, u.category, 242 u.description, u.decimals, u.defaultCalc); 243 userMetricIndexMap.put(m.getName(), new Integer (i)); 244 userMetrics[i] = m; 245 } 246 } 247 metricSnapshotStore = new MetricSnapshotStore( 248 config.metricStoreCapacity, config.metricSnapshotIntervalMs); 249 metricSnapshotStore.addSource(this); 250 } 251 252 protected void startLogDownloader(ConfigInfo config) { 253 logDownloaderThread = new Thread (logDownloader, 254 "VOA Log Downloader " + config.url); 255 logDownloaderThread.setDaemon(true); 256 logDownloaderThread.start(); 257 } 258 259 protected void initLogDownloader(ConfigInfo config, ClassLoader loader) { 260 try { 261 if (config.logDownloaderClass == null) { 262 logDownloader = new LogDownloader(); 263 } else { 264 logDownloader = (VersantBackgroundTask)BeanUtils.newInstance( 265 config.logDownloaderClass, loader, 266 VersantBackgroundTask.class); 267 } 268 BeanUtils.setProperties(logDownloader, config.logDownloaderProps); 269 if (logDownloader instanceof LogDownloader) { 270 ((LogDownloader)logDownloader).setQuiet(true); 271 } 272 logDownloader.setPmf(this); 273 } catch (Exception e) { 274 throw handleException(e); 275 } 276 } 277 278 public synchronized void close() { 279 super.close(); 280 if (pmfServers != null) { 281 for (int i = 0; i < pmfServers.length; i++) { 282 try { 283 pmfServers[i].close(); 284 } catch (Throwable e) { 285 } 287 } 288 } 289 if (logDownloaderThread != null) { 290 logDownloader.shutdown(); 291 logDownloaderThread.interrupt(); 292 logDownloaderThread = null; 293 } 294 if (metricSnapshotStore != null) { 295 metricSnapshotStore.shutdown(); 296 metricSnapshotStore = null; 297 } 298 } 299 300 public Metric[] getMetrics() { 301 return metricSnapshotStore.getMetrics(); 302 } 303 304 public MetricSnapshotPacket getNewMetricSnapshots(int lastId) { 305 return metricSnapshotStore.getNewSnapshots(lastId); 306 } 307 308 public MetricSnapshotPacket getMostRecentMetricSnapshot(int lastId) { 309 return metricSnapshotStore.getMostRecentSnapshot(lastId); 310 } 311 312 protected int findUserMetricIndex(String name) { 313 Integer ans = (Integer )userMetricIndexMap.get(name); 314 if (ans == null) { 315 throw BindingSupportImpl.getInstance().invalidOperation( 316 "Unknown user-defined Metric: '" + name + "'"); 317 } 318 return ans.intValue(); 319 } 320 321 public void setUserMetric(String name, int value) { 322 userMetricValues[findUserMetricIndex(name)] = value; 323 } 324 325 public synchronized void incUserMetric(String name, int delta) { 326 userMetricValues[findUserMetricIndex(name)] += delta; 327 } 328 329 public int getUserMetric(String name) { 330 return userMetricValues[findUserMetricIndex(name)]; 331 } 332 333 public void addMetrics(List list) { 334 list.add(metricEvents); 335 list.add(metricLastEventId); 336 list.add(metricPMCreated); 337 list.add(metricPMClosed); 338 list.add(metricPMClosedAuto); 339 list.add(metricPMClosedAutoTx); 340 list.add(metricPMCount); 341 if (pmPool != null) { 342 pmPool.addMetrics(list); 343 } 344 if (smf instanceof HasMetrics) { 345 ((HasMetrics)smf).addMetrics(list); 346 } 347 if (userMetrics != null) { 348 list.addAll(Arrays.asList(userMetrics)); 349 } 350 } 351 352 public void sampleMetrics(int[][] buf, int pos) { 353 buf[metricEvents.getIndex()][pos] = pes.getEventsLogged(); 354 buf[metricLastEventId.getIndex()][pos] = LogEvent.getLastId(); 355 buf[metricPMCreated.getIndex()][pos] = pmCreatedCount; 356 buf[metricPMClosed.getIndex()][pos] = pmClosedCount; 357 buf[metricPMClosedAuto.getIndex()][pos] = pmClosedAutoCount; 358 buf[metricPMClosedAutoTx.getIndex()][pos] = pmClosedAutoTxCount; 359 buf[metricPMCount.getIndex()][pos] = activePMs.size(); 360 if (pmPool != null) { 361 pmPool.sampleMetrics(buf, pos); 362 } 363 if (smf instanceof HasMetrics) { 364 ((HasMetrics)smf).sampleMetrics(buf, pos); 365 } 366 if (userMetrics != null) { 367 for (int i = userMetrics.length - 1; i >= 0; i--) { 368 buf[userMetrics[i].getIndex()][pos] = userMetricValues[i]; 369 } 370 } 371 } 372 373 public Map getHyperdriveBytecode() { 374 return hyperdriveBytecode; 375 } 376 377 public int getHyperdriveBytecodeMaxSize() { 378 return hyperdriveBytecodeMaxSize; 379 } 380 381 public boolean isLocal() { 382 return true; 383 } 384 385 } 386 387 | Popular Tags |