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.
com.hazelcast.replicatedmap.impl.ReplicatedMapEventPublishingService Maven / Gradle / Ivy
/*
* Copyright (c) 2008-2016, 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.replicatedmap.impl;
import com.hazelcast.config.Config;
import com.hazelcast.config.ReplicatedMapConfig;
import com.hazelcast.core.EntryEvent;
import com.hazelcast.core.EntryEventType;
import com.hazelcast.core.EntryListener;
import com.hazelcast.core.MapEvent;
import com.hazelcast.core.Member;
import com.hazelcast.instance.MemberImpl;
import com.hazelcast.internal.serialization.InternalSerializationService;
import com.hazelcast.map.impl.DataAwareEntryEvent;
import com.hazelcast.map.impl.event.EntryEventData;
import com.hazelcast.map.impl.event.EventData;
import com.hazelcast.map.impl.event.MapEventData;
import com.hazelcast.monitor.impl.LocalReplicatedMapStatsImpl;
import com.hazelcast.nio.Address;
import com.hazelcast.nio.serialization.Data;
import com.hazelcast.query.impl.QueryEntry;
import com.hazelcast.replicatedmap.ReplicatedMapCantBeCreatedOnLiteMemberException;
import com.hazelcast.replicatedmap.impl.record.AbstractReplicatedRecordStore;
import com.hazelcast.replicatedmap.impl.record.ReplicatedQueryEventFilter;
import com.hazelcast.replicatedmap.impl.record.ReplicatedRecordStore;
import com.hazelcast.spi.EventFilter;
import com.hazelcast.spi.EventPublishingService;
import com.hazelcast.spi.EventRegistration;
import com.hazelcast.spi.EventService;
import com.hazelcast.spi.NodeEngine;
import java.util.Collection;
import java.util.EventListener;
import java.util.HashMap;
import static com.hazelcast.core.EntryEventType.ADDED;
import static com.hazelcast.core.EntryEventType.REMOVED;
import static com.hazelcast.core.EntryEventType.UPDATED;
import static com.hazelcast.replicatedmap.impl.ReplicatedMapService.SERVICE_NAME;
/**
* Dispatches published events on replicated map to corresponding listeners.
*/
public class ReplicatedMapEventPublishingService implements EventPublishingService {
private final ReplicatedMapService replicatedMapService;
private final NodeEngine nodeEngine;
private final Config config;
private final EventService eventService;
private final HashMap statisticsMap = new HashMap();
public ReplicatedMapEventPublishingService(ReplicatedMapService replicatedMapService) {
this.replicatedMapService = replicatedMapService;
this.nodeEngine = replicatedMapService.getNodeEngine();
this.config = nodeEngine.getConfig();
this.eventService = nodeEngine.getEventService();
}
@Override
public void dispatchEvent(Object event, Object listener) {
if ((event instanceof EntryEventData)) {
EntryEventData entryEventData = (EntryEventData) event;
Member member = getMember(entryEventData);
EntryEvent entryEvent = createDataAwareEntryEvent(entryEventData, member);
EntryListener entryListener = (EntryListener) listener;
switch (entryEvent.getEventType()) {
case ADDED:
entryListener.entryAdded(entryEvent);
break;
case EVICTED:
entryListener.entryEvicted(entryEvent);
break;
case UPDATED:
entryListener.entryUpdated(entryEvent);
break;
case REMOVED:
entryListener.entryRemoved(entryEvent);
break;
default:
throw new IllegalArgumentException("event type " + entryEvent.getEventType() + " not supported");
}
String mapName = ((EntryEventData) event).getMapName();
Boolean statisticsEnabled = statisticsMap.get(mapName);
if (statisticsEnabled == null) {
ReplicatedMapConfig mapConfig = config.findReplicatedMapConfig(mapName);
statisticsEnabled = mapConfig.isStatisticsEnabled();
statisticsMap.put(mapName, statisticsEnabled);
}
if (statisticsEnabled) {
int partitionId = nodeEngine.getPartitionService().getPartitionId(entryEventData.getDataKey());
ReplicatedRecordStore recordStore = replicatedMapService.getPartitionContainer(partitionId)
.getRecordStore(mapName);
if (recordStore instanceof AbstractReplicatedRecordStore) {
LocalReplicatedMapStatsImpl stats = ((AbstractReplicatedRecordStore) recordStore).getStats();
stats.incrementReceivedEvents();
}
}
} else if (event instanceof MapEventData) {
MapEventData mapEventData = (MapEventData) event;
Member member = getMember(mapEventData);
MapEvent mapEvent = new MapEvent(mapEventData.getMapName(), member,
mapEventData.getEventType(), mapEventData.getNumberOfEntries());
EntryListener entryListener = (EntryListener) listener;
EntryEventType type = EntryEventType.getByType(mapEventData.getEventType());
switch (type) {
case CLEAR_ALL:
entryListener.mapCleared(mapEvent);
break;
default:
throw new IllegalArgumentException("event type " + type + " not supported");
}
}
}
public String addEventListener(EventListener entryListener, EventFilter eventFilter, String mapName) {
if (config.isLiteMember()) {
throw new ReplicatedMapCantBeCreatedOnLiteMemberException(nodeEngine.getThisAddress());
}
EventRegistration registration = eventService.registerLocalListener(SERVICE_NAME, mapName, eventFilter,
entryListener);
return registration.getId();
}
public boolean removeEventListener(String mapName, String registrationId) {
if (config.isLiteMember()) {
throw new ReplicatedMapCantBeCreatedOnLiteMemberException(nodeEngine.getThisAddress());
}
if (registrationId == null) {
throw new IllegalArgumentException("registrationId cannot be null");
}
return eventService.deregisterListener(SERVICE_NAME, mapName, registrationId);
}
public void fireMapClearedEvent(int deletedEntrySize, String name) {
EventService eventService = nodeEngine.getEventService();
Collection registrations = eventService.getRegistrations(
SERVICE_NAME, name);
if (registrations.isEmpty()) {
return;
}
MapEventData mapEventData = new MapEventData(name, name, nodeEngine.getThisAddress(),
EntryEventType.CLEAR_ALL.getType(), deletedEntrySize);
eventService.publishEvent(SERVICE_NAME, registrations, mapEventData, name.hashCode());
}
private Member getMember(EventData eventData) {
Member member = replicatedMapService.getNodeEngine().getClusterService().getMember(eventData.getCaller());
if (member == null) {
member = new MemberImpl(eventData.getCaller(), false);
}
return member;
}
private DataAwareEntryEvent createDataAwareEntryEvent(EntryEventData entryEventData, Member member) {
return new DataAwareEntryEvent(member, entryEventData.getEventType(), entryEventData.getMapName(),
entryEventData.getDataKey(), entryEventData.getDataNewValue(), entryEventData.getDataOldValue(),
entryEventData.getDataMergingValue(), nodeEngine.getSerializationService());
}
public void fireEntryListenerEvent(Data key, Data oldValue, Data value, String name, Address caller) {
EntryEventType eventType = value == null ? REMOVED : oldValue == null ? ADDED : UPDATED;
fireEntryListenerEvent(key, oldValue, value, eventType, name, caller);
}
public void fireEntryListenerEvent(Data key, Data oldValue, Data value, EntryEventType eventType, String name,
Address caller) {
Collection registrations = eventService.getRegistrations(SERVICE_NAME, name);
if (registrations.isEmpty()) {
return;
}
EntryEventData eventData = new EntryEventData(name, name, caller, key, value, oldValue, eventType.getType());
for (EventRegistration registration : registrations) {
if (!shouldPublish(key, oldValue, value, eventType, registration.getFilter())) {
continue;
}
eventService.publishEvent(SERVICE_NAME, registration, eventData, key.hashCode());
}
}
private boolean shouldPublish(Data key, Data oldValue, Data value, EntryEventType eventType, EventFilter filter) {
QueryEntry queryEntry = null;
if (filter instanceof ReplicatedQueryEventFilter) {
Data testValue;
if (eventType == REMOVED) {
testValue = oldValue;
} else {
testValue = value;
}
InternalSerializationService serializationService =
(InternalSerializationService) nodeEngine.getSerializationService();
queryEntry = new QueryEntry(serializationService, key, testValue, null);
}
return filter == null || filter.eval(queryEntry != null ? queryEntry : key);
}
}