Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
sss.openstar.rpc.UserSession.scala Maven / Gradle / Ivy
package sss.openstar.rpc
import akka.NotUsed
import akka.actor.{ActorContext, ActorRef}
import akka.stream.scaladsl.Source
import com.typesafe.scalalogging.Logger
import sss.ancillary.{Guid, LogFactory}
import sss.db.Db
import sss.openstar.account.NodeIdentity
import sss.openstar.chains.Chains.GlobalChainIdMask
import sss.openstar.contacts.ContactService
import sss.openstar.contacts.ContactService.LoggedInUser
import sss.openstar.controller.Send
import sss.openstar.html5push.Subscriptions
import sss.openstar.html5push.Subscriptions.Subscription
import sss.openstar.identityledger.{IdentityServiceQuery, MessageStoreProviders}
import sss.openstar.message.MessageDownloadActor.PublishUnProcessedMessages
import sss.openstar.message.MessageInBox.SavedMessage
import sss.openstar.message.MessagePaywall.MessagePaywallGenerator
import sss.openstar.message.payloads.MessageEcryption.{AttachmentDetails, MessageAttachments}
import sss.openstar.message.{MessageDownloadPersistCache, MessageInBox, OutgoingMessageProcessorUtil, UtxoQuery, UtxoWatch}
import sss.openstar.network.MessageEventBus
import sss.openstar.nodebuilder.MessageHandlingActors
import sss.openstar.rpc.RpcBridgeEventSource.RpcBridgeEventSourceShutdown
import sss.openstar.tools.SendTxSupport.SendTx
import sss.openstar.ui.rpc.Event
import sss.openstar.util.TryOps.LogTry
import sss.openstar.wallet.UnlockedWallet
import sss.openstar.wallet.UtxoTracker.TrackWallet
import sss.openstar.{Currency, UniqueNodeIdentifier}
import java.util.concurrent.atomic.AtomicReference
/**
* Created by alan on 12/20/16.
*/
class MessageAttachmentsHolder(attachmentProviderName: UniqueNodeIdentifier) {
private val ref = new AtomicReference[Map[Guid,MessageAttachments]](Map.empty)
def clear(): Unit = {
ref.set(Map.empty)
}
def apply(guid: Guid):MessageAttachments = {
ref.updateAndGet(currentMap => {
currentMap + (guid -> currentMap.getOrElse(guid, MessageAttachments(attachmentProviderName)))
})(guid)
}
def apply(guid: Guid, attachments: MessageAttachments): Unit = {
ref.updateAndGet(currentMap => {
currentMap + (guid -> attachments)
})
}
def addDetails(guid: Guid, details: AttachmentDetails): Unit = {
ref.updateAndGet(currentMap => {
val attachments = currentMap.getOrElse(guid, MessageAttachments(attachmentProviderName))
currentMap + (guid -> attachments.copy(
attachmentDetails =
attachments.attachmentDetails.filter(_.name != details.name) :+ details))
})
}
def getAttachments(guid: Guid): Option[MessageAttachments] = {
ref.get().get(guid)
}
}
case class UserSession[BASECURRENCY <: Currency](messageHandlingActors: Option[MessageHandlingActors],
loggedInUser: LoggedInUser,
messageAttachments: MessageAttachmentsHolder,
userAdaWallet: UnlockedWallet[BASECURRENCY]
)(
implicit val nodeId: NodeIdentity,
actorContext: ActorContext,
events: MessageEventBus,
//val userStarzWallet: UnlockedWallet[Starz],
db: Db) {
lazy val messages: MessageInBox = MessageInBox(nodeId.id)
lazy implicit val guidToSavedMessage: Guid => Option[SavedMessage] = messages.find
def update(updatedLoggedInUser: LoggedInUser): UserSession[BASECURRENCY] = copy(loggedInUser = updatedLoggedInUser)
def createEventSource: Source[Event, NotUsed] = RpcBridgeEventSource(nodeId.id, userAdaWallet.w.ledgerId)
}
object UserSessionFactory {
type LookUpMessageByGuid = Guid => Option[SavedMessage]
}
class UserSessionFactory[BASECURRENCY <: Currency] {
implicit val log: Logger = LogFactory.getLogger(this.getClass.toString)
def apply(sessId: String): Option[UserSession[BASECURRENCY]] = {
val all = allSessions.get()
all.get(sessId)
}
def update(sessId: String, updated: UserSession[BASECURRENCY]): UserSession[BASECURRENCY] = {
allSessions.updateAndGet(
_ + (sessId -> updated)
)(sessId)
}
def remove(sessId: String)(implicit events: MessageEventBus): Unit = synchronized {
allSessions.getAndUpdate(
_ - sessId
).get(sessId).foreach { sess =>
sess.messageHandlingActors.foreach(_.stop())
events publish RpcBridgeEventSourceShutdown(sess.nodeId.id)
}
}
def register(sessId: String,
nodeIdentity: NodeIdentity,
hostingNodeIdentity: String,
//starzUserWallet: UnlockedWallet[Starz],
adaUserWallet: UnlockedWallet[BASECURRENCY],
subscriptionOpt: Option[Subscription],
messageInBoxActorGroup: ActorRef)
(implicit db: Db,
subscriptions: Subscriptions,
persistCache: MessageDownloadPersistCache,
utxoWatch: UtxoWatch,
utxoQuery: UtxoQuery,
personalPaywallGenerator: MessagePaywallGenerator[BASECURRENCY],
outgoingMessageProcessorUtil: OutgoingMessageProcessorUtil,
events: MessageEventBus,
identityService: IdentityServiceQuery,
contactService: ContactService,
actorContext: ActorContext,
send: Send,
sendTx: SendTx,
chainId: GlobalChainIdMask
): Map[String, UserSession[BASECURRENCY]] = synchronized {
remove(sessId)
// TODO remove same user already logged in removeUser(nodeIdentity.id)
implicit val imNodeIdentity = nodeIdentity
//implicit val imUserWallet = starzUserWallet
val messageHandlingActorsOpt = if(nodeIdentity.id == hostingNodeIdentity) {
None
} else Some(
MessageHandlingActors.addMessageHandlingActors[BASECURRENCY](adaUserWallet, nodeIdentity, messageInBoxActorGroup)
)
//Don't delete subscriptions if they down't exist, only update them if they do
subscriptionOpt.map ( _ =>
subscriptions.persist(nodeIdentity.id, subscriptionOpt)
.andLog("subscriptions.persist")
)
val balance = adaUserWallet.w.balance().get
//events publish TrackWallet[Starz](starzUserWallet.w, balance)
events publish TrackWallet[BASECURRENCY](adaUserWallet.w, balance)
events publish PublishUnProcessedMessages(nodeIdentity.id)
val providers = identityService.messageStores(nodeIdentity.id)
events publish MessageStoreProviders(nodeIdentity.id, providers)
val loggedInUser = contactService.findUser(nodeIdentity.id).getOrElse {
contactService.addContact(nodeIdentity.id)
contactService.findUser(nodeIdentity.id).get
}
val attachmentsHolder = new MessageAttachmentsHolder(hostingNodeIdentity)
allSessions.updateAndGet(
_ + (sessId -> UserSession[BASECURRENCY](
messageHandlingActorsOpt,
loggedInUser,
attachmentsHolder,
adaUserWallet))
)
}
private val allSessions: AtomicReference[Map[String, UserSession[BASECURRENCY]]] = new AtomicReference(Map.empty)
}