blob: 11fa16e69a2a28223717cc2aa8a3c1acc92897d4 [file]
/* 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.
*/
#include <gtest/gtest.h>
#include <geode/Cache.hpp>
#include <geode/CacheFactory.hpp>
#include <geode/CacheListener.hpp>
#include <geode/PoolManager.hpp>
#include <geode/QueryService.hpp>
#include <geode/RegionFactory.hpp>
#include <geode/RegionShortcut.hpp>
#include "framework/Cluster.h"
#include "framework/Framework.h"
#include "framework/Gfsh.h"
namespace {
using apache::geode::client::Cache;
using apache::geode::client::CacheableInt16;
using apache::geode::client::CacheFactory;
using apache::geode::client::CacheListener;
using apache::geode::client::NotConnectedException;
using apache::geode::client::PdxInstance;
using apache::geode::client::Region;
using apache::geode::client::RegionEvent;
using apache::geode::client::RegionShortcut;
using apache::geode::client::SelectResults;
static bool isDisconnected = false;
class RegionListener : public CacheListener {
public:
void waitConnected() {
std::unique_lock<decltype(mutex_)> lock{mutex_};
status_cv_.wait(lock, [this] { return status_; });
}
void waitDisconnected() {
std::unique_lock<decltype(mutex_)> lock{mutex_};
status_cv_.wait(lock, [this] { return !status_; });
}
protected:
void afterRegionDisconnected(Region&) override {
std::unique_lock<decltype(mutex_)> lock{mutex_};
status_ = false;
status_cv_.notify_all();
}
void afterRegionLive(const RegionEvent&) override {
std::unique_lock<decltype(mutex_)> lock{mutex_};
status_ = true;
status_cv_.notify_all();
}
protected:
bool status_;
std::mutex mutex_;
std::condition_variable status_cv_;
};
Cache createTestCache() {
CacheFactory cacheFactory;
return cacheFactory.set("log-level", "none")
.set("connect-timeout", "2s")
.set("statistic-sampling-enabled", "false")
.set("on-client-disconnect-clear-pdxType-Ids", "true")
.setPdxReadSerialized(true)
.create();
}
void createTestPool(Cluster& cluster, Cache& cache) {
auto poolFactory = cache.getPoolManager()
.createFactory()
.setReadTimeout(std::chrono::seconds{1})
.setPingInterval(std::chrono::seconds{5})
.setSubscriptionEnabled(true);
cluster.applyLocators(poolFactory);
poolFactory.create("pool");
}
std::shared_ptr<Region> createTestRegion(
Cache& cache, std::shared_ptr<RegionListener> listener) {
auto regionFactory = cache.createRegionFactory(RegionShortcut::PROXY);
return regionFactory.setPoolName("pool").setCacheListener(listener).create(
"region");
}
std::shared_ptr<PdxInstance> createTestPdxInstance(Cache& cache,
const std::string& entry) {
auto factory = cache.createPdxInstanceFactory("__GEMFIRE_JSON", false);
return factory.writeString("entryName", entry)
.writeInt("int-value", -1)
.create();
}
TEST(PdxTypeRegistryTest, cleanupOnClusterRestart) {
Cluster cluster{LocatorCount{1}, ServerCount{2}};
cluster.start();
auto& gfsh = cluster.getGfsh();
gfsh.create().region().withName("region").withType("PARTITION").execute();
auto listener = std::make_shared<RegionListener>();
auto cache = createTestCache();
createTestPool(cluster, cache);
auto qs = cache.getQueryService("pool");
auto region = createTestRegion(cache, listener);
std::string key = "before-shutdown";
region->put(key, createTestPdxInstance(cache, key));
// Shutdown and wait for some time
gfsh.shutdown().execute();
listener->waitDisconnected();
std::this_thread::sleep_for(std::chrono::seconds{15});
for (auto& server : cluster.getServers()) {
server.start();
}
listener->waitConnected();
key = "after-restart";
region->put(key, createTestPdxInstance(cache, key));
// If PdxTypeRegistry was cleaned up, then the PdxType should have been
// registered in the new cluster
std::shared_ptr<SelectResults> result;
auto query =
qs->newQuery("SELECT * FROM /region WHERE entryName = '" + key + "'");
EXPECT_NO_THROW(result = query->execute());
EXPECT_TRUE(result);
EXPECT_GT(result->size(), 0);
}
} // namespace