/* * Copyright 2014-2016 CyberVision, Inc. * * 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.kaaproject.kaa.server.operations.service.akka.actors.core.endpoint.local; import org.kaaproject.kaa.common.TransportType; import org.kaaproject.kaa.common.dto.EndpointProfileDto; import org.kaaproject.kaa.common.dto.NotificationDto; import org.kaaproject.kaa.server.operations.service.akka.actors.core.endpoint.AbstractEndpointActorState; import org.kaaproject.kaa.server.operations.service.akka.actors.core.endpoint.local.ChannelMap.ChannelMetaData; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Set; import java.util.UUID; public class LocalEndpointActorState extends AbstractEndpointActorState { private static final Logger LOG = LoggerFactory.getLogger(LocalEndpointActorState.class); /** * The map of active communication channels. */ private final ChannelMap channelMap; private EndpointProfileDto endpointProfile; private String userId; private boolean userRegistrationRequestSent; private int processedEventSeqNum = Integer.MIN_VALUE; private Map<String, Integer> subscriptionStates; private boolean ucfHashIntialized; private byte[] ucfHash; private boolean epsConfigurationInitialized; private byte[] epsConfigurationHash; /** * All-args constructor. */ public LocalEndpointActorState(String endpointKey, String actorKey) { super(endpointKey, actorKey); this.channelMap = new ChannelMap(endpointKey, actorKey); this.subscriptionStates = new HashMap<String, Integer>(); } public void addChannel(ChannelMetaData channel) { this.channelMap.addChannel(channel); } public boolean isNoChannels() { return channelMap.isEmpty(); } Set<ChannelMetaData> getAllChannels() { return getChannelsByTypes(TransportType.values()); } Set<ChannelMetaData> getChannelsByType(TransportType type) { return new HashSet<>(this.channelMap.getByTransportType(type)); } Set<ChannelMetaData> getChannelsByTypes(TransportType... types) { Set<ChannelMetaData> channels = new HashSet<>(); for (TransportType type : types) { channels.addAll(channelMap.getByTransportType(type)); } return channels; } ChannelMetaData getChannelByRequestId(UUID requestId) { return channelMap.getByRequestId(requestId); } ChannelMetaData getChannelById(UUID requestId) { return channelMap.getById(requestId); } public void removeChannel(ChannelMetaData channel) { channelMap.removeChannel(channel); } String getUserId() { return userId; } void setUserId(String userId) { this.userId = userId; } EndpointProfileDto getProfile() { return endpointProfile; } void setProfile(EndpointProfileDto endpointProfile) { this.endpointProfile = endpointProfile; } boolean isProfileSet() { return this.endpointProfile != null; } String getProfileUserId() { if (endpointProfile != null) { return endpointProfile.getEndpointUserId(); } else { return null; } } void setProfileUserId(String userId) { endpointProfile.setEndpointUserId(userId); } boolean isValidForUser() { return endpointProfile != null && endpointProfile.getEndpointUserId() != null && !endpointProfile.getEndpointUserId().isEmpty(); } boolean isValidForEvents() { return endpointProfile != null && endpointProfile.getEndpointUserId() != null && !endpointProfile.getEndpointUserId().isEmpty() && endpointProfile.getEcfVersionStates() != null && !endpointProfile.getEcfVersionStates().isEmpty(); } boolean userIdMismatch() { return userId != null && !userId.equals(getProfileUserId()); } boolean isUserRegistrationPending() { return userRegistrationRequestSent; } void setUserRegistrationPending(boolean userRegistrationRequestSent) { this.userRegistrationRequestSent = userRegistrationRequestSent; } int getEventSeqNumber() { return processedEventSeqNum; } void setEventSeqNumber(int maxSentEventSeqNum) { processedEventSeqNum = maxSentEventSeqNum; } void resetEventSeqNumber() { processedEventSeqNum = Integer.MIN_VALUE; } public Map<String, Integer> getSubscriptionStates() { return subscriptionStates; } public void setSubscriptionStates(Map<String, Integer> subscriptionStates) { this.subscriptionStates = new HashMap<>(subscriptionStates); } /** * Returns whether hash requires initialization. * * @return true if hash requires initialization otherwise false */ public boolean isUcfHashRequiresInitialization() { return isValidForUser() && !ucfHashIntialized; } /** * Returns whether user configuration update is pending. * * @return true if user configuration update is pending otherwise false */ public boolean isUserConfigurationUpdatePending() { if (!isValidForUser() || isUcfHashRequiresInitialization()) { return false; } return !Arrays.equals(ucfHash, endpointProfile.getUserConfigurationHash()); } public byte[] getUcfHash() { return ucfHash; } public void setUcfHash(byte[] ucfHash) { this.ucfHashIntialized = true; this.ucfHash = ucfHash; } /** * Returns whether endpoint specific configuration hash requires initialization. * * @return true if endpoint specific configuration hash requires initialization otherwise false */ public boolean isEpsConfigurationRequiresInitialization() { if (endpointProfile == null) { return false; } return !epsConfigurationInitialized; } /** * Returns whether endpoint specific configuration was changed. * * @return true if endpoint specific configuration changed otherwise false */ public boolean isEpsConfigurationChanged() { if (endpointProfile == null) { return false; } return !Arrays.equals(epsConfigurationHash, endpointProfile.getEpsConfigurationHash()); } public byte[] getEpsConfigurationHash() { return epsConfigurationHash; } public void setEpsConfigurationHash(byte[] epsConfigurationHash) { this.epsConfigurationHash = epsConfigurationHash; this.epsConfigurationInitialized = true; } /** * Returns notifications that belongs to subscribed topics. * * @param notifications notifications * @return notifications that belongs to subscribed topics */ public List<NotificationDto> filter(List<NotificationDto> notifications) { List<NotificationDto> list = new ArrayList<>(notifications.size()); for (NotificationDto nf : notifications) { if (subscriptionStates.containsKey(nf.getTopicId())) { list.add(nf); } else { LOG.trace("[{}][{}] Notification {} is no longer valid due to subscription state", endpointKey, actorKey, nf); } } return list; } }