/**
* Copyright © 2016-2017 The Thingsboard Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.thingsboard.server.actors.session;
import org.thingsboard.server.actors.ActorSystemContext;
import org.thingsboard.server.actors.shared.AbstractContextAwareMsgProcessor;
import org.thingsboard.server.actors.shared.SessionTimeoutMsg;
import org.thingsboard.server.common.data.id.DeviceId;
import org.thingsboard.server.common.data.id.SessionId;
import org.thingsboard.server.common.msg.cluster.ClusterEventMsg;
import org.thingsboard.server.common.msg.cluster.ServerAddress;
import org.thingsboard.server.common.msg.device.BasicToDeviceActorMsg;
import org.thingsboard.server.common.msg.device.ToDeviceActorMsg;
import org.thingsboard.server.common.msg.session.*;
import org.thingsboard.server.common.msg.session.ctrl.SessionCloseMsg;
import akka.actor.ActorContext;
import akka.actor.ActorRef;
import akka.event.LoggingAdapter;
import java.util.Optional;
abstract class AbstractSessionActorMsgProcessor extends AbstractContextAwareMsgProcessor {
protected final SessionId sessionId;
protected SessionContext sessionCtx;
protected ToDeviceActorMsg toDeviceActorMsgPrototype;
protected AbstractSessionActorMsgProcessor(ActorSystemContext ctx, LoggingAdapter logger, SessionId sessionId) {
super(ctx, logger);
this.sessionId = sessionId;
}
protected abstract void processToDeviceActorMsg(ActorContext ctx, ToDeviceActorSessionMsg msg);
protected abstract void processTimeoutMsg(ActorContext context, SessionTimeoutMsg msg);
protected abstract void processToDeviceMsg(ActorContext context, ToDeviceMsg msg);
public abstract void processClusterEvent(ActorContext context, ClusterEventMsg msg);
protected void processSessionCtrlMsg(ActorContext ctx, SessionCtrlMsg msg) {
if (msg instanceof SessionCloseMsg) {
cleanupSession(ctx);
terminateSession(ctx, sessionId);
}
}
protected void cleanupSession(ActorContext ctx) {
}
protected void updateSessionCtx(ToDeviceActorSessionMsg msg, SessionType type) {
sessionCtx = msg.getSessionMsg().getSessionContext();
toDeviceActorMsgPrototype = new BasicToDeviceActorMsg(msg, type);
}
protected ToDeviceActorMsg toDeviceMsg(ToDeviceActorSessionMsg msg) {
AdaptorToSessionActorMsg adaptorMsg = msg.getSessionMsg();
return new BasicToDeviceActorMsg(toDeviceActorMsgPrototype, adaptorMsg.getMsg());
}
protected Optional<ToDeviceActorMsg> toDeviceMsg(FromDeviceMsg msg) {
if (toDeviceActorMsgPrototype != null) {
return Optional.of(new BasicToDeviceActorMsg(toDeviceActorMsgPrototype, msg));
} else {
return Optional.empty();
}
}
protected Optional<ServerAddress> forwardToAppActor(ActorContext ctx, ToDeviceActorMsg toForward) {
Optional<ServerAddress> address = systemContext.getRoutingService().resolve(toForward.getDeviceId());
forwardToAppActor(ctx, toForward, address);
return address;
}
protected Optional<ServerAddress> forwardToAppActorIfAdressChanged(ActorContext ctx, ToDeviceActorMsg toForward, Optional<ServerAddress> oldAddress) {
Optional<ServerAddress> newAddress = systemContext.getRoutingService().resolve(toForward.getDeviceId());
if (!newAddress.equals(oldAddress)) {
if (newAddress.isPresent()) {
systemContext.getRpcService().tell(newAddress.get(),
toForward.toOtherAddress(systemContext.getRoutingService().getCurrentServer()));
} else {
getAppActor().tell(toForward, ctx.self());
}
}
return newAddress;
}
protected void forwardToAppActor(ActorContext ctx, ToDeviceActorMsg toForward, Optional<ServerAddress> address) {
if (address.isPresent()) {
systemContext.getRpcService().tell(address.get(),
toForward.toOtherAddress(systemContext.getRoutingService().getCurrentServer()));
} else {
getAppActor().tell(toForward, ctx.self());
}
}
public static void terminateSession(ActorContext ctx, SessionId sessionId) {
ctx.parent().tell(new SessionTerminationMsg(sessionId), ActorRef.noSender());
ctx.stop(ctx.self());
}
public DeviceId getDeviceId() {
return toDeviceActorMsgPrototype.getDeviceId();
}
}