| /* |
| * 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. |
| */ |
| |
| #pragma once |
| |
| #ifndef GEODE_INTEGRATION_TEST_THINCLIENTLISTENERINIT_H_ |
| #define GEODE_INTEGRATION_TEST_THINCLIENTLISTENERINIT_H_ |
| |
| #include "fw_dunit.hpp" |
| #include "ThinClientHelper.hpp" |
| #include "TallyListener.hpp" |
| #include "TallyWriter.hpp" |
| #include "TallyLoader.hpp" |
| |
| #define CLIENT1 s1p1 |
| #define CLIENT2 s1p2 |
| #define SERVER1 s2p1 |
| |
| namespace { // NOLINT(google-build-namespaces) |
| |
| using apache::geode::client::Cacheable; |
| |
| using apache::geode::client::testing::TallyListener; |
| using apache::geode::client::testing::TallyLoader; |
| using apache::geode::client::testing::TallyWriter; |
| |
| static bool isLocator = false; |
| static bool isLocalServer = true; |
| static int numberOfLocators = 1; |
| const char* locatorsG = |
| CacheHelper::getLocatorHostPort(isLocator, isLocalServer, numberOfLocators); |
| const char* poolName = "__TESTPOOL1_"; |
| std::shared_ptr<TallyListener> reg1Listener1, reg1Listener2; |
| std::shared_ptr<TallyWriter> reg1Writer1, reg1Writer2; |
| std::shared_ptr<TallyLoader> reg1Loader1, reg1Loader2; |
| int numCreates = 0; |
| int numUpdates = 0; |
| int numLoads = 0; |
| |
| #include "LocatorHelper.hpp" |
| |
| class ThinClientTallyLoader : public TallyLoader { |
| public: |
| ThinClientTallyLoader() : TallyLoader() {} |
| |
| virtual ~ThinClientTallyLoader() = default; |
| |
| std::shared_ptr<Cacheable> load( |
| Region& rp, const std::shared_ptr<CacheableKey>& key, |
| const std::shared_ptr<Serializable>& aCallbackArgument) { |
| int32_t loadValue = std::dynamic_pointer_cast<CacheableInt32>( |
| TallyLoader::load(rp, key, aCallbackArgument)) |
| ->value(); |
| char lstrvalue[32]; |
| sprintf(lstrvalue, "%i", loadValue); |
| auto lreturnValue = CacheableString::create(lstrvalue); |
| if (key && (!rp.getAttributes().getEndpoints().empty() || |
| !rp.getAttributes().getPoolName().empty())) { |
| LOGDEBUG("Putting the value (%s) for local region clients only ", |
| lstrvalue); |
| rp.put(key, lreturnValue); |
| } |
| return std::move(lreturnValue); |
| } |
| }; |
| |
| void setCacheListener(const char* regName, |
| std::shared_ptr<TallyListener> regListener) { |
| auto reg = getHelper()->getRegion(regName); |
| auto attrMutator = reg->getAttributesMutator(); |
| attrMutator->setCacheListener(regListener); |
| } |
| |
| void setCacheLoader(const char* regName, |
| std::shared_ptr<TallyLoader> regLoader) { |
| auto reg = getHelper()->getRegion(regName); |
| auto attrMutator = reg->getAttributesMutator(); |
| attrMutator->setCacheLoader(regLoader); |
| } |
| |
| void setCacheWriter(const char* regName, |
| std::shared_ptr<TallyWriter> regWriter) { |
| auto reg = getHelper()->getRegion(regName); |
| auto attrMutator = reg->getAttributesMutator(); |
| attrMutator->setCacheWriter(regWriter); |
| } |
| |
| void validateEventCount(int line) { |
| LOGINFO("ValidateEvents called from line (%d).", line); |
| ASSERT(reg1Listener1->getCreates() == numCreates, |
| "Got wrong number of creation events."); |
| ASSERT(reg1Listener1->getUpdates() == numUpdates, |
| "Got wrong number of update events."); |
| ASSERT(reg1Loader1->getLoads() == numLoads, |
| "Got wrong number of loader events."); |
| ASSERT(reg1Writer1->getCreates() == numCreates, |
| "Got wrong number of writer events."); |
| } |
| |
| DUNIT_TASK_DEFINITION(SERVER1, StartServer) |
| { |
| if (isLocalServer) { |
| CacheHelper::initServer(1, "cacheserver_notify_subscription.xml"); |
| } |
| LOG("SERVER started"); |
| } |
| END_TASK_DEFINITION |
| |
| DUNIT_TASK_DEFINITION(CLIENT1, InitClientEvents) |
| { |
| numCreates = 0; |
| numUpdates = 0; |
| numLoads = 0; |
| } |
| END_TASK_DEFINITION |
| |
| DUNIT_TASK_DEFINITION(CLIENT1, SetupClient_Pooled_Locator) |
| { |
| initClient(true); |
| reg1Listener1 = std::make_shared<TallyListener>(); |
| createPooledRegion(regionNames[0], false, locatorsG, poolName, true, |
| reg1Listener1); |
| reg1Loader1 = std::make_shared<ThinClientTallyLoader>(); |
| reg1Writer1 = std::make_shared<TallyWriter>(); |
| setCacheLoader(regionNames[0], reg1Loader1); |
| setCacheWriter(regionNames[0], reg1Writer1); |
| } |
| END_TASK_DEFINITION |
| |
| DUNIT_TASK_DEFINITION(CLIENT1, testLoaderAndWriter) |
| { |
| auto regPtr = getHelper()->getRegion(regionNames[0]); |
| auto keyPtr = CacheableKey::create(keys[0]); |
| std::vector<std::shared_ptr<CacheableKey>> keys; |
| keys.push_back(keyPtr); |
| regPtr->registerKeys(keys); |
| |
| /*NIL: Changed the asserion due to the change in invalidate. |
| Now we create new entery for every invalidate event received or |
| localInvalidate call |
| so expect containsKey to returns true insted of false earlier. */ |
| ASSERT(regPtr->containsKey(keyPtr), "Key should found in region."); |
| // now having all the Callbacks set, lets call the loader and writer |
| ASSERT(regPtr->get(keyPtr) != nullptr, "Expected non null value"); |
| |
| auto regEntryPtr = regPtr->getEntry(keyPtr); |
| auto valuePtr = regEntryPtr->getValue(); |
| int val = atoi(valuePtr->toString().c_str()); |
| LOGFINE("val for keyPtr is %d", val); |
| ASSERT(val == 0, "Expected value CacheLoad value should be 0"); |
| numLoads++; |
| numCreates++; |
| |
| validateEventCount(__LINE__); |
| } |
| END_TASK_DEFINITION |
| |
| DUNIT_TASK_DEFINITION(CLIENT1, testCreatesAndUpdates) |
| { |
| auto regPtr = getHelper()->getRegion(regionNames[0]); |
| auto keyPtr1 = CacheableKey::create(keys[1]); |
| auto keyPtr2 = CacheableKey::create(keys[2]); |
| std::vector<std::shared_ptr<CacheableKey>> keys; |
| keys.push_back(keyPtr1); |
| keys.push_back(keyPtr2); |
| regPtr->registerKeys(keys); |
| |
| // Do a create followed by a create on the same key |
| /*NIL: Changed the asserion due to the change in invalidate. |
| Now we create new entery for every invalidate event received or |
| localInvalidate call |
| so expect containsKey to returns true insted of false earlier. |
| and used put call to update value for that key, instead of create call |
| earlier or will get |
| Region::create: Entry already exists in the region */ |
| ASSERT(regPtr->containsKey(keyPtr1), "Key should found in region."); |
| regPtr->put(keyPtr1, vals[1]); |
| numCreates++; |
| validateEventCount(__LINE__); |
| |
| /** |
| see bug #252 |
| try { |
| regPtr->create(keyPtr1, nvals[1]); |
| ASSERT(nullptr, "Expected an EntryExistsException"); |
| } catch(EntryExistsException &) { |
| //Expected Behavior |
| } |
| validateEventCount(__LINE__); |
| **/ |
| |
| // Trigger an update event from a put |
| regPtr->put(keyPtr1, nvals[1]); |
| numUpdates++; |
| validateEventCount(__LINE__); |
| |
| // This put creates a new value, verify update event is not received |
| regPtr->put(keyPtr2, vals[2]); |
| numCreates++; |
| validateEventCount(__LINE__); |
| |
| // Do a get on a preexisting value to confirm no events are triggered |
| regPtr->get(keyPtr2); |
| validateEventCount(__LINE__); |
| } |
| END_TASK_DEFINITION |
| |
| DUNIT_TASK_DEFINITION(CLIENT1, testDestroy) |
| { |
| auto regPtr = getHelper()->getRegion(regionNames[0]); |
| auto keyPtr1 = CacheableKey::create(keys[1]); |
| auto keyPtr2 = CacheableKey::create(keys[2]); |
| regPtr->localInvalidate(keyPtr1); |
| // Verify no listener activity after the invalidate |
| validateEventCount(__LINE__); |
| |
| // Verify after update listener activity after a get on an invalidated value |
| regPtr->get(keyPtr1); |
| auto regEntryPtr = regPtr->getEntry(keyPtr1); |
| auto valuePtr = regEntryPtr->getValue(); |
| int val = atoi(valuePtr->toString().c_str()); |
| LOGFINE("val for keyPtr1 is %d", val); |
| ASSERT(val == 0, "Expected value CacheLoad value should be 0"); |
| numUpdates++; |
| validateEventCount(__LINE__); |
| |
| regPtr->destroy(keyPtr2); |
| regPtr->get(keyPtr2); |
| auto regEntryPtr1 = regPtr->getEntry(keyPtr2); |
| auto valuePtr1 = regEntryPtr1->getValue(); |
| int val1 = atoi(valuePtr1->toString().c_str()); |
| LOGFINE("val1 for keyPtr2 is %d", val1); |
| ASSERT(val1 == 1, "Expected value CacheLoad value should be 1"); |
| numLoads++; |
| numCreates++; |
| validateEventCount(__LINE__); |
| } |
| END_TASK_DEFINITION |
| |
| DUNIT_TASK_DEFINITION(SERVER1, StopServer) |
| { |
| if (isLocalServer) CacheHelper::closeServer(1); |
| LOG("SERVER stopped"); |
| } |
| END_TASK_DEFINITION |
| |
| DUNIT_TASK_DEFINITION(CLIENT1, CloseCache1) |
| { cleanProc(); } |
| END_TASK_DEFINITION |
| |
| } // namespace |
| |
| #endif // GEODE_INTEGRATION_TEST_THINCLIENTLISTENERINIT_H_ |