From: Christos KK Loverdos Date: Fri, 25 May 2012 14:25:08 +0000 (+0300) Subject: Work in progress on handling user state X-Git-Url: https://code.grnet.gr/git/aquarium/commitdiff_plain/66cf54af4784a412d592e60be05c8800888508bf Work in progress on handling user state I just committed everything. Not sure what will survive yet. --- diff --git a/src/main/scala/gr/grnet/aquarium/actor/service/user/UserActor.scala b/src/main/scala/gr/grnet/aquarium/actor/service/user/UserActor.scala index 56f2695..f6b96c3 100644 --- a/src/main/scala/gr/grnet/aquarium/actor/service/user/UserActor.scala +++ b/src/main/scala/gr/grnet/aquarium/actor/service/user/UserActor.scala @@ -39,14 +39,12 @@ package user import gr.grnet.aquarium.actor._ -import gr.grnet.aquarium.util.shortClassNameOf import akka.config.Supervision.Temporary import gr.grnet.aquarium.Aquarium import gr.grnet.aquarium.actor.message.event.{ProcessResourceEvent, ProcessIMEvent} import gr.grnet.aquarium.actor.message.{GetUserStateRequest, GetUserBalanceRequest} import gr.grnet.aquarium.computation.data.IMStateSnapshot import gr.grnet.aquarium.event.model.im.IMEventModel -import gr.grnet.aquarium.computation.NewUserState import gr.grnet.aquarium.actor.message.config.{InitializeUserState, ActorProviderConfigured, AquariumPropertiesLoaded} /** diff --git a/src/main/scala/gr/grnet/aquarium/computation/NewUserState.scala b/src/main/scala/gr/grnet/aquarium/computation/NewUserState.scala new file mode 100644 index 0000000..29f0a8e --- /dev/null +++ b/src/main/scala/gr/grnet/aquarium/computation/NewUserState.scala @@ -0,0 +1,83 @@ +/* + * Copyright 2011-2012 GRNET S.A. All rights reserved. + * + * Redistribution and use in source and binary forms, with or + * without modification, are permitted provided that the following + * conditions are met: + * + * 1. Redistributions of source code must retain the above + * copyright notice, this list of conditions and the following + * disclaimer. + * + * 2. Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY GRNET S.A. ``AS IS'' AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GRNET S.A OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and + * documentation are those of the authors and should not be + * interpreted as representing official policies, either expressed + * or implied, of GRNET S.A. + */ + +package gr.grnet.aquarium.computation + +import gr.grnet.aquarium.computation.data.{AgreementHistory, RoleHistory, AgreementHistoryItem} +import gr.grnet.aquarium.converter.{JsonTextFormat, StdConverters} + + +/** + * + * @author Christos KK Loverdos + */ + +case class NewUserState( + isInitial: Boolean, + userID: String, + userCreationMillis: Long, + stateReferenceMillis: Long, // The time this state refers to + totalCredits: Double, + roleHistory: RoleHistory, + agreementHistory: AgreementHistory +) + +object NewUserState { + def fromJson(json: String): NewUserState = { + StdConverters.AllConverters.convertEx[NewUserState](JsonTextFormat(json)) + } + + object JsonNames { + final val _id = "_id" + final val userID = "userID" + } + + def createInitialUserState(userID: String, + credits: Double, + isActive: Boolean, + role: String, + agreement: String, + userCreationMillis: Long): NewUserState = { + NewUserState( + true, + userID, + userCreationMillis, + userCreationMillis, + credits, + RoleHistory.initial(role, userCreationMillis), + AgreementHistory.initial(agreement, userCreationMillis) + ) + } +} \ No newline at end of file diff --git a/src/main/scala/gr/grnet/aquarium/computation/UserState.scala b/src/main/scala/gr/grnet/aquarium/computation/UserState.scala index 57318e7..eee1c1d 100644 --- a/src/main/scala/gr/grnet/aquarium/computation/UserState.scala +++ b/src/main/scala/gr/grnet/aquarium/computation/UserState.scala @@ -43,8 +43,8 @@ import gr.grnet.aquarium.event.model.{WalletEntry, NewWalletEntry} import gr.grnet.aquarium.util.json.JsonSupport import gr.grnet.aquarium.logic.accounting.dsl.DSLAgreement import gr.grnet.aquarium.computation.reason.{NoSpecificChangeReason, UserStateChangeReason, InitialUserStateSetup, IMEventArrival} -import gr.grnet.aquarium.computation.data.{AgreementSnapshot, ResourceInstanceSnapshot, OwnedResourcesSnapshot, AgreementsSnapshot, CreditSnapshot, LatestResourceEventsSnapshot, ImplicitlyIssuedResourceEventsSnapshot, IMStateSnapshot} import gr.grnet.aquarium.event.model.im.{StdIMEvent, IMEventModel} +import gr.grnet.aquarium.computation.data.{RoleHistory, AgreementHistoryItem, ResourceInstanceSnapshot, OwnedResourcesSnapshot, AgreementHistory, CreditSnapshot, LatestResourceEventsSnapshot, ImplicitlyIssuedResourceEventsSnapshot, IMStateSnapshot} /** * A comprehensive representation of the User's state. @@ -157,7 +157,7 @@ case class UserState( billingPeriodOutOfSyncResourceEventsCounter: Long, imStateSnapshot: IMStateSnapshot, creditsSnapshot: CreditSnapshot, - agreementsSnapshot: AgreementsSnapshot, + agreementsSnapshot: AgreementHistory, ownedResourcesSnapshot: OwnedResourcesSnapshot, newWalletEntries: List[NewWalletEntry], occurredMillis: Long, // The time fro which this state is relevant @@ -209,14 +209,14 @@ case class UserState( def resourcesMap = ownedResourcesSnapshot.toResourcesMap - def modifyFromIMEvent(imEvent: IMEventModel, snapshotMillis: Long): UserState = { - this.copy( - isInitial = false, - imStateSnapshot = IMStateSnapshot(imEvent), - lastChangeReason = IMEventArrival(imEvent), - occurredMillis = snapshotMillis - ) - } +// def modifyFromIMEvent(imEvent: IMEventModel, snapshotMillis: Long): UserState = { +// this.copy( +// isInitial = false, +// imStateSnapshot = imStateSnapshot.addMostRecentEvent(imEvent), +// lastChangeReason = IMEventArrival(imEvent), +// occurredMillis = snapshotMillis +// ) +// } // def toShortString = "UserState(%s, %s, %s, %s, %s)".format( // userId, @@ -258,9 +258,9 @@ object UserState { LatestResourceEventsSnapshot(List()), 0L, 0L, - IMStateSnapshot(imEvent), + IMStateSnapshot(true, imEvent, RoleHistory.Empty), CreditSnapshot(credits), - AgreementsSnapshot(List(AgreementSnapshot(agreementName, userCreationMillis))), + AgreementHistory(List(AgreementHistoryItem(agreementName, userCreationMillis))), OwnedResourcesSnapshot(Nil), Nil, userCreationMillis, @@ -290,16 +290,18 @@ object UserState { 0L, 0L, IMStateSnapshot( + true, StdIMEvent( "", now, now, userID, "", isActive, roleNames.headOption.getOrElse("default"), "1.0", - IMEventModel.EventTypeNames.create, Map()) + IMEventModel.EventTypeNames.create, Map()), + RoleHistory.Empty ), CreditSnapshot(credits), - AgreementsSnapshot(List(AgreementSnapshot(agreementName, userCreationMillis))), + AgreementHistory(List(AgreementHistoryItem(agreementName, userCreationMillis))), OwnedResourcesSnapshot(Nil), Nil, now, @@ -309,7 +311,7 @@ object UserState { def createInitialUserStateFrom(us: UserState): UserState = { createInitialUserState( - us.imStateSnapshot.imEvent, + us.imStateSnapshot.latestIMEvent, us.creditsSnapshot.creditAmount, us.agreementsSnapshot.agreementsByTimeslot.valuesIterator.toList.last) } diff --git a/src/main/scala/gr/grnet/aquarium/util/ContextualLogger.scala b/src/main/scala/gr/grnet/aquarium/util/ContextualLogger.scala index d57a9b2..3d71eae 100644 --- a/src/main/scala/gr/grnet/aquarium/util/ContextualLogger.scala +++ b/src/main/scala/gr/grnet/aquarium/util/ContextualLogger.scala @@ -61,16 +61,16 @@ DEBUG 17:50:19 g.g.a.user.UserStateComputationsTest - …ndUserStateAtEndOfBilli DEBUG 17:50:19 g.g.a.user.UserStateComputationsTest - doFullMonthlyBilling(2011-11) BEGIN DEBUG 17:50:19 g.g.a.user.UserStateComputationsTest - …ndUserStateAtEndOfBillingMonth(2011-10) BEGIN DEBUG 17:50:19 g.g.a.user.UserStateComputationsTest - …ndUserStateAtEndOfBillingMonth(2011-10) User did not exist before 2011-11-01 00:00:00.000 -DEBUG 17:50:19 g.g.a.user.UserStateComputationsTest - …ndUserStateAtEndOfBillingMonth(2011-10) Returning INITIAL state [_id=4fa7e12ba0eee3db73fbe8d0] UserState(true,CKKL,1320098400000,0,false,null,ImplicitlyIssuedResourceEventsSnapshot(List()),List(),List(),LatestResourceEventsSnapshot(List()),0,0,IMStateSnapshot(StdIMEvent(,1320098400000,1320098400000,CKKL,,true,user,1.0,create,Map())),CreditSnapshot(0.0),AgreementsSnapshot(List(AgreementSnapshot(default, 2011-11-01 00:00:00.000, 292278994-08-17 07:12:55.807))),OwnedResourcesSnapshot(List()),List(),1320098400000,InitialUserStateSetup,0,None,4fa7e12ba0eee3db73fbe8d0) +DEBUG 17:50:19 g.g.a.user.UserStateComputationsTest - …ndUserStateAtEndOfBillingMonth(2011-10) Returning INITIAL state [_id=4fa7e12ba0eee3db73fbe8d0] UserState(true,CKKL,1320098400000,0,false,null,ImplicitlyIssuedResourceEventsSnapshot(List()),List(),List(),LatestResourceEventsSnapshot(List()),0,0,IMStateSnapshot(StdIMEvent(,1320098400000,1320098400000,CKKL,,true,user,1.0,create,Map())),CreditSnapshot(0.0),AgreementHistory(List(AgreementHistoryItem(default, 2011-11-01 00:00:00.000, 292278994-08-17 07:12:55.807))),OwnedResourcesSnapshot(List()),List(),1320098400000,InitialUserStateSetup,0,None,4fa7e12ba0eee3db73fbe8d0) DEBUG 17:50:19 g.g.a.user.UserStateComputationsTest - …ndUserStateAtEndOfBillingMonth(2011-10) END DEBUG 17:50:19 g.g.a.user.UserStateComputationsTest - doFullMonthlyBilling(2011-11) calculationReason = MonthlyBillingCalculation(2011-11) -DEBUG 17:50:19 g.g.a.user.UserStateComputationsTest - doFullMonthlyBilling(2011-11) Saved [_id=4fa7e12ba0eee3db73fbe8d0] UserState(true,CKKL,1320098400000,1,false,null,ImplicitlyIssuedResourceEventsSnapshot(List()),List(),List(),LatestResourceEventsSnapshot(List()),0,0,IMStateSnapshot(StdIMEvent(,1320098400000,1320098400000,CKKL,,true,user,1.0,create,Map())),CreditSnapshot(0.0),AgreementsSnapshot(List(AgreementSnapshot(default, 2011-11-01 00:00:00.000, 292278994-08-17 07:12:55.807))),OwnedResourcesSnapshot(List()),List(),1320098400000,MonthlyBillingCalculation(2011-11),0,Some(4fa7e12ba0eee3db73fbe8d0),4fa7e12ba0eee3db73fbe8d0) -DEBUG 17:50:19 g.g.a.user.UserStateComputationsTest - doFullMonthlyBilling(2011-11) RETURN UserState(true,CKKL,1320098400000,1,false,null,ImplicitlyIssuedResourceEventsSnapshot(List()),List(),List(),LatestResourceEventsSnapshot(List()),0,0,IMStateSnapshot(StdIMEvent(,1320098400000,1320098400000,CKKL,,true,user,1.0,create,Map())),CreditSnapshot(0.0),AgreementsSnapshot(List(AgreementSnapshot(default, 2011-11-01 00:00:00.000, 292278994-08-17 07:12:55.807))),OwnedResourcesSnapshot(List()),List(),1320098400000,MonthlyBillingCalculation(2011-11),0,Some(4fa7e12ba0eee3db73fbe8d0),4fa7e12ba0eee3db73fbe8d0) +DEBUG 17:50:19 g.g.a.user.UserStateComputationsTest - doFullMonthlyBilling(2011-11) Saved [_id=4fa7e12ba0eee3db73fbe8d0] UserState(true,CKKL,1320098400000,1,false,null,ImplicitlyIssuedResourceEventsSnapshot(List()),List(),List(),LatestResourceEventsSnapshot(List()),0,0,IMStateSnapshot(StdIMEvent(,1320098400000,1320098400000,CKKL,,true,user,1.0,create,Map())),CreditSnapshot(0.0),AgreementHistory(List(AgreementHistoryItem(default, 2011-11-01 00:00:00.000, 292278994-08-17 07:12:55.807))),OwnedResourcesSnapshot(List()),List(),1320098400000,MonthlyBillingCalculation(2011-11),0,Some(4fa7e12ba0eee3db73fbe8d0),4fa7e12ba0eee3db73fbe8d0) +DEBUG 17:50:19 g.g.a.user.UserStateComputationsTest - doFullMonthlyBilling(2011-11) RETURN UserState(true,CKKL,1320098400000,1,false,null,ImplicitlyIssuedResourceEventsSnapshot(List()),List(),List(),LatestResourceEventsSnapshot(List()),0,0,IMStateSnapshot(StdIMEvent(,1320098400000,1320098400000,CKKL,,true,user,1.0,create,Map())),CreditSnapshot(0.0),AgreementHistory(List(AgreementHistoryItem(default, 2011-11-01 00:00:00.000, 292278994-08-17 07:12:55.807))),OwnedResourcesSnapshot(List()),List(),1320098400000,MonthlyBillingCalculation(2011-11),0,Some(4fa7e12ba0eee3db73fbe8d0),4fa7e12ba0eee3db73fbe8d0) DEBUG 17:50:19 g.g.a.user.UserStateComputationsTest - doFullMonthlyBilling(2011-11) END DEBUG 17:50:19 g.g.a.user.UserStateComputationsTest - …ndUserStateAtEndOfBillingMonth(2011-11) END DEBUG 17:50:19 g.g.a.user.UserStateComputationsTest - doFullMonthlyBilling(2011-12) calculationReason = MonthlyBillingCalculation(2011-12) -DEBUG 17:50:19 g.g.a.user.UserStateComputationsTest - doFullMonthlyBilling(2011-12) Saved [_id=4fa7e12ba0eee3db73fbe8d0] UserState(true,CKKL,1320098400000,2,false,null,ImplicitlyIssuedResourceEventsSnapshot(List()),List(),List(),LatestResourceEventsSnapshot(List()),0,0,IMStateSnapshot(StdIMEvent(,1320098400000,1320098400000,CKKL,,true,user,1.0,create,Map())),CreditSnapshot(0.0),AgreementsSnapshot(List(AgreementSnapshot(default, 2011-11-01 00:00:00.000, 292278994-08-17 07:12:55.807))),OwnedResourcesSnapshot(List()),List(),1320098400000,MonthlyBillingCalculation(2011-12),0,Some(4fa7e12ba0eee3db73fbe8d0),4fa7e12ba0eee3db73fbe8d0) -DEBUG 17:50:19 g.g.a.user.UserStateComputationsTest - doFullMonthlyBilling(2011-12) RETURN UserState(true,CKKL,1320098400000,2,false,null,ImplicitlyIssuedResourceEventsSnapshot(List()),List(),List(),LatestResourceEventsSnapshot(List()),0,0,IMStateSnapshot(StdIMEvent(,1320098400000,1320098400000,CKKL,,true,user,1.0,create,Map())),CreditSnapshot(0.0),AgreementsSnapshot(List(AgreementSnapshot(default, 2011-11-01 00:00:00.000, 292278994-08-17 07:12:55.807))),OwnedResourcesSnapshot(List()),List(),1320098400000,MonthlyBillingCalculation(2011-12),0,Some(4fa7e12ba0eee3db73fbe8d0),4fa7e12ba0eee3db73fbe8d0) +DEBUG 17:50:19 g.g.a.user.UserStateComputationsTest - doFullMonthlyBilling(2011-12) Saved [_id=4fa7e12ba0eee3db73fbe8d0] UserState(true,CKKL,1320098400000,2,false,null,ImplicitlyIssuedResourceEventsSnapshot(List()),List(),List(),LatestResourceEventsSnapshot(List()),0,0,IMStateSnapshot(StdIMEvent(,1320098400000,1320098400000,CKKL,,true,user,1.0,create,Map())),CreditSnapshot(0.0),AgreementHistory(List(AgreementHistoryItem(default, 2011-11-01 00:00:00.000, 292278994-08-17 07:12:55.807))),OwnedResourcesSnapshot(List()),List(),1320098400000,MonthlyBillingCalculation(2011-12),0,Some(4fa7e12ba0eee3db73fbe8d0),4fa7e12ba0eee3db73fbe8d0) +DEBUG 17:50:19 g.g.a.user.UserStateComputationsTest - doFullMonthlyBilling(2011-12) RETURN UserState(true,CKKL,1320098400000,2,false,null,ImplicitlyIssuedResourceEventsSnapshot(List()),List(),List(),LatestResourceEventsSnapshot(List()),0,0,IMStateSnapshot(StdIMEvent(,1320098400000,1320098400000,CKKL,,true,user,1.0,create,Map())),CreditSnapshot(0.0),AgreementHistory(List(AgreementHistoryItem(default, 2011-11-01 00:00:00.000, 292278994-08-17 07:12:55.807))),OwnedResourcesSnapshot(List()),List(),1320098400000,MonthlyBillingCalculation(2011-12),0,Some(4fa7e12ba0eee3db73fbe8d0),4fa7e12ba0eee3db73fbe8d0) DEBUG 17:50:19 g.g.a.user.UserStateComputationsTest - doFullMonthlyBilling(2011-12) END DEBUG 17:50:19 g.g.a.user.UserStateComputationsTest - …ndUserStateAtEndOfBillingMonth(2011-12) END DEBUG 17:50:19 g.g.a.user.UserStateComputationsTest - walletEntriesForResourceEvent(0) +++ [EVENT(0, [2012-01-01 00:00:00], 0.0, vmtime::VM.1, Map(), CKKL, synnefo)] +++ @@ -79,8 +79,8 @@ DEBUG 17:50:19 g.g.a.user.UserStateComputationsTest - walletEntriesForRe DEBUG 17:50:19 g.g.a.user.UserStateComputationsTest - walletEntriesForResourceEvent(0) Ignoring first event of its kind EVENT(0, [2012-01-01 00:00:00], 0.0, vmtime::VM.1, Map(), CKKL, synnefo) DEBUG 17:50:19 g.g.a.user.UserStateComputationsTest - walletEntriesForResourceEvent(0) --- [EVENT(0, [2012-01-01 00:00:00], 0.0, vmtime::VM.1, Map(), CKKL, synnefo)] --- DEBUG 17:50:19 g.g.a.user.UserStateComputationsTest - doFullMonthlyBilling(2012-01) calculationReason = MonthlyBillingCalculation(2012-01) -DEBUG 17:50:19 g.g.a.user.UserStateComputationsTest - doFullMonthlyBilling(2012-01) Saved [_id=4fa7e12ba0eee3db73fbe8d0] UserState(true,CKKL,1320098400000,3,false,null,ImplicitlyIssuedResourceEventsSnapshot(List()),List(),List(),LatestResourceEventsSnapshot(List(StdResourceEvent(0,1325368800000,1325368800000,CKKL,synnefo,vmtime,VM.1,0.0,1.0,Map()))),0,0,IMStateSnapshot(StdIMEvent(,1320098400000,1320098400000,CKKL,,true,user,1.0,create,Map())),CreditSnapshot(0.0),AgreementsSnapshot(List(AgreementSnapshot(default, 2011-11-01 00:00:00.000, 292278994-08-17 07:12:55.807))),OwnedResourcesSnapshot(List()),List(),1320098400000,MonthlyBillingCalculation(2012-01),0,Some(4fa7e12ba0eee3db73fbe8d0),4fa7e12ba0eee3db73fbe8d0) -DEBUG 17:50:19 g.g.a.user.UserStateComputationsTest - doFullMonthlyBilling(2012-01) RETURN UserState(true,CKKL,1320098400000,3,false,null,ImplicitlyIssuedResourceEventsSnapshot(List()),List(),List(),LatestResourceEventsSnapshot(List(StdResourceEvent(0,1325368800000,1325368800000,CKKL,synnefo,vmtime,VM.1,0.0,1.0,Map()))),0,0,IMStateSnapshot(StdIMEvent(,1320098400000,1320098400000,CKKL,,true,user,1.0,create,Map())),CreditSnapshot(0.0),AgreementsSnapshot(List(AgreementSnapshot(default, 2011-11-01 00:00:00.000, 292278994-08-17 07:12:55.807))),OwnedResourcesSnapshot(List()),List(),1320098400000,MonthlyBillingCalculation(2012-01),0,Some(4fa7e12ba0eee3db73fbe8d0),4fa7e12ba0eee3db73fbe8d0) +DEBUG 17:50:19 g.g.a.user.UserStateComputationsTest - doFullMonthlyBilling(2012-01) Saved [_id=4fa7e12ba0eee3db73fbe8d0] UserState(true,CKKL,1320098400000,3,false,null,ImplicitlyIssuedResourceEventsSnapshot(List()),List(),List(),LatestResourceEventsSnapshot(List(StdResourceEvent(0,1325368800000,1325368800000,CKKL,synnefo,vmtime,VM.1,0.0,1.0,Map()))),0,0,IMStateSnapshot(StdIMEvent(,1320098400000,1320098400000,CKKL,,true,user,1.0,create,Map())),CreditSnapshot(0.0),AgreementHistory(List(AgreementHistoryItem(default, 2011-11-01 00:00:00.000, 292278994-08-17 07:12:55.807))),OwnedResourcesSnapshot(List()),List(),1320098400000,MonthlyBillingCalculation(2012-01),0,Some(4fa7e12ba0eee3db73fbe8d0),4fa7e12ba0eee3db73fbe8d0) +DEBUG 17:50:19 g.g.a.user.UserStateComputationsTest - doFullMonthlyBilling(2012-01) RETURN UserState(true,CKKL,1320098400000,3,false,null,ImplicitlyIssuedResourceEventsSnapshot(List()),List(),List(),LatestResourceEventsSnapshot(List(StdResourceEvent(0,1325368800000,1325368800000,CKKL,synnefo,vmtime,VM.1,0.0,1.0,Map()))),0,0,IMStateSnapshot(StdIMEvent(,1320098400000,1320098400000,CKKL,,true,user,1.0,create,Map())),CreditSnapshot(0.0),AgreementHistory(List(AgreementHistoryItem(default, 2011-11-01 00:00:00.000, 292278994-08-17 07:12:55.807))),OwnedResourcesSnapshot(List()),List(),1320098400000,MonthlyBillingCalculation(2012-01),0,Some(4fa7e12ba0eee3db73fbe8d0),4fa7e12ba0eee3db73fbe8d0) DEBUG 17:50:19 g.g.a.user.UserStateComputationsTest - doFullMonthlyBilling(2012-01) END DEBUG 17:50:19 g.g.a.user.UserStateComputationsTest - testOrphanOFF() _id = 4fa7e12ba0eee3db73fbe8d0 DEBUG 17:50:19 g.g.a.user.UserStateComputationsTest - testOrphanOFF() parentId = Some(4fa7e12ba0eee3db73fbe8d0)