Statistics
| Branch: | Tag: | Revision:

root / src / main / scala / gr / grnet / aquarium / user / simulation / ClientServiceSim.scala @ 491934d4

History | View | Annotate | Download (8.9 kB)

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
package gr.grnet.aquarium.user.simulation
36

    
37
import gr.grnet.aquarium.util.date.DateCalculator
38
import gr.grnet.aquarium.logic.events.ResourceEvent
39
import java.util.Date
40
import gr.grnet.aquarium.logic.accounting.dsl.OnOffCostPolicyValues
41
import gr.grnet.aquarium.store.memory.MemStore
42
import com.ckkloverdos.maybe.Maybe
43
import gr.grnet.aquarium.store.RecordID
44

    
45
/**
46
 * A simulator for an Aquarium client service, which is an event generator.
47
 *
48
 * @author Christos KK Loverdos <loverdos@gmail.com>
49
 */
50

    
51
case class ClientServiceSim(clientId: String)(implicit uidGen: UIDGenerator) {
52
  private[this] val UserProto      = UserSim("", new Date(0), new MemStore().resourceEventStore)
53
  private[this] val VMTimeProto    = VMTimeSim(UserProto, "")
54
  private[this] val DiskspaceProto = DiskspaceSim(UserProto, "")
55
  private[this] val BandwidthProto = BandwidthSim(UserProto, "")
56

    
57
  private[this] var _resources = List[ResourceSim]()
58

    
59
  sealed abstract class ResourceSim(_resource: String, val owner: UserSim, val instanceId: String = "") {
60
    def resource = _resource
61
  }
62

    
63
  case class VMTimeSim(override val owner: UserSim,
64
                       override val instanceId: String = "")
65
  extends ResourceSim("vmtime", owner, instanceId) {
66

    
67
    def newON(occurredDate: Date): Maybe[RecordID] = {
68
      val id = uidGen.nextUID()
69
      val time = occurredDate.getTime
70
      val occurredTime = time
71
      val receivedTime = time
72
      val event = ResourceEvent(
73
        id,
74
        occurredTime,
75
        receivedTime,
76
        owner.userId,
77
        clientId,
78
        resource,
79
        instanceId,
80
        "1.0",
81
        OnOffCostPolicyValues.ON,
82
        Map())
83

    
84
      owner._addResourceEvent(event)
85
    }
86

    
87
    def newON_OutOfSync(occuredDate: Date, outOfSyncHours: Int): Maybe[RecordID] = {
88
      val id = uidGen.nextUID()
89
      val occurredDateCalc = new DateCalculator(occuredDate)
90
      val occurredTime = occurredDateCalc.toMillis
91
      val receivedTime = occurredDateCalc.goPlusHours(outOfSyncHours).toMillis
92

    
93
      val event = ResourceEvent(
94
        id,
95
        occurredTime,
96
        receivedTime,
97
        owner.userId,
98
        clientId,
99
        resource,
100
        instanceId,
101
        "1.0",
102
        OnOffCostPolicyValues.ON,
103
        Map())
104

    
105
      owner._addResourceEvent(event)
106
    }
107

    
108
    def newOFF(occurredDate: Date): Maybe[RecordID] = {
109
      val id = uidGen.nextUID()
110
      val time = occurredDate.getTime
111
      val occurredTime = time
112
      val receivedTime = time
113
      val event = ResourceEvent(
114
        id,
115
        occurredTime,
116
        receivedTime,
117
        owner.userId,
118
        clientId,
119
        resource,
120
        instanceId,
121
        "1.0",
122
        OnOffCostPolicyValues.OFF,
123
        Map())
124

    
125
      owner._addResourceEvent(event)
126
    }
127

    
128
    def newOFF_OutOfSync(occuredDate: Date, outOfSyncHours: Int): Maybe[RecordID] = {
129
      val id = uidGen.nextUID()
130
      val occurredDateCalc = new DateCalculator(occuredDate)
131
      val occurredTime = occurredDateCalc.toMillis
132
      val receivedTime = occurredDateCalc.goPlusHours(outOfSyncHours).toMillis
133

    
134
      val event = ResourceEvent(
135
        id,
136
        occurredTime,
137
        receivedTime,
138
        owner.userId,
139
        clientId,
140
        resource,
141
        instanceId,
142
        "1.0",
143
        OnOffCostPolicyValues.OFF,
144
        Map())
145

    
146
      owner._addResourceEvent(event)
147
    }
148

    
149
    def newONOFF(occurredDateForON: Date, totalVMTimeInHours: Int): (Maybe[RecordID], Maybe[RecordID]) = {
150
      val onID = newON(occurredDateForON)
151
      val offDate = new DateCalculator(occurredDateForON).goPlusHours(totalVMTimeInHours).toDate
152
      val offID = newOFF(offDate)
153

    
154
      (onID, offID)
155
    }
156

    
157
    def newONOFF_OutOfSync(occurredDateForON: Date,
158
                           totalVMTimeInHours: Int,
159
                           outOfSyncONHours: Int,
160
                           outOfSyncOFFHours: Int): (Maybe[RecordID], Maybe[RecordID]) = {
161
      val onID = newON_OutOfSync(occurredDateForON, outOfSyncONHours)
162
      val occurredDateCalcForOFF = new DateCalculator(occurredDateForON).goPlusHours(totalVMTimeInHours)
163
      val occurredDateForOFF = occurredDateCalcForOFF.toDate
164
      val offID = newOFF_OutOfSync(occurredDateForOFF, outOfSyncOFFHours)
165

    
166
      (onID, offID)
167
    }
168
  }
169

    
170
  case class BandwidthSim(override val owner: UserSim,
171
                          override val instanceId: String = "") extends ResourceSim("bandwidth", owner, instanceId) {
172

    
173
    def useBandwidth(occurredDate: Date, megaBytes: Double): Maybe[RecordID] = {
174
      val id = uidGen.nextUID()
175
      val time = occurredDate.getTime
176
      val event = ResourceEvent(
177
        id,
178
        time,
179
        time,
180
        owner.userId,
181
        clientId,
182
        resource,
183
        instanceId,
184
        "1.0",
185
        megaBytes,
186
        Map()
187
      )
188

    
189
      owner._addResourceEvent(event)
190
    }
191
  }
192

    
193
  case class DiskspaceSim(override val owner: UserSim,
194
                          override val instanceId: String = "") extends ResourceSim("diskspace", owner, instanceId) {
195

    
196
    def consumeMB(occurredDate: Date, megaBytes: Double): Maybe[RecordID] = {
197
      val id = uidGen.nextUID()
198
      val time = occurredDate.getTime
199
      val event = ResourceEvent(
200
        id,
201
        time,
202
        time,
203
        owner.userId,
204
        clientId,
205
        resource,
206
        instanceId,
207
        "1.0",
208
        megaBytes,
209
        Map()
210
      )
211

    
212
      owner._addResourceEvent(event)
213
    }
214
    
215
    def freeMB(occurredDate: Date, megaBytes: Double): Maybe[RecordID] = {
216
      consumeMB(occurredDate, -megaBytes)
217
    }
218

    
219
    def consumeMB_OutOfSync(occurredDate: Date, outOfSyncHours: Int, megaBytes: Double): Maybe[RecordID] = {
220
      val id = uidGen.nextUID()
221
      val occurredDateCalc = new DateCalculator(occurredDate)
222
      val occurredTime = occurredDateCalc.toMillis
223
      val receivedTime = occurredDateCalc.goPlusHours(outOfSyncHours).toMillis
224

    
225
      val event = ResourceEvent(
226
        id,
227
        occurredTime,
228
        receivedTime,
229
        owner.userId,
230
        clientId,
231
        resource,
232
        instanceId,
233
        "1.0",
234
        megaBytes,
235
        Map()
236
      )
237

    
238
      owner._addResourceEvent(event)
239
    }
240

    
241
    def freeMB_OutOfSync(occurredDate: Date, outOfSyncHours: Int, megaBytes: Double): Maybe[RecordID] = {
242
      consumeMB_OutOfSync(occurredDate, outOfSyncHours, -megaBytes)
243
    }
244
  }
245

    
246
  private[simulation]
247
  def _addVMTime(vmtime: VMTimeSim): VMTimeSim = {
248
    _resources = vmtime :: _resources
249
    vmtime
250
  }
251

    
252
  private[simulation]
253
  def _addDiskspace(diskspace: DiskspaceSim): DiskspaceSim = {
254
    _resources = diskspace :: _resources
255
    diskspace
256
  }
257

    
258
  private[simulation]
259
  def _addBandwidth(bandwidth: BandwidthSim): BandwidthSim = {
260
    _resources = bandwidth :: _resources
261
    bandwidth
262
  }
263

    
264
  def qualifyResource(resource: String, instanceId: String) = {
265
    "%s/%s/%s".format(clientId, resource, instanceId)
266
  }
267

    
268
  def newVMTime(owner: UserSim, _instanceId: String): VMTimeSim = {
269
    owner._addServiceClient(this)
270
    _addVMTime(VMTimeSim(owner, this.qualifyResource(VMTimeProto.resource, _instanceId)))
271
  }
272

    
273
  def newDiskspace(owner: UserSim, _instanceId: String): DiskspaceSim = {
274
    owner._addServiceClient(this)
275
    _addDiskspace(DiskspaceSim(owner, this.qualifyResource(DiskspaceProto.resource, _instanceId)))
276
  }
277

    
278
  def newBandwidth(owner: UserSim, _instanceId: String): BandwidthSim = {
279
    owner._addServiceClient(this)
280
    _addBandwidth(BandwidthSim(owner, this.qualifyResource(BandwidthProto.resource, _instanceId)))
281
  }
282

    
283
  def myResources: List[ResourceSim] = _resources
284
}