Flat project hierarchy
[aquarium] / src / main / scala / gr / grnet / aquarium / util / RandomEventGenerator.scala
1 /*
2  * Copyright 2011 GRNET S.A. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or
5  * without modification, are permitted provided that the following
6  * conditions are met:
7  *
8  *   1. Redistributions of source code must retain the above
9  *      copyright notice, this list of conditions and the following
10  *      disclaimer.
11  *
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.
16  *
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.
29  *
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.
34  */
35
36 package gr.grnet.aquarium.util
37
38 import akka.amqp._
39 import gr.grnet.aquarium.messaging.AkkaAMQP
40 import util.Random
41 import gr.grnet.aquarium.logic.events.{UserEvent, ResourceEvent}
42 import java.security.MessageDigest
43
44 /**
45  *  Generates random resource events to use as input for testing and
46  *  injects them to the specified exchange.
47  *
48  * @author Georgios Gousios <gousiosg@gmail.com>
49  */
50 trait RandomEventGenerator extends AkkaAMQP {
51
52   val userIds = 1 to 100
53   val clientIds = 1 to 4
54   val vmIds = 1 to 4000
55   val resources = List("vmtime", "bndup", "bnddown", "dsksp")
56   val tsFrom = 1293840000000L //1/1/2011 0:00:00 GMT
57   val tsTo = 1325376000000L   //1/1/2012 0:00:00 GMT
58   val eventVersion = 1 to 4
59
60   private val seed = 0xdeadbeef
61   private lazy val rnd = new Random(seed)
62
63   /**
64    * Generate a random resource event
65    */
66   def nextUserEvent(): UserEvent = {
67     val md = MessageDigest.getInstance("SHA-1");
68     md.update(rnd.nextString(30).getBytes)
69
70     val sha1 = md.toString
71     val ts = tsFrom + (scala.math.random * ((tsTo - tsFrom) + 1)).asInstanceOf[Long]
72     val id = userIds.apply(rnd.nextInt(100))
73     val event = Array("ACTIVE", "SUSPENDED").apply(rnd.nextInt(2))
74     val idp = Array("LOCAL", "SHIBBOLETH", "OPENID").apply(rnd.nextInt(3))
75     val tenant = Array("TENTANT1", "TENANT2").apply(rnd.nextInt(2))
76     val role = Array("ADMIN", "NORMAL").apply(rnd.nextInt(2))
77
78     UserEvent(sha1, ts, id.toString, 1, 2, event, idp, tenant, Array(role))
79   }
80
81   /**
82    * Generate a random resource event
83    */
84   def genPublishUserEvents(num: Int) = {
85     val publisher = producer("im")
86
87     (1 to num).foreach {
88       n =>
89         var event = nextUserEvent()
90         publisher ! Message(event.toBytes, "")
91     }
92   }
93
94   /**
95    * Generete and publish create events for test users
96    */
97   def initUsers = {
98     val publisher = producer("im")
99
100     userIds.foreach {
101       i =>
102         val md = MessageDigest.getInstance("SHA-1");
103         val ts = tsFrom + (scala.math.random * ((tsTo - tsFrom) + 1)).asInstanceOf[Long]
104         md.update(rnd.nextString(30).getBytes)
105         val sha1 = md.toString
106         val user = UserEvent(sha1, ts, i.toString, 1, 1, "ACTIVE", "LOCAL", "TENTANT1", Array("NORMAL"))
107         publisher ! Message(user.toBytes, "user.%s".format("CREATED"))
108     }
109   }
110
111   /**
112    * Get the next random resource event
113    */
114   def nextResourceEvent() : ResourceEvent = {
115     val res = rnd.shuffle(resources).head
116
117     val extra = res match {
118       case "vmtime" => Map("vmid" -> rnd.nextInt(vmIds.max).toString)
119       case _ => Map[String, String]()
120     }
121
122     val ts = tsFrom + (scala.math.random * ((tsTo - tsFrom) + 1)).asInstanceOf[Long]
123
124     ResourceEvent(
125       rnd.nextString(35),
126       rnd.nextInt(userIds.max),
127       rnd.nextInt(clientIds.max).toString,
128       res,ts,1.toString,extra)
129   }
130
131   /**
132    * Generate resource events and publish them to the queue
133    */
134   def genPublishResEvents(num: Int) = {
135
136     assert(num > 0)
137     val publisher = producer("aquarium")
138
139     (1 to num).foreach {
140       n =>
141         var event = nextResourceEvent
142         publisher ! Message(event.toBytes,
143           "resevent.%d.%s".format(event.clientId, event.resource))
144     }
145   }
146 }
147
148 object RandomEventGen extends RandomEventGenerator {
149
150   def main(args: Array[String]): Unit = {
151
152     var num = 100
153
154     if (args.size > 0)
155       num = args.head.toInt
156
157     println("Publishing %d messages. Hit Ctrl+c to stop".format(num))
158
159     genPublishResEvents(num)
160   }
161 }