2 * Copyright 2011-2012 GRNET S.A. All rights reserved.
4 * Redistribution and use in source and binary forms, with or
5 * without modification, are permitted provided that the following
8 * 1. Redistributions of source code must retain the above
9 * copyright notice, this list of conditions and the following
12 * 2. Redistributions in binary form must reproduce the above
13 * copyright notice, this list of conditions and the following
14 * disclaimer in the documentation and/or other materials
15 * provided with the distribution.
17 * THIS SOFTWARE IS PROVIDED BY GRNET S.A. ``AS IS'' AND ANY EXPRESS
18 * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
19 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
20 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GRNET S.A OR
21 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
22 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
23 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
24 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
25 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
26 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
27 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
28 * POSSIBILITY OF SUCH DAMAGE.
30 * The views and conclusions contained in the software and
31 * documentation are those of the authors and should not be
32 * interpreted as representing official policies, either expressed
33 * or implied, of GRNET S.A.
36 package gr.grnet.aquarium.store
38 import gr.grnet.aquarium.Configurator
39 import java.io.{FileOutputStream, File}
40 import gr.grnet.aquarium.util.{Loggable, stringOfStackTrace}
41 import gr.grnet.aquarium.util.date.{TimeHelpers, MutableDateCalc}
42 import gr.grnet.aquarium.uid.{EAIOUUIDGenerator, UIDGenerator}
43 import gr.grnet.aquarium.event.ResourceEvent
44 import gr.grnet.aquarium.event.im.IMEventModel
47 * This is used whenever the property `events.store.folder` is setup in aquarium configuration.
49 * @author Christos KK Loverdos <loverdos@gmail.com>
52 object LocalFSEventStore extends Loggable {
53 private[this] final val UIDGen: UIDGenerator[_] = EAIOUUIDGenerator
54 private[this] final val NewLine = "\n".getBytes("UTF-8")
55 private[this] final val NewLine2 = NewLine ++ NewLine
57 private[this] def writeToFile(file: File, data: Array[Byte], appendString: Option[String] = None): Unit = {
58 val out = new FileOutputStream(file)
63 out.write(s.getBytes("UTF-8"))
69 logger.debug("Wrote to file {}", file.getCanonicalPath)
72 private[this] def createResourceEventsFolder(root: File): File = {
73 val folder = new File(root, "rc")
78 private[this] def createIMEventsFolder(root: File): File = {
79 val folder = new File(root, "im")
84 private[this] def writeJson(tag: String,
86 jsonPayload: Array[Byte],
87 occurredString: String,
89 extraName: Option[String],
91 appendString: Option[String] = None): Unit = {
94 "%s-%s%s.%s.%s.json".format(
98 case Some(s) ⇒ "-" + s
102 if(isParsed) "p" else "u"
105 writeToFile(file, jsonPayload, appendString)
108 def storeUnparsedResourceEvent(mc: Configurator, initialPayload: Array[Byte], exception: Throwable): Unit = {
109 for(root <- mc.eventsStoreFolder) {
110 val uid = UIDGen.nextUID()
111 val occurredMDC = new MutableDateCalc(TimeHelpers.nowMillis())
112 val occurredString = occurredMDC.toFilename_YYYYMMDDHHMMSSSSS
113 val rcEventsFolder = createResourceEventsFolder(root)
114 val trace = stringOfStackTrace(exception)
116 writeJson("rc", rcEventsFolder, initialPayload, occurredString, uid, None, false, Some(trace))
120 def storeResourceEvent(mc: Configurator, event: ResourceEvent, initialPayload: Array[Byte]): Unit = {
121 require(event ne null, "Resource event must be not null")
123 for(root <- mc.eventsStoreFolder) {
124 val uid = UIDGen.nextUID()
126 val occurredMDC = new MutableDateCalc(event.occurredMillis)
127 val occurredString = occurredMDC.toFilename_YYYYMMDDHHMMSSSSS
128 val rcEventsFolder = createResourceEventsFolder(root)
137 Some("[%s]-[%s]-[%s]-[%s]".format(
147 def storeUnparsedIMEvent(mc: Configurator, initialPayload: Array[Byte], exception: Throwable): Unit = {
148 for(root <- mc.eventsStoreFolder) {
149 val uid = UIDGen.nextUID()
150 val occurredMDC = new MutableDateCalc(TimeHelpers.nowMillis())
151 val occurredString = occurredMDC.toFilename_YYYYMMDDHHMMSSSSS
152 val imEventsFolder = createIMEventsFolder(root)
153 val trace = stringOfStackTrace(exception)
155 writeJson("im", imEventsFolder, initialPayload, occurredString, uid, None, false, Some(trace))
159 def storeIMEvent(mc: Configurator, event: IMEventModel, initialPayload: Array[Byte]): Unit = {
160 require(event ne null, "IM event must be not null")
161 for(root <- mc.eventsStoreFolder) {
162 val uid = UIDGen.nextUID()
164 val occurredMDC = new MutableDateCalc(event.occurredMillis)
165 val occurredString = occurredMDC.toFilename_YYYYMMDDHHMMSSSSS
166 val imEventsFolder = createIMEventsFolder(root)
174 Some("[%s]-[%s]".format(event.id, event.userID)),