gedi.solutions.geode.client.GeodeClient Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of gedi-geode-extensions-core Show documentation
Show all versions of gedi-geode-extensions-core Show documentation
GemFire Enterprise Data Integration - common development extensions powered by Apache Geode
The newest version!
package gedi.solutions.geode.client;
import java.io.File;
import java.io.IOException;
import java.nio.file.Paths;
import java.util.Collection;
import java.util.Hashtable;
import java.util.Map;
import java.util.Properties;
import java.util.Set;
import java.util.concurrent.BlockingQueue;
import java.util.function.Consumer;
import org.apache.geode.cache.CacheClosedException;
import org.apache.geode.cache.CacheListener;
import org.apache.geode.cache.EntryEvent;
import org.apache.geode.cache.Region;
import org.apache.geode.cache.client.ClientCache;
import org.apache.geode.cache.client.ClientCacheFactory;
import org.apache.geode.cache.client.ClientRegionFactory;
import org.apache.geode.cache.client.ClientRegionShortcut;
import org.apache.geode.cache.execute.Execution;
import org.apache.geode.cache.execute.FunctionService;
import org.apache.geode.cache.execute.RegionFunctionContext;
import org.apache.geode.cache.query.CqAttributes;
import org.apache.geode.cache.query.CqAttributesFactory;
import org.apache.geode.cache.query.CqClosedException;
import org.apache.geode.cache.query.CqException;
import org.apache.geode.cache.query.CqExistsException;
import org.apache.geode.cache.query.CqQuery;
import org.apache.geode.cache.query.QueryInvalidException;
import org.apache.geode.cache.query.QueryService;
import org.apache.geode.cache.query.RegionNotFoundException;
import org.apache.geode.pdx.PdxSerializer;
import gedi.solutions.geode.client.cq.CqQueueListener;
import gedi.solutions.geode.io.GemFireIO;
import gedi.solutions.geode.io.Querier;
import gedi.solutions.geode.io.QuerierMgr;
import gedi.solutions.geode.io.QuerierService;
import gedi.solutions.geode.listeners.CacheListenerBridge;
import gedi.solutions.geode.lucene.GeodeLuceneSearch;
import gedi.solutions.geode.lucene.TextPageCriteria;
import gedi.solutions.geode.lucene.function.LuceneSearchFunction;
import gedi.solutions.geode.serialization.EnhancedReflectionSerializer;
import nyla.solutions.core.exception.ConfigException;
import nyla.solutions.core.exception.SystemException;
import nyla.solutions.core.io.IO;
import nyla.solutions.core.operations.ClassPath;
import nyla.solutions.core.patterns.iteration.Paging;
import nyla.solutions.core.util.Config;
import nyla.solutions.core.util.Debugger;
/**
* GemFire (power by Apache Geode) API wrapper.
*
* export SSL_KEYSTORE_PASSWORD=pivotal
export SSL_PROTOCOLS=TLSv1.2
export SSL_TRUSTSTORE_PASSWORD=pivotal
export SSL_KEYSTORE_TYPE=jks
export SSL_CIPHERS=TLS_RSA_WITH_AES_128_GCM_SHA256
export SSL_ENABLED_COMPONENTS=gateway,server,locator,jmx
export SSL_REQUIRE_AUTHENTICATION=true
export SSL_TRUSTSTORE_CLASSPATH_FILE=truststore.jks
export SSL_KEYSTORE_CLASSPATH_FILE=keystore.jks
export LOCATORS=hostname[ports]
* @author Gregory Green
*
*/
public class GeodeClient
{
/**
* GemFire connection object is a Client Cache
*/
private final ClientCache clientCache;
private boolean cachingProxy;
private final ClientRegionFactory, ?> proxyRegionfactory;
private final ClientRegionFactory, ?> cachingRegionfactory;
private static GeodeClient geodeClient = null;
private Map> listenerMap = new Hashtable<>();
protected GeodeClient(boolean cachingProxy, String... classPatterns)
{
this.cachingProxy = cachingProxy;
String name = Config.getProperty(GeodeConfigConstants.NAME_PROP,GeodeClient.class.getSimpleName());
//check for exists client cache
ClientCache cache = null;
try
{
cache = ClientCacheFactory.getAnyInstance();
}
catch(CacheClosedException e)
{
Debugger.println(e.getMessage());
}
try{
if(cache != null)
cache.close(); //close old connection
}catch(Exception e)
{Debugger.println(e.getMessage());}
String className = Config.getProperty(
GeodeConfigConstants.PDX_SERIALIZER_CLASS_NM_PROP,
EnhancedReflectionSerializer.class.getName());
PdxSerializer pdxSerializer = createPdxSerializer(className,classPatterns);
Properties props = new Properties();
try
{
constructSecurity(props);
}
catch(IOException e)
{
throw new ConfigException("Unable to configure security connection details ERROR:"+e.getMessage(),e);
}
ClientCacheFactory factory = new ClientCacheFactory(props);
factory.setPoolSubscriptionEnabled(true)
.setPdxSerializer(pdxSerializer)
.setPdxReadSerialized(GeodeConfigConstants.PDX_READ_SERIALIZED)
.setPoolPRSingleHopEnabled(Config.getPropertyBoolean(
GeodeConfigConstants.POOL_PR_SINGLE_HOP_ENABLED_PROP,true))
.set("log-level", Config.getProperty("log-level","config"))
.set("name", name);
//.addPoolLocator(host, port)
GeodeSettings.getInstance().constructPoolLocator(factory);
this.clientCache = factory.create();
//Caching Proxy
cachingRegionfactory = clientCache.createClientRegionFactory(ClientRegionShortcut.CACHING_PROXY);
proxyRegionfactory = clientCache.createClientRegionFactory(ClientRegionShortcut.PROXY);
}//------------------------------------------------
/**
* Initialize security properties
* @param props the security properties
* @throws IOException
*/
protected static void constructSecurity(Properties props) throws IOException
{
props.setProperty("security-client-auth-init", GeodeConfigAuthInitialize.class.getName()+".create");
//write to file
File sslFile = saveEnvFile(GeodeConfigConstants.SSL_KEYSTORE_CLASSPATH_FILE_PROP);
System.out.println("sslFile:"+sslFile);
File sslTrustStoreFile = saveEnvFile(GeodeConfigConstants.SSL_TRUSTSTORE_CLASSPATH_FILE_PROP);
String sslTrustStoreFilePath = "";
if(sslTrustStoreFile != null)
sslTrustStoreFilePath = sslTrustStoreFile.getAbsolutePath();
props.setProperty("ssl-keystore",(sslFile != null) ? sslFile.getAbsolutePath(): "");
props.setProperty("ssl-keystore-password",Config.getPropertyEnv("ssl-keystore-password",""));
props.setProperty("ssl-truststore",sslTrustStoreFilePath);
props.setProperty("ssl-protocols",Config.getPropertyEnv("ssl-protocols",""));
props.setProperty("ssl-truststore-password",Config.getPropertyEnv("ssl-truststore-password",""));
props.setProperty("ssl-keystore-type",Config.getPropertyEnv("ssl-keystore-type","") );
props.setProperty("ssl-ciphers",Config.getPropertyEnv("ssl-ciphers",""));
props.setProperty("ssl-require-authentication",Config.getPropertyEnv("ssl-require-authentication","") );
props.setProperty("ssl-enabled-components", Config.getPropertyEnv("ssl-enabled-components",""));
}//------------------------------------------------
/**
*
* @param configPropFilePath the property name with the file path
* @return the saved File
* @throws IOException when there is an issue with saving the file
*/
private static File saveEnvFile(String configPropFilePath)
throws IOException
{
String sslKeystorePath = Config.getProperty(configPropFilePath,"");
String fileName = Paths.get(sslKeystorePath).toFile().getName();
if(sslKeystorePath.length() == 0)
return null;
byte[] bytes = IO.readBinaryClassPath(sslKeystorePath);
String sslDirectory = Config.getProperty(GeodeConfigConstants.SSL_KEYSTORE_STORE_DIR_PROP,".");
File sslDirectoryFile = Paths.get(sslDirectory).toFile();
if(!sslDirectoryFile.exists())
{
throw new ConfigException("Configuration property "+GeodeConfigConstants.SSL_KEYSTORE_STORE_DIR_PROP+" "+sslDirectoryFile+" but it does not exist");
}
else if(!sslDirectoryFile.isDirectory())
{
throw new ConfigException("Configuration property "+GeodeConfigConstants.SSL_KEYSTORE_STORE_DIR_PROP+" "+sslDirectoryFile+" but is not a valid directory");
}
File sslFile = Paths.get(sslDirectoryFile+IO.fileSperator()+fileName).toFile();
IO.writeFile(sslFile, bytes);
return sslFile;
}//------------------------------------------------
public Collection select(String oql)
{
return select(oql,null);
}//------------------------------------------------
static PdxSerializer createPdxSerializer(String pdxSerializerClassNm, String... classPatterns )
{
Object [] initArgs = {classPatterns};
return ClassPath.newInstance(pdxSerializerClassNm, initArgs);
}
//------------------------------------------------
/**
* @param the key class
* @param the value class
* @param criteria the search criteria
* @param region the region
* @param filter the filter set
* @return collection of results
*/
@SuppressWarnings({"unchecked", "rawtypes"})
public Paging searchText(TextPageCriteria criteria, Region region, Set filter)
{
try
{
LuceneSearchFunction func = new LuceneSearchFunction();
Execution