/* * Copyright (c) 2008-2017, Hazelcast, Inc. All Rights Reserved. * * 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 com.hazelcast.map.impl.querycache.subscriber; import com.hazelcast.core.EntryEventType; import com.hazelcast.core.IMapEvent; import com.hazelcast.core.MapEvent; import com.hazelcast.core.Member; import com.hazelcast.map.EventLostEvent; import com.hazelcast.map.impl.DataAwareEntryEvent; import com.hazelcast.map.impl.EntryEventFilter; import com.hazelcast.map.impl.event.EventData; import com.hazelcast.map.impl.querycache.QueryCacheContext; import com.hazelcast.map.impl.querycache.QueryCacheEventService; import com.hazelcast.map.impl.querycache.event.LocalCacheWideEventData; import com.hazelcast.map.impl.querycache.event.LocalEntryEventData; import com.hazelcast.map.impl.querycache.subscriber.record.QueryCacheRecord; import com.hazelcast.nio.serialization.Data; import com.hazelcast.spi.EventFilter; import com.hazelcast.spi.serialization.SerializationService; /** * Helper class for publishing events to {@code QueryCache} listeners. */ public final class EventPublisherHelper { private EventPublisherHelper() { } /** * Publishes event upon a change on a key in {@code QueryCache}. * * @param mapName the name of underlying map. * @param cacheName the name of {@code QueryCache} * @param dataKey the key in {@code Data} format. * @param dataNewValue the value in {@code Data} format. * @param oldRecord the relevant {@code QueryCacheEntry} * @param context the {@code QueryCacheContext} */ static void publishEntryEvent(QueryCacheContext context, String mapName, String cacheName, Data dataKey, Data dataNewValue, QueryCacheRecord oldRecord, EntryEventType eventType) { QueryCacheEventService eventService = getQueryCacheEventService(context); if (!eventService.hasListener(mapName, cacheName)) { return; } Object oldValue = getOldValue(oldRecord); LocalEntryEventData eventData = createLocalEntryEventData(cacheName, dataKey, dataNewValue, oldValue, eventType.getType(), -1, context); eventService.publish(mapName, cacheName, eventData, dataKey.hashCode()); } static void publishCacheWideEvent(QueryCacheContext context, String mapName, String cacheName, int numberOfEntriesAffected, EntryEventType eventType) { QueryCacheEventService eventService = getQueryCacheEventService(context); if (!eventService.hasListener(mapName, cacheName)) { return; } LocalCacheWideEventData eventData = new LocalCacheWideEventData(cacheName, eventType.getType(), numberOfEntriesAffected); eventService.publish(mapName, cacheName, eventData, cacheName.hashCode()); } private static Object getOldValue(QueryCacheRecord oldRecord) { return oldRecord == null ? null : oldRecord.getValue(); } private static LocalEntryEventData createLocalEntryEventData(String cacheName, Data dataKey, Data dataNewValue, Object oldValue, int eventType, int partitionId, QueryCacheContext context) { SerializationService serializationService = context.getSerializationService(); return new LocalEntryEventData(serializationService, cacheName, eventType, dataKey, oldValue, dataNewValue, partitionId); } private static QueryCacheEventService getQueryCacheEventService(QueryCacheContext context) { SubscriberContext subscriberContext = context.getSubscriberContext(); return subscriberContext.getEventService(); } public static void publishEventLost(QueryCacheContext context, String mapName, String cacheName, int partitionId) { QueryCacheEventService eventService = getQueryCacheEventService(context); int orderKey = cacheName.hashCode(); eventService.publish(mapName, cacheName, createLocalEntryEventData(cacheName, null, null, null, EventLostEvent.EVENT_TYPE, partitionId, context), orderKey); } public static IMapEvent createIMapEvent(EventData eventData, EventFilter filter, Member member, SerializationService serializationService) { String source = eventData.getSource(); int eventType = eventData.getEventType(); if (eventType == EventLostEvent.EVENT_TYPE) { LocalEntryEventData localEventData = (LocalEntryEventData) eventData; int partitionId = localEventData.getPartitionId(); return new EventLostEvent(source, null, partitionId); } if (eventType == EntryEventType.CLEAR_ALL.getType() || eventType == EntryEventType.EVICT_ALL.getType()) { LocalCacheWideEventData localCacheWideEventData = (LocalCacheWideEventData) eventData; int numberOfEntriesAffected = localCacheWideEventData.getNumberOfEntriesAffected(); return new MapEvent(source, null, eventType, numberOfEntriesAffected); } LocalEntryEventData localEntryEventData = (LocalEntryEventData) eventData; Data dataKey = localEntryEventData.getKeyData(); Data dataNewValue = localEntryEventData.getValueData(); Data dataOldValue = localEntryEventData.getOldValueData(); boolean includeValue = isIncludeValue(filter); return new DataAwareEntryEvent(member, eventType, source, dataKey, (includeValue ? dataNewValue : null), (includeValue ? dataOldValue : null), null, serializationService); } private static boolean isIncludeValue(EventFilter filter) { if (filter instanceof EntryEventFilter) { return ((EntryEventFilter) filter).isIncludeValue(); } return true; } }