GEODE-7041: Add FunctionService::OnServers Test in New Framework (#507)
* Add support for server xml config to test framework.
* Allow separate xml config for each server.
* Switch to TestCacheXmlDir for xml files.
* GEODE-7041: Add OnServersWithReplicatedRegionsInPool
* Switch to TestCacheXmlDir for xml files.
diff --git a/cppcache/integration-test/resources/func_cacheserver1_pool.xml b/cppcache/integration-test/resources/func_cacheserver1_pool.xml
index 34d6e0e..b5fefaa 100755
--- a/cppcache/integration-test/resources/func_cacheserver1_pool.xml
+++ b/cppcache/integration-test/resources/func_cacheserver1_pool.xml
@@ -18,7 +18,8 @@
<cache
xmlns="http://geode.apache.org/schema/cache"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://geode.apache.org/schema/cache http://geode.apache.org/schema/cache/cache-1.0.xsd" version="1.0">
- <cache-server port="HOST_PORT1">
+ <!--cache-server host="cod" port="24680" /-->
+ <cache-server port="0">
<group>ServerGroup1</group>
</cache-server>
<pdx read-serialized="true" />
@@ -41,9 +42,6 @@
<class-name>javaobject.MultiGetFunction2</class-name>
</function>
<function>
- <class-name>javaobject.ThinClientRegionExceptionTest</class-name>
- </function>
- <function>
<class-name>javaobject.MultiPutFunction</class-name>
</function>
<function>
diff --git a/cppcache/integration-test/resources/func_cacheserver2_pool.xml b/cppcache/integration-test/resources/func_cacheserver2_pool.xml
index fb1e791..1223c7b 100755
--- a/cppcache/integration-test/resources/func_cacheserver2_pool.xml
+++ b/cppcache/integration-test/resources/func_cacheserver2_pool.xml
@@ -18,7 +18,7 @@
<cache
xmlns="http://geode.apache.org/schema/cache"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://geode.apache.org/schema/cache http://geode.apache.org/schema/cache/cache-1.0.xsd" version="1.0">
- <cache-server port="HOST_PORT2">
+ <cache-server port="0">
<group>ServerGroup1</group>
</cache-server>
<pdx read-serialized="true" />
@@ -76,9 +76,6 @@
<function>
<class-name>javaobject.FEOnRegionPrSHOP_OptimizeForWrite</class-name>
</function>
- <function>
- <class-name>javaobject.ThinClientRegionExceptionTest</class-name>
- </function>
</function-service>
<serialization-registration>
<instantiator id="5200">
diff --git a/cppcache/integration/framework/Cluster.cpp b/cppcache/integration/framework/Cluster.cpp
index b6f4765..f0907e1 100644
--- a/cppcache/integration/framework/Cluster.cpp
+++ b/cppcache/integration/framework/Cluster.cpp
@@ -75,6 +75,7 @@
.withSecurityManager(cluster_.getSecurityManager())
.withUser(cluster_.getUser())
.withPassword(cluster_.getPassword())
+ .withCacheXMLFile(getCacheXMLFile())
.execute();
// std::cout << "server: " << serverAddress_.port << ": started" << std::endl << std::flush;
@@ -89,7 +90,7 @@
started_ = false;
}
-void Cluster::start() {
+void Cluster::start(std::function<void()> extraGfshCommands) {
locators_.reserve(initialLocators_);
for (size_t i = 0; i < initialLocators_; i++) {
locators_.push_back({*this, locators_,
@@ -98,13 +99,20 @@
}
servers_.reserve(initialServers_);
+ std::string xmlFile;
for (size_t i = 0; i < initialServers_; i++) {
+ xmlFile = (cacheXMLFiles_.size() == 0) ? "" :
+ cacheXMLFiles_.size() == 1 ? cacheXMLFiles_[1] :
+ cacheXMLFiles_[i];
+
servers_.push_back(
- {*this, locators_, name_ + "/server/" + std::to_string(i)});
+ {*this, locators_, name_ + "/server/" + std::to_string(i), xmlFile});
}
startLocators();
+ extraGfshCommands();
+
startServers();
// std::cout << "cluster: " << jmxManagerPort_ << ": started" << std::endl;
diff --git a/cppcache/integration/framework/Cluster.h b/cppcache/integration/framework/Cluster.h
index 0545fe9..4578437 100644
--- a/cppcache/integration/framework/Cluster.h
+++ b/cppcache/integration/framework/Cluster.h
@@ -23,14 +23,13 @@
#include <cstdint>
#include <string>
-#include "gtest/gtest.h"
-
#include <geode/Cache.hpp>
#include <geode/PoolManager.hpp>
#include "Framework.h"
#include "GfshExecute.h"
#include "NamedType.h"
+#include "gtest/gtest.h"
class Cluster;
@@ -104,8 +103,11 @@
class Server {
public:
- Server(Cluster &cluster, std::vector<Locator> &locators, std::string name)
- : cluster_(cluster), locators_(locators), name_(std::move(name)) {
+ Server(Cluster &cluster, std::vector<Locator> &locators, std::string name, std::string xmlFile)
+ : cluster_(cluster),
+ locators_(locators),
+ name_(std::move(name)),
+ xmlFile_(xmlFile) {
auto hostname = "localhost";
auto port = static_cast<uint16_t>(0);
serverAddress_ = ServerAddress{hostname, port};
@@ -113,6 +115,8 @@
// start();
}
+ std::string getCacheXMLFile() { return xmlFile_; }
+
~Server() noexcept {
try {
if (started_) {
@@ -129,7 +133,8 @@
locators_(move.locators_),
serverAddress_(move.serverAddress_),
started_(move.started_),
- name_(move.name_) {
+ name_(move.name_),
+ xmlFile_(move.xmlFile_) {
move.started_ = false;
};
// Server &operator=(Server &&other) = default;
@@ -147,6 +152,7 @@
bool started_ = false;
std::string name_;
+ std::string xmlFile_;
};
using LocatorCount = NamedType<size_t, struct LocatorCountParameter>;
@@ -156,6 +162,8 @@
using SecurityManager = NamedType<std::string, struct SecurityManagerParameter>;
using User = NamedType<std::string, struct UserParameter>;
using Password = NamedType<std::string, struct PasswordParameter>;
+using CacheXMLFiles =
+ NamedType<std::vector<std::string>, struct CacheXMLFilesParameter>;
class Cluster {
public:
@@ -167,25 +175,54 @@
::testing::UnitTest::GetInstance()
->current_test_info()
->name()),
- initialLocators, initialServers){};
+ initialLocators, initialServers) {}
+
+ Cluster(LocatorCount initialLocators, ServerCount initialServers,
+ CacheXMLFiles cacheXMLFiles)
+ : name_(std::string(::testing::UnitTest::GetInstance()
+ ->current_test_info()
+ ->test_case_name()) +
+ "/" +
+ ::testing::UnitTest::GetInstance()->current_test_info()->name()),
+ initialLocators_(initialLocators.get()),
+ initialServers_(initialServers.get()),
+ jmxManagerPort_(Framework::getAvailablePort()) {
+ removeServerDirectory();
+ cacheXMLFiles_ = cacheXMLFiles.get();
+ }
Cluster(Name name, LocatorCount initialLocators, ServerCount initialServers)
- : Cluster(Name(name.get()),
- Classpath(""),
- SecurityManager(""),
- User(""),
- Password(""),
- initialLocators, initialServers){};
+ : Cluster(Name(name.get()), Classpath(""), SecurityManager(""), User(""),
+ Password(""), initialLocators, initialServers,
+ CacheXMLFiles({})) {}
- Cluster(Name name,
- Classpath classpath,
- SecurityManager securityManager,
- User user,
- Password password,
- LocatorCount initialLocators,
- ServerCount initialServers) :
- name_(name.get()), classpath_(classpath.get()), securityManager_(securityManager.get()), user_(user.get()), password_(password.get()), initialLocators_(initialLocators.get()), initialServers_(initialServers.get()) {
+ Cluster(Name name, Classpath classpath, SecurityManager securityManager,
+ User user, Password password, LocatorCount initialLocators,
+ ServerCount initialServers, CacheXMLFiles cacheXMLFiles)
+ : name_(name.get()),
+ classpath_(classpath.get()),
+ securityManager_(securityManager.get()),
+ user_(user.get()),
+ password_(password.get()),
+ initialLocators_(initialLocators.get()),
+ initialServers_(initialServers.get()) {
+ jmxManagerPort_ = Framework::getAvailablePort();
+ cacheXMLFiles_ = cacheXMLFiles.get();
+ removeServerDirectory();
+ start();
+ };
+
+ Cluster(Name name, Classpath classpath, SecurityManager securityManager,
+ User user, Password password, LocatorCount initialLocators,
+ ServerCount initialServers)
+ : name_(name.get()),
+ classpath_(classpath.get()),
+ securityManager_(securityManager.get()),
+ user_(user.get()),
+ password_(password.get()),
+ initialLocators_(initialLocators.get()),
+ initialServers_(initialServers.get()) {
jmxManagerPort_ = Framework::getAvailablePort();
removeServerDirectory();
@@ -211,7 +248,7 @@
std::to_string(jmxManagerPort_) + "]";
}
- void start();
+ void start(std::function<void()> fn = []() {});
void stop();
@@ -228,7 +265,8 @@
}
apache::geode::client::Cache createCache(
- const std::unordered_map<std::string, std::string> &properties, bool subscriptionEnabled) {
+ const std::unordered_map<std::string, std::string> &properties,
+ bool subscriptionEnabled) {
using apache::geode::client::CacheFactory;
CacheFactory cacheFactory;
@@ -241,7 +279,9 @@
.set("statistic-sampling-enabled", "false")
.create();
- auto poolFactory = cache.getPoolManager().createFactory().setSubscriptionEnabled(subscriptionEnabled);
+ auto poolFactory =
+ cache.getPoolManager().createFactory().setSubscriptionEnabled(
+ subscriptionEnabled);
applyLocators(poolFactory);
poolFactory.create("default");
@@ -257,25 +297,19 @@
Gfsh &getGfsh() noexcept { return gfsh_; }
- std::vector<Server>& getServers() {
- return servers_;
- }
+ std::vector<Server> &getServers() { return servers_; }
- std::string& getClasspath() {
- return classpath_;
- }
+ std::vector<Locator> &getLocators() { return locators_; }
- std::string& getSecurityManager() {
- return securityManager_;
- }
+ std::string &getClasspath() { return classpath_; }
- std::string& getUser() {
- return user_;
- }
+ std::string &getSecurityManager() { return securityManager_; }
- std::string& getPassword() {
- return password_;
- }
+ std::string &getUser() { return user_; }
+
+ std::string &getPassword() { return password_; }
+
+ std::vector<std::string> &getCacheXMLFiles() { return cacheXMLFiles_; }
private:
std::string name_;
@@ -283,6 +317,7 @@
std::string securityManager_;
std::string user_;
std::string password_;
+ std::vector<std::string> cacheXMLFiles_;
size_t initialLocators_;
std::vector<Locator> locators_;
diff --git a/cppcache/integration/framework/Gfsh.h b/cppcache/integration/framework/Gfsh.h
index 182434e..7df7ebd 100644
--- a/cppcache/integration/framework/Gfsh.h
+++ b/cppcache/integration/framework/Gfsh.h
@@ -150,51 +150,51 @@
Server &withName(const std::string &name) {
command_ += " --name=" + name;
return *this;
- };
+ }
Server &withDir(const std::string &dir) {
command_ += " --dir=" + dir;
return *this;
- };
+ }
Server &withBindAddress(const std::string &bindAddress) {
command_ += " --bind-address=" + bindAddress;
return *this;
- };
+ }
Server &withPort(uint16_t serverPort) {
command_ += " --server-port=" + std::to_string(serverPort);
return *this;
- };
+ }
Server &withLocators(const std::string locators) {
command_ += " --locators=" + locators;
return *this;
- };
+ }
Server &withLogLevel(const std::string logLevel) {
command_ += " --log-level=" + logLevel;
return *this;
- };
+ }
Server &withMaxHeap(const std::string maxHeap) {
command_ += " --max-heap=" + maxHeap;
return *this;
- };
+ }
Server &withClasspath(const std::string classpath) {
if (!classpath.empty()) {
command_ += " --classpath=" + classpath;
}
return *this;
- };
+ }
Server &withSecurityManager(const std::string securityManager) {
if (!securityManager.empty()) {
command_ += " --J=-Dgemfire.security-manager=" + securityManager;
}
return *this;
- };
+ }
Server &withUser(const std::string user) {
if (!user.empty()) {
@@ -202,14 +202,21 @@
}
return *this;
- };
+ }
Server &withPassword(const std::string password) {
if (!password.empty()) {
command_ += " --password=" + password;
}
return *this;
- };
+ }
+
+ Server &withCacheXMLFile(const std::string file) {
+ if (!file.empty()) {
+ command_ += " --cache-xml-file=" + file;
+ }
+ return *this;
+ }
};
private:
diff --git a/cppcache/integration/test/CMakeLists.txt b/cppcache/integration/test/CMakeLists.txt
index aec2fa7..607fb08 100644
--- a/cppcache/integration/test/CMakeLists.txt
+++ b/cppcache/integration/test/CMakeLists.txt
@@ -80,6 +80,13 @@
endforeach()
endif()
+configure_file(
+ ${CMAKE_CURRENT_SOURCE_DIR}/func_cacheserver1_pool.xml
+ ${CMAKE_CURRENT_BINARY_DIR}/func_cacheserver1_pool.xml COPYONLY)
+configure_file(
+ ${CMAKE_CURRENT_SOURCE_DIR}/func_cacheserver2_pool.xml
+ ${CMAKE_CURRENT_BINARY_DIR}/func_cacheserver2_pool.xml COPYONLY)
+
set_target_properties(cpp-integration-test PROPERTIES
CXX_VISIBILITY_PRESET hidden
VISIBILITY_INLINES_HIDDEN ON
diff --git a/cppcache/integration/test/FunctionExecutionTest.cpp b/cppcache/integration/test/FunctionExecutionTest.cpp
index 8640882..d731c90 100644
--- a/cppcache/integration/test/FunctionExecutionTest.cpp
+++ b/cppcache/integration/test/FunctionExecutionTest.cpp
@@ -31,6 +31,8 @@
using apache::geode::client::Cache;
using apache::geode::client::Cacheable;
+using apache::geode::client::CacheableArrayList;
+using apache::geode::client::CacheableString;
using apache::geode::client::CacheableVector;
using apache::geode::client::CacheFactory;
using apache::geode::client::FunctionExecutionException;
@@ -39,6 +41,7 @@
using apache::geode::client::Region;
using apache::geode::client::RegionShortcut;
using apache::geode::client::ResultCollector;
+const int ON_SERVERS_TEST_REGION_ENTRIES_SIZE = 34;
std::shared_ptr<Region> setupRegion(Cache &cache) {
auto region = cache.createRegionFactory(RegionShortcut::PROXY)
@@ -131,8 +134,8 @@
}
TEST(FunctionExecutionTest,
- FunctionReturnsObjectWhichCantBeDeserializedOnServer) {
- Cluster cluster{LocatorCount{1}, ServerCount{2}};
+ Disabled_FunctionReturnsObjectWhichCantBeDeserializedOnServer) {
+ Cluster cluster{LocatorCount{1}, ServerCount{1}};
cluster.getGfsh()
.create()
.region()
@@ -145,20 +148,93 @@
.jar(getFrameworkString(FrameworkVariable::JavaObjectJarPath))
.execute();
- auto cache = CacheFactory().set("log-level", "none").create();
- auto pool = cache.getPoolManager()
- .createFactory()
- .addLocator("localhost", 10334)
- .create("pool");
+ auto cache = cluster.createCache();
auto region = cache.createRegionFactory(RegionShortcut::PROXY)
- .setPoolName("pool")
+ .setPoolName("default")
.create("region");
const char *GetScopeSnapshotsFunction =
"executeFunction_SendObjectWhichCantBeDeserialized";
auto functionService = FunctionService::onRegion(region);
ASSERT_THROW(functionService.execute(GetScopeSnapshotsFunction),
- NotConnectedException);
+ apache::geode::client::IllegalStateException);
cache.close();
}
+
+const std::vector<std::string> serverResultsToStrings(
+ std::shared_ptr<CacheableVector> serverResults) {
+ std::vector<std::string> resultList;
+ for (auto result : *serverResults) {
+ auto resultArray = std::dynamic_pointer_cast<CacheableArrayList>(result);
+ for (decltype(resultArray->size()) i = 0; i < resultArray->size(); i++) {
+ auto value =
+ std::dynamic_pointer_cast<CacheableString>(resultArray->at(i));
+ resultList.push_back(value->toString());
+ }
+ }
+
+ return resultList;
+}
+TEST(FunctionExecutionTest, OnServersWithReplicatedRegionsInPool) {
+ Cluster cluster{
+ LocatorCount{1}, ServerCount{2},
+ CacheXMLFiles(
+ {std::string(getFrameworkString(FrameworkVariable::TestCacheXmlDir)) +
+ "/func_cacheserver1_pool.xml",
+ std::string(getFrameworkString(FrameworkVariable::TestCacheXmlDir)) +
+ "/func_cacheserver2_pool.xml"})};
+
+ cluster.start([&]() {
+ cluster.getGfsh()
+ .deploy()
+ .jar(getFrameworkString(FrameworkVariable::JavaObjectJarPath))
+ .execute();
+ });
+
+ auto cache = CacheFactory().set("log-level", "none").create();
+ auto poolFactory = cache.getPoolManager().createFactory();
+
+ cluster.applyLocators(poolFactory);
+
+ auto pool = poolFactory.create("pool");
+
+ auto region = cache.createRegionFactory(RegionShortcut::PROXY)
+ .setPoolName("pool")
+ .create("partition_region");
+
+ for (int i = 0; i < ON_SERVERS_TEST_REGION_ENTRIES_SIZE; i++) {
+ region->put("KEY--" + std::to_string(i), "VALUE--" + std::to_string(i));
+ }
+
+ // Filter on odd keys
+ auto routingObj = CacheableVector::create();
+ for (int i = 0; i < ON_SERVERS_TEST_REGION_ENTRIES_SIZE; i++) {
+ if (i % 2 == 0) {
+ continue;
+ }
+ routingObj->push_back(CacheableString::create("KEY--" + std::to_string(i)));
+ }
+
+ auto execution = FunctionService::onServers(pool);
+
+ auto rc = execution.withArgs(routingObj).execute("MultiGetFunctionI");
+ auto executeFunctionResult = rc->getResult();
+
+ // Executed on 2 servers, we should have two sets of results
+ ASSERT_EQ(executeFunctionResult->size(), 2);
+
+ auto resultList = serverResultsToStrings(executeFunctionResult);
+
+ // We filtered on odd keys, we should have 1/2 as many results in each set,
+ // for a total of ON_SERVERS_TEST_REGION_ENTRIES_SIZE results
+ ASSERT_EQ(resultList.size(), ON_SERVERS_TEST_REGION_ENTRIES_SIZE);
+
+ for (decltype(resultList.size()) i = 0;
+ i < ON_SERVERS_TEST_REGION_ENTRIES_SIZE / 2; i++) {
+ // Each entry in the first result set (first half of this vector) should be
+ // equal to its corresponding entry in the second set (2nd half of vector)
+ ASSERT_EQ(resultList[i],
+ resultList[i + ON_SERVERS_TEST_REGION_ENTRIES_SIZE / 2]);
+ }
+}
diff --git a/cppcache/integration/test/func_cacheserver1_pool.xml b/cppcache/integration/test/func_cacheserver1_pool.xml
new file mode 100644
index 0000000..820faa5
--- /dev/null
+++ b/cppcache/integration/test/func_cacheserver1_pool.xml
@@ -0,0 +1,86 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You 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.
+-->
+<cache
+ xmlns="http://geode.apache.org/schema/cache"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://geode.apache.org/schema/cache http://geode.apache.org/schema/cache/cache-1.0.xsd" version="1.0">
+ <!--cache-server host="cod" port="24680" /-->
+ <cache-server port="HOST_PORT1">
+ <group>ServerGroup1</group>
+ </cache-server>
+ <pdx read-serialized="true" />
+ <region name='partition_region'>
+ <region-attributes data-policy="partition">
+ <partition-attributes redundant-copies="1" startup-recovery-delay="1"/>
+ </region-attributes>
+ </region>
+ <function-service>
+ <function>
+ <class-name>javaobject.MultiGetFunctionI</class-name>
+ </function>
+ <function>
+ <class-name>javaobject.MultiPutFunctionI</class-name>
+ </function>
+ <function>
+ <class-name>javaobject.MultiGetFunction</class-name>
+ </function>
+ <function>
+ <class-name>javaobject.MultiGetFunction2</class-name>
+ </function>
+ <function>
+ <class-name>javaobject.MultiPutFunction</class-name>
+ </function>
+ <function>
+ <class-name>javaobject.RegionOperationsFunction</class-name>
+ </function>
+ <function>
+ <class-name>javaobject.RegionOperationsHAFunction</class-name>
+ </function>
+ <function>
+ <class-name>javaobject.ExceptionHandlingFunction</class-name>
+ </function>
+ <function>
+ <class-name>javaobject.OnServerHAExceptionFunction</class-name>
+ </function>
+ <function>
+ <class-name>javaobject.OnServerHAShutdownFunction</class-name>
+ </function>
+ <function>
+ <class-name>javaobject.PdxFunctionTest</class-name>
+ </function>
+ <function>
+ <class-name>javaobject.SingleStrGetFunction</class-name>
+ </function>
+ <function>
+ <class-name>javaobject.executeFunction_SendException</class-name>
+ </function>
+ <function>
+ <class-name>javaobject.FEOnRegionPrSHOP</class-name>
+ </function>
+ <function>
+ <class-name>javaobject.FEOnRegionPrSHOP_OptimizeForWrite</class-name>
+ </function>
+ <function>
+ <class-name>javaobject.RegionOperationsHAFunctionPrSHOP</class-name>
+ </function>
+ </function-service>
+ <serialization-registration>
+ <instantiator id="5200">
+ <class-name>javaobject.InstantiatorTest</class-name>
+ </instantiator>
+ </serialization-registration>
+</cache>
\ No newline at end of file
diff --git a/cppcache/integration/test/func_cacheserver2_pool.xml b/cppcache/integration/test/func_cacheserver2_pool.xml
new file mode 100644
index 0000000..354b1ff
--- /dev/null
+++ b/cppcache/integration/test/func_cacheserver2_pool.xml
@@ -0,0 +1,85 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You 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.
+-->
+<cache
+ xmlns="http://geode.apache.org/schema/cache"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://geode.apache.org/schema/cache http://geode.apache.org/schema/cache/cache-1.0.xsd" version="1.0">
+ <cache-server port="HOST_PORT2">
+ <group>ServerGroup1</group>
+ </cache-server>
+ <pdx read-serialized="true" />
+ <region name='partition_region'>
+ <region-attributes data-policy="partition">
+ <partition-attributes redundant-copies="1" startup-recovery-delay="1"/>
+ </region-attributes>
+ </region>
+ <function-service>
+ <function>
+ <class-name>javaobject.MultiGetFunctionI</class-name>
+ </function>
+ <function>
+ <class-name>javaobject.MultiPutFunctionI</class-name>
+ </function>
+ <function>
+ <class-name>javaobject.MultiGetFunction</class-name>
+ </function>
+ <function>
+ <class-name>javaobject.MultiGetFunction2</class-name>
+ </function>
+ <function>
+ <class-name>javaobject.MultiPutFunction</class-name>
+ </function>
+ <function>
+ <class-name>javaobject.RegionOperationsHAFunction</class-name>
+ </function>
+ <function>
+ <class-name>javaobject.RegionOperationsFunction</class-name>
+ </function>
+ <function>
+ <class-name>javaobject.ExceptionHandlingFunction</class-name>
+ </function>
+ <function>
+ <class-name>javaobject.OnServerHAExceptionFunction</class-name>
+ </function>
+ <function>
+ <class-name>javaobject.OnServerHAShutdownFunction</class-name>
+ </function>
+ <function>
+ <class-name>javaobject.SingleStrGetFunction</class-name>
+ </function>
+ <function>
+ <class-name>javaobject.executeFunction_SendException</class-name>
+ </function>
+ <function>
+ <class-name>javaobject.RegionOperationsHAFunctionPrSHOP</class-name>
+ </function>
+ <function>
+ <class-name>javaobject.PdxFunctionTest</class-name>
+ </function>
+ <function>
+ <class-name>javaobject.FEOnRegionPrSHOP</class-name>
+ </function>
+ <function>
+ <class-name>javaobject.FEOnRegionPrSHOP_OptimizeForWrite</class-name>
+ </function>
+ </function-service>
+ <serialization-registration>
+ <instantiator id="5200">
+ <class-name>javaobject.InstantiatorTest</class-name>
+ </instantiator>
+ </serialization-registration>
+</cache>
\ No newline at end of file