Statistics
| Branch: | Tag: | Revision:

root / src / main / scala / gr / grnet / aquarium / actor / service / user / UserActor.scala @ 0a02ec0c

History | View | Annotate | Download (5.6 kB)

1
/*
2
 * Copyright 2011-2012 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.actor
37
package service
38
package user
39

    
40
import gr.grnet.aquarium.actor._
41

    
42
import gr.grnet.aquarium.util.shortClassNameOf
43
import message.config.{ActorProviderConfigured, AquariumPropertiesLoaded}
44
import akka.config.Supervision.Temporary
45
import gr.grnet.aquarium.Aquarium
46
import gr.grnet.aquarium.util.date.{TimeHelpers, MutableDateCalc}
47
import gr.grnet.aquarium.actor.message.event.{ProcessResourceEvent, ProcessIMEvent}
48
import gr.grnet.aquarium.actor.message.{GetUserStateResponse, GetUserBalanceResponse, GetUserStateRequest, GetUserBalanceRequest}
49
import gr.grnet.aquarium.computation.data.IMStateSnapshot
50
import gr.grnet.aquarium.computation.UserState
51
import gr.grnet.aquarium.event.model.im.IMEventModel
52

    
53
/**
54
 *
55
 * @author Christos KK Loverdos <loverdos@gmail.com>
56
 */
57

    
58
class UserActor extends ReflectiveRoleableActor {
59
  private[this] var _imState: IMStateSnapshot = _
60
  private[this] var _userState: UserState = _
61

    
62
  self.lifeCycle = Temporary
63

    
64
  private[this] def _userID = this._userState.userID
65
  private[this] def _shutmedown(): Unit = {
66
    if(_haveUserState) {
67
      UserActorCache.invalidate(_userID)
68
    }
69

    
70
    self.stop()
71
  }
72

    
73
  override protected def onThrowable(t: Throwable, message: AnyRef) = {
74
    logChainOfCauses(t)
75
    ERROR(t, "Terminating due to: %s(%s)", shortClassNameOf(t), t.getMessage)
76

    
77
    _shutmedown()
78
  }
79

    
80
  def role = UserActorRole
81

    
82
  private[this] def _configurator: Aquarium = Aquarium.Instance
83

    
84
  private[this] def _timestampTheshold =
85
    _configurator.props.getLong(Aquarium.Keys.user_state_timestamp_threshold).getOr(10000)
86

    
87

    
88
  private[this] def _haveUserState = {
89
    this._userState ne null
90
  }
91

    
92
  private[this] def _haveIMState = {
93
    this._imState ne null
94
  }
95

    
96
  def onAquariumPropertiesLoaded(event: AquariumPropertiesLoaded): Unit = {
97
  }
98

    
99
  def onActorProviderConfigured(event: ActorProviderConfigured): Unit = {
100
  }
101

    
102
  private[this] def _getAgreementNameForNewUser(imEvent: IMEventModel): String = {
103
    // FIXME: Implement based on the role
104
    "default"
105
  }
106

    
107
  /**
108
   * Process [[gr.grnet.aquarium.event.model.im.IMEventModel]]s.
109
   * When this method is called, we assume that all proper checks have been made and it
110
   * is OK to proceed with the event processing.
111
   */
112
  def onProcessIMEvent(processEvent: ProcessIMEvent): Unit = {
113
    val imEvent = processEvent.imEvent
114
    val hadIMState = _haveIMState
115

    
116
    if(hadIMState) {
117

    
118
      this._imState = this._imState.addMostRecentEvent(imEvent)
119
    } else {
120
      this._imState = IMStateSnapshot.initial(imEvent)
121
    }
122

    
123
    DEBUG("%s %s = %s", if(hadIMState) "Update" else "Set", shortClassNameOf(this._imState), this._imState)
124
  }
125

    
126
  def onGetUserBalanceRequest(event: GetUserBalanceRequest): Unit = {
127
    val userId = event.userID
128
    // FIXME: Implement
129
    self reply GetUserBalanceResponse(userId, Right(_userState.creditsSnapshot.creditAmount))
130
  }
131

    
132
  def onGetUserStateRequest(event: GetUserStateRequest): Unit = {
133
    val userId = event.userID
134
   // FIXME: Implement
135
    self reply GetUserStateResponse(userId, Right(this._userState))
136
  }
137

    
138
  def onProcessResourceEvent(event: ProcessResourceEvent): Unit = {
139
    val rcEvent = event.rcEvent
140

    
141
    logger.info("Got\n{}", rcEvent.toJsonString)
142
  }
143

    
144

    
145
  private[this] def D_userID = {
146
    if(this._userState eq null)
147
      if(this._imState eq null)
148
        "<NOT INITIALIZED>"
149
      else
150
        this._imState.imEvent.userID
151
    else
152
      this._userState.userID
153
  }
154

    
155
  private[this] def DEBUG(fmt: String, args: Any*) =
156
    logger.debug("UserActor[%s]: %s".format(D_userID, fmt.format(args: _*)))
157

    
158
  private[this] def INFO(fmt: String, args: Any*) =
159
    logger.info("UserActor[%s]: %s".format(D_userID, fmt.format(args: _*)))
160

    
161
  private[this] def WARN(fmt: String, args: Any*) =
162
    logger.warn("UserActor[%s]: %s".format(D_userID, fmt.format(args: _*)))
163

    
164
  private[this] def ERROR(fmt: String, args: Any*) =
165
    logger.error("UserActor[%s]: %s".format(D_userID, fmt.format(args: _*)))
166

    
167
  private[this] def ERROR(t: Throwable, fmt: String, args: Any*) =
168
    logger.error("UserActor[%s]: %s".format(D_userID, fmt.format(args: _*)), t)
169
}