Skip to content

Commit

Permalink
Force bundle cache update when using a different bundle location.
Browse files Browse the repository at this point in the history
  • Loading branch information
PengZheng committed Aug 2, 2023
1 parent 8f08933 commit 523a31a
Show file tree
Hide file tree
Showing 7 changed files with 52 additions and 33 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -147,18 +147,6 @@ TEST_F(CelixBundleCacheErrorInjectionTestSuite, SystemArchiveCreateErrorTest) {
EXPECT_EQ(CELIX_SUCCESS, celix_bundleCache_destroy(cache));
}

TEST_F(CelixBundleCacheErrorInjectionTestSuite, ArchiveDestroyErrorTest) {
celix_bundle_cache_t* cache = nullptr;
createCache(&cache);
bundle_archive_t* archive = nullptr;
EXPECT_EQ(CELIX_SUCCESS, celix_bundleCache_createArchive(cache, 1, SIMPLE_TEST_BUNDLE1_LOCATION, &archive));
celix_ei_expect_celix_utils_deleteDirectory((void*)celix_bundleCache_destroyArchive, 1, CELIX_FILE_IO_EXCEPTION);
std::string storeRoot = celix_bundleArchive_getPersistentStoreRoot(archive);
EXPECT_EQ(CELIX_FILE_IO_EXCEPTION, celix_bundleCache_destroyArchive(cache, archive, true));
EXPECT_TRUE(celix_utils_directoryExists(storeRoot.c_str()));
EXPECT_EQ(CELIX_SUCCESS, celix_bundleCache_destroy(cache));
}

TEST_F(CelixBundleCacheErrorInjectionTestSuite, CreateBundleArchivesCacheErrorTest) {
celix_bundle_cache_t* cache = nullptr;
celix_properties_set(fw.configurationMap, CELIX_AUTO_START_1, SIMPLE_TEST_BUNDLE1_LOCATION);
Expand Down
8 changes: 5 additions & 3 deletions libs/framework/gtest/src/CelixBundleCacheTestSuite.cc
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,8 @@ TEST_F(CelixBundleCacheTestSuite, ArchiveCreateDestroyTest) {
EXPECT_TRUE(celix_bundleCache_isBundleIdAlreadyUsed(fw.cache, 1));
std::string loc = celix_bundleArchive_getPersistentStoreRoot(archive);
EXPECT_TRUE(celix_utils_directoryExists(loc.c_str()));
EXPECT_EQ(CELIX_SUCCESS, celix_bundleCache_destroyArchive(fw.cache, archive, true));
celix_bundleArchive_invalidate(archive);
celix_bundleCache_destroyArchive(fw.cache, archive);
EXPECT_EQ(-1, celix_bundleCache_findBundleIdForLocation(fw.cache, SIMPLE_TEST_BUNDLE1_LOCATION));
EXPECT_FALSE(celix_bundleCache_isBundleIdAlreadyUsed(fw.cache, 1));
EXPECT_FALSE(celix_utils_directoryExists(loc.c_str()));
Expand All @@ -70,7 +71,7 @@ TEST_F(CelixBundleCacheTestSuite, NonPermanentDestroyTest) {
EXPECT_NE(nullptr, archive);
std::string loc = celix_bundleArchive_getPersistentStoreRoot(archive);
EXPECT_TRUE(celix_utils_directoryExists(loc.c_str()));
EXPECT_EQ(CELIX_SUCCESS, celix_bundleCache_destroyArchive(fw.cache, archive, false));
celix_bundleCache_destroyArchive(fw.cache, archive);
EXPECT_EQ(1, celix_bundleCache_findBundleIdForLocation(fw.cache, SIMPLE_TEST_BUNDLE1_LOCATION));
EXPECT_TRUE(celix_bundleCache_isBundleIdAlreadyUsed(fw.cache, 1));
EXPECT_TRUE(celix_utils_directoryExists(loc.c_str()));
Expand All @@ -85,7 +86,8 @@ TEST_F(CelixBundleCacheTestSuite, SystemArchiveCreateDestroyTest) {
EXPECT_EQ(CELIX_SUCCESS, bundleArchive_getArchiveRoot(archive, &archiveRoot));
EXPECT_EQ(nullptr, archiveRoot);
EXPECT_EQ(nullptr, celix_bundleArchive_getLocation(archive));
EXPECT_EQ(CELIX_SUCCESS, celix_bundleCache_destroyArchive(fw.cache, archive, true));
celix_bundleArchive_invalidate(archive);
celix_bundleCache_destroyArchive(fw.cache, archive);
}

TEST_F(CelixBundleCacheTestSuite, CreateBundleArchivesCacheTest) {
Expand Down
33 changes: 30 additions & 3 deletions libs/framework/src/bundle_archive.c
Original file line number Diff line number Diff line change
Expand Up @@ -54,10 +54,10 @@ struct bundleArchive {
char* resourceCacheRoot;
char* bundleSymbolicName; // read from the manifest
char* bundleVersion; // read from the manifest

celix_thread_mutex_t lock; // protects below and saving of bundle state properties
bundle_revision_t* revision; // the current revision
char* location;
bool cacheValid; // is the cache valid (e.g. not deleted)
bool valid; // is the archive valid (e.g. not deleted)
};

static celix_status_t celix_bundleArchive_storeBundleStateProperties(bundle_archive_pt archive) {
Expand Down Expand Up @@ -304,7 +304,8 @@ celix_status_t celix_bundleArchive_create(celix_framework_t* fw, const char *arc
goto store_prop_failed;
}
}

archive->cacheValid = true;
archive->valid = true;
*bundle_archive = archive;
return CELIX_SUCCESS;
store_prop_failed:
Expand Down Expand Up @@ -466,3 +467,29 @@ const char* celix_bundleArchive_getCurrentRevisionRoot(bundle_archive_t* archive
}


void celix_bundleArchive_invalidate(bundle_archive_pt archive) {
archive->valid = false;
archive->cacheValid = false;
}

void celix_bundleArchive_invalidateCache(bundle_archive_pt archive) {
archive->cacheValid = false;
}

bool celix_bundleArchive_isCacheValid(bundle_archive_pt archive) {
return archive->cacheValid;
}

void celix_bundleArchive_removeInvalidDirs(bundle_archive_pt archive) {
if (archive->id == CELIX_FRAMEWORK_BUNDLE_ID) {
return;
}
if (!archive->valid) {
celix_status_t status = CELIX_SUCCESS;
const char* err = NULL;
status = celix_utils_deleteDirectory(archive->archiveRoot, &err);
framework_logIfError(archive->fw->logger, status, NULL, "Failed to remove invalid archive root '%s': %s", archive->archiveRoot, err);
} else if (!archive->cacheValid){
(void)celix_bundleArchive_removeResourceCache(archive);
}
}
5 changes: 5 additions & 0 deletions libs/framework/src/bundle_archive_private.h
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,11 @@ const char* celix_bundleArchive_getPersistentStoreRoot(bundle_archive_t *archive
*/
const char* celix_bundleArchive_getCurrentRevisionRoot(bundle_archive_pt archive);

void celix_bundleArchive_invalidate(bundle_archive_pt archive);
void celix_bundleArchive_invalidateCache(bundle_archive_pt archive);
bool celix_bundleArchive_isCacheValid(bundle_archive_pt archive);
void celix_bundleArchive_removeInvalidDirs(bundle_archive_pt archive);

#ifdef __cplusplus
}
#endif
Expand Down
12 changes: 5 additions & 7 deletions libs/framework/src/celix_bundle_cache.c
Original file line number Diff line number Diff line change
Expand Up @@ -230,18 +230,16 @@ celix_status_t celix_bundleCache_createSystemArchive(celix_framework_t* fw, bund
return celix_bundleCache_createArchive(fw->cache, CELIX_FRAMEWORK_BUNDLE_ID, NULL, archive);
}

celix_status_t celix_bundleCache_destroyArchive(celix_bundle_cache_t* cache, bundle_archive_pt archive, bool permanent) {
celix_status_t status = CELIX_SUCCESS;
const char* loc = NULL;
void celix_bundleCache_destroyArchive(celix_bundle_cache_t* cache, bundle_archive_pt archive) {
celixThreadMutex_lock(&cache->mutex);
if (permanent) {
if (!celix_bundleArchive_isCacheValid(archive)) {
const char* loc = NULL;
(void) bundleArchive_getLocation(archive, &loc);
(void) celix_stringHashMap_remove(cache->locationToBundleIdLookupMap, loc);
status = bundleArchive_closeAndDelete(archive);
}
(void)celix_bundleArchive_removeInvalidDirs(archive);
celixThreadMutex_unlock(&cache->mutex);
(void) bundleArchive_destroy(archive);
return status;
bundleArchive_destroy(archive);
}

/**
Expand Down
9 changes: 2 additions & 7 deletions libs/framework/src/celix_bundle_cache.h
Original file line number Diff line number Diff line change
Expand Up @@ -91,16 +91,11 @@ celix_status_t celix_bundleCache_createSystemArchive(celix_framework_t* fw, bund

/**
* @brief Destroy the archive from the cache.
* It releases all resources allocated in celix_bundleCache_createArchive and deletes the archive directory if requested.
* It releases all resources allocated in celix_bundleCache_createArchive and deletes the invalid directories if needed.
* @param [in] cache The bundle cache to destroy archive from.
* @param [in] archive The archive to destroy.
* @param [in] permanent Whether the archive directory should be deleted or not.
* @return Status code indication failure or success:
* - CELIX_SUCCESS when no errors are encountered.
* - CELIX_FILE_IO_EXCEPTION when root of the archive is not a directory.
* - errno when the directory cannot be deleted for other reasons, check error codes of fts_open/fts_read/remove.
*/
celix_status_t celix_bundleCache_destroyArchive(celix_bundle_cache_t* cache, bundle_archive_pt archive, bool permanent);
void celix_bundleCache_destroyArchive(celix_bundle_cache_t* cache, bundle_archive_pt archive);

/**
* @brief Deletes the entire bundle cache.
Expand Down
6 changes: 5 additions & 1 deletion libs/framework/src/framework.c
Original file line number Diff line number Diff line change
Expand Up @@ -2010,7 +2010,10 @@ static celix_status_t celix_framework_uninstallBundleEntryImpl(celix_framework_t
celix_framework_waitForEmptyEventQueue(framework); //to ensure that the uninstall event is triggered and handled
(void)bundle_closeModules(bnd);
(void)bundle_destroy(bnd);
(void)celix_bundleCache_destroyArchive(framework->cache, archive, permanent);
if(permanent) {
celix_bundleArchive_invalidate(archive);
}
(void)celix_bundleCache_destroyArchive(framework->cache, archive);
}
framework_logIfError(framework->logger, status, "", "Cannot uninstall bundle");
return status;
Expand Down Expand Up @@ -2359,6 +2362,7 @@ celix_status_t celix_framework_updateBundleEntry(celix_framework_t* framework,
status = CELIX_ILLEGAL_STATE;
break;
}
celix_bundleArchive_invalidateCache(celix_bundle_getArchive(bndEntry->bnd));
}
status = celix_framework_uninstallBundleEntryImpl(framework, bndEntry, false);
if (status != CELIX_SUCCESS) {
Expand Down

0 comments on commit 523a31a

Please sign in to comment.