All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.bagri.server.hazelcast.impl.PopulationManagementImpl Maven / Gradle / Ivy

The newest version!
package com.bagri.server.hazelcast.impl;

import static com.bagri.core.Constants.*;
import static com.bagri.core.server.api.CacheConstants.*;
import static com.bagri.server.hazelcast.util.SpringContextHolder.*;

import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.Set;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.ApplicationContext;

import com.bagri.core.DocumentKey;
import com.bagri.core.KeyFactory;
import com.bagri.core.model.Document;
import com.bagri.core.model.Transaction;
import com.bagri.core.server.api.PopulationManagement;
import com.bagri.server.hazelcast.store.DocumentMemoryStore;
import com.bagri.server.hazelcast.task.schema.SchemaPopulator;
import com.hazelcast.core.EntryEvent;
import com.hazelcast.core.IMap;
import com.hazelcast.core.LifecycleEvent;
import com.hazelcast.core.LifecycleEvent.LifecycleState;
import com.hazelcast.core.LifecycleListener;
import com.hazelcast.core.MapEvent;
import com.hazelcast.core.MapStore;
import com.hazelcast.core.MemberAttributeEvent;
import com.hazelcast.core.MembershipEvent;
import com.hazelcast.core.MembershipListener;
import com.hazelcast.core.MigrationEvent;
import com.hazelcast.core.MigrationListener;
import com.hazelcast.map.impl.MapContainer;
import com.hazelcast.map.impl.MapService;
import com.hazelcast.map.impl.MapServiceContext;
import com.hazelcast.map.impl.MapStoreWrapper;
import com.hazelcast.map.impl.mapstore.MapStoreContext;
import com.hazelcast.map.impl.recordstore.RecordStore;
import com.hazelcast.map.listener.EntryAddedListener;
import com.hazelcast.map.listener.EntryEvictedListener;
import com.hazelcast.map.listener.EntryMergedListener;
import com.hazelcast.map.listener.EntryRemovedListener;
import com.hazelcast.map.listener.EntryUpdatedListener;
import com.hazelcast.map.listener.MapClearedListener;
import com.hazelcast.map.listener.MapEvictedListener;
//import com.hazelcast.map.listener.MapListener;
import com.hazelcast.spi.ManagedService;
import com.hazelcast.spi.NodeEngine;

public class PopulationManagementImpl implements PopulationManagement, ManagedService, 
	MembershipListener, MigrationListener, LifecycleListener,
	MapClearedListener, MapEvictedListener, 
	EntryAddedListener, 
	EntryEvictedListener, 
	EntryUpdatedListener, 
	EntryRemovedListener, 
	EntryMergedListener  { 

    private static final transient Logger logger = LoggerFactory.getLogger(PopulationManagementImpl.class);

    private String schemaName;
    private int populationSize;
    private NodeEngine nodeEngine;

    private KeyFactory xFactory;
	private IMap xtxCache;
    private IMap keyCache;
	//private IMap xddCache;
	private IMap xddCache;
	private DocumentMemoryStore docStore;
	private DocumentManagementImpl docMgr;

	@Override
	public String getKeyMapping(DocumentKey key) {
		return keyCache.get(key);
	}

	@Override
	public void setKeyMapping(DocumentKey key, String mapping) {
		keyCache.put(key, mapping);
	}

	@Override
	public Map getKeyMappings(Set keys) {
		return keyCache.getAll(keys);
	}

	@Override
	public void setKeyMappings(Map mappings) {
		keyCache.putAll(mappings);
	}

	@Override
	public String deleteKeyMapping(DocumentKey key) {
		return keyCache.remove(key);
	}

	@Override
	public int deleteKeyMappings(Set keys) {
		int cnt = 0;
		for (DocumentKey key: keys) {
			if (keyCache.remove(key) != null) {
				cnt++;
			}
		}
		return cnt;
	}

	@Override
	public void init(NodeEngine nodeEngine, Properties properties) {
		logger.info("init; got properties: {}", properties); 
		this.nodeEngine = nodeEngine;
		this.schemaName = properties.getProperty(pn_schema_name);
		this.populationSize = Integer.parseInt(properties.getProperty(pn_schema_population_size));
		String dataPath = properties.getProperty(pn_schema_store_data_path);
		String nodeNum = properties.getProperty(pn_node_instance);
		int buffSize = 2048*100;
		String bSize = properties.getProperty(pn_schema_population_buffer_size);
		if (bSize != null) {
			buffSize = Integer.parseInt(bSize);
		}
		logger.info("init; will open doc store from path: {}; instance: {}; buffer size: {} docs", dataPath, nodeNum, buffSize);
		docStore = new DocumentMemoryStore(dataPath, nodeNum, buffSize);
			
		nodeEngine.getPartitionService().addMigrationListener(this);
		nodeEngine.getHazelcastInstance().getCluster().addMembershipListener(this);
		nodeEngine.getHazelcastInstance().getLifecycleService().addLifecycleListener(this);
		nodeEngine.getHazelcastInstance().getUserContext().put(ctx_popService, this);
	}
	
	@Override
	public void reset() {
		logger.info("reset"); 
	}

	@Override
	public void shutdown(boolean terminate) {
		logger.info("shutdown; terminate: {}", terminate);
		docStore.close();
	}

	public void checkPopulation(int currentSize) throws Exception {
		logger.info("checkPopulation; populationSize: {}; currentSize: {}", populationSize, currentSize);
		activateDocStore();
		xddCache.addEntryListener(this, true);
    	if (populationSize == currentSize && xddCache.size() == 0) {
    		SchemaPopulator pop = new SchemaPopulator(schemaName);
    		// try to run it from the same thread..
    		nodeEngine.getHazelcastInstance().getExecutorService(PN_XDM_SCHEMA_POOL).submitToMember(pop, nodeEngine.getLocalMember());
    		//pop.call();
    	}
    }
	
	public Document getDocument(Long docKey) {
		return docStore.getEntry(docKey);
	}
	
	public int getActiveCount() {
		return docStore.getActiveEntryCount();
	}
	
	public int getDocumentCount() {
		return docStore.getFullEntryCount();
	}
	
	public int getUpdatingDocumentCount() {
		MapService svc = nodeEngine.getService(MapService.SERVICE_NAME);
		MapServiceContext xddCtx = svc.getMapServiceContext();
		// this does not work for some reason
		//return xddCtx.getWriteBehindQueueItemCounter().get();
		int cnt = 0;
		List parts = nodeEngine.getPartitionService().getMemberPartitions(nodeEngine.getThisAddress());
		for (int part: parts) {
			RecordStore rs = xddCtx.getRecordStore(part, CN_XDM_DOCUMENT);
			if (rs != null) {
				cnt += rs.getMapDataStore().notFinishedOperationsCount();
			}
		}
		return cnt;
	}
	
	public Set getDocumentKeys() {
		if (docStore.getEntryKeys().size() == 0) {
			return null;
		}
		
		Set result = new HashSet<>();
		KeyFactory factory = getKeyFactory();
		for (Long docKey: docStore.getEntryKeys()) {
			result.add(factory.newDocumentKey(docKey));
		}
		logger.info("getDocumentKeys; returning {} keys", result.size());
		return result;
	}
	
	public long getMaxTransactionId() {
		return docStore.getMaxTransactionId();
	}
	
	private void activateDocStore() {

		if (docStore.isActivated()) {
			logger.info("activateDocStore; the document store has been already activated");
			return;
		}

		docStore.init(xddCache);

		ApplicationContext schemaCtx = getContext(schemaName);
		docMgr = schemaCtx.getBean(DocumentManagementImpl.class);
	}
	
	private KeyFactory getKeyFactory() {
		if (xFactory == null) {
			ApplicationContext schemaCtx = getContext(schemaName);
			xFactory = schemaCtx.getBean("xdmFactory", KeyFactory.class);
		}
		return xFactory;
	}

	public MapStore getMapStore(String mapName) {
		MapService svc = nodeEngine.getService(MapService.SERVICE_NAME);
		MapContainer mc = svc.getMapServiceContext().getMapContainer(mapName);
		if (mc != null) {
			MapStoreContext msc = mc.getMapStoreContext();
			if (msc != null) {
				MapStoreWrapper msw = msc.getMapStoreWrapper();
				if (msw != null) {
					return msw.getMapStore();
				}
			}
		}
		return null;
	}

	//public ManagedService getHzService(String serviceName, String instanceName) {
	//	return nodeEngine.getHazelcastInstance().getDistributedObject(serviceName, instanceName);
	//}
	
	@Override
	public void stateChanged(LifecycleEvent event) {
		logger.info("stateChanged; event: {}", event);
		if (LifecycleState.STARTED == event.getState()) {
			xtxCache = nodeEngine.getHazelcastInstance().getMap(CN_XDM_TRANSACTION);
			xddCache = nodeEngine.getHazelcastInstance().getMap(CN_XDM_DOCUMENT);
			keyCache = nodeEngine.getHazelcastInstance().getMap(CN_XDM_KEY);
			//readCatalog(catalog);
			// too early
			//checkPopulation(nodeEngine.getClusterService().getSize());
		} else if (LifecycleState.SHUTTING_DOWN == event.getState()) {
			xtxCache.flush();
			xddCache.flush();
			logger.info("stateChanged; Maps were flushed");
		}
	}

	@Override
	public void memberAdded(MembershipEvent membershipEvent) {
		logger.info("memberAdded; event: {}", membershipEvent);
		// this does not work, unfortunately
		//if (membershipEvent.getMember().localMember()) {
		//	IMap xddCache = nodeEngine.getHazelcastInstance().getMap(CN_XDM_DOCUMENT);
		//	xddCache.addEntryListener(this, true);
		//}
		//checkPopulation(membershipEvent.getMembers().size());
	}

	@Override
	public void memberRemoved(MembershipEvent membershipEvent) {
		logger.info("memberRemoved; event: {}; docs size: {}; active count: {}", membershipEvent, xddCache.size(), docStore.getActiveEntryCount());
	}

	@Override
	public void memberAttributeChanged(MemberAttributeEvent memberAttributeEvent) {
		logger.trace("memberAttributeChaged; event: {}", memberAttributeEvent);
	}

	@Override
	public void migrationStarted(MigrationEvent migrationEvent) {
		logger.debug("migrationStarted; event: {}", migrationEvent); 
	}

	@Override
	public void migrationCompleted(MigrationEvent migrationEvent) {
		logger.debug("migrationCompleted; event: {}", migrationEvent); 
	}

	@Override
	public void migrationFailed(MigrationEvent migrationEvent) {
		logger.debug("migrationFailed; event: {};", migrationEvent); 
	}

	//@Override
	//public void migrationInitialized(MigrationEvent migrationEvent) {
	//	logger.debug("migrationInitialized; event: {}", migrationEvent);
	//}

	//@Override
	//public void migrationFinalized(MigrationEvent migrationEvent) {
	//	logger.debug("migrationFinalized; event: {}", migrationEvent);
	//}

	@Override
	public void mapEvicted(MapEvent event) {
		logger.trace("mapEvicted; event: {}", event);
	}

	@Override
	public void mapCleared(MapEvent event) {
		logger.trace("mapCleared; event: {}", event);
	}

	@Override
	public void entryAdded(EntryEvent event) {
		logger.trace("entryAdded.enter; event: {}", event);
		boolean added = docStore.putEntry(event.getKey().getKey(), event.getValue(), false);
		logger.trace("entryAdded.exit; added: {}", added);
	}

	@Override
	public void entryUpdated(EntryEvent event) {
		logger.trace("entryUpdated.enter; event: {}", event);
		boolean updated = docStore.putEntry(event.getKey().getKey(), event.getValue(), true);
		logger.trace("entryUpdated.exit; updated: {}", updated);
	}

	@Override
	public void entryRemoved(EntryEvent event) {
		logger.trace("entryRemoved.enter; event: {}", event);
		boolean removed = docStore.clearEntry(event.getKey().getKey(), event.getValue(), true);
		logger.trace("entryRemoved.exit; removed: {}", removed);
	}

	@Override
	public void entryEvicted(EntryEvent event) {
		logger.trace("entryEvicted.enter; event: {}", event);
	}

	@Override
	public void entryMerged(EntryEvent event) {
		logger.trace("entryMerged; event: {}", event);
	}

}





© 2015 - 2025 Weber Informatics LLC | Privacy Policy