Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[g11n-java-client] Fix for issue #717 - non-supported locales trigger a request to VIP service in a separate thread for every getMessage/getMessages request #738

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2019 VMware, Inc.
* Copyright 2019-2020 VMware, Inc.
* SPDX-License-Identifier: EPL-2.0
*/
package com.vmware.vipclient.i18n.messages.service;
Expand Down Expand Up @@ -105,14 +105,18 @@ public MessageCacheItem getMessages(Iterator<Locale> fallbackLocalesIter) {
MessageCacheItem cacheItem = null;
if (cacheService.isContainComponent()) { // Item is in cache
cacheItem = cacheService.getCacheOfComponent();
if (cacheItem.isExpired()) { // cacheItem has expired
if (cacheItem.getCachedData().isEmpty()) { // This means that the data to be used is from a fallback locale.
// If expired, try to first create and store cacheItem for the requested locale in a separate thread.
if (cacheItem.isExpired())
this.createCacheItemTask(null); // Pass null so that locale fallback will not be applied.

// Use cached data of cacheItem.getLocale() --> fallback locale
MessagesDTO fallbackLocaleDTO = new MessagesDTO(dto.getComponent(), cacheItem.getLocale(), dto.getProductID(), dto.getVersion());
cacheItem = new ComponentService(fallbackLocaleDTO).getMessages(null);
} else if (cacheItem.isExpired()) {
// Refresh the cacheItem in a separate thread
refreshCacheItemTask(cacheItem);
}
// If the cacheItem is for a fallback locale, create and store cacheItem for the requested locale in a separate thread.
if (!LocaleUtility.isSameLocale(cacheItem.getLocale(), this.dto.getLocale())) {
this.createCacheItemTask(fallbackLocalesIter);
}
} else { // Item is not in cache. Create and store cacheItem for the requested locale
cacheItem = createCacheItem(fallbackLocalesIter);
}
Expand All @@ -122,7 +126,7 @@ public MessageCacheItem getMessages(Iterator<Locale> fallbackLocalesIter) {
/**
* Creates a new MessageCacheItem for the DTO and stores it in cache.
*
* @param fallbackLocalesIter The fallback locale queue to use in case of failure.
* @param fallbackLocalesIter The fallback locale queue to use in case of failure. If null, no locale fallback will be applied.
*
*/
private MessageCacheItem createCacheItem(Iterator<Locale> fallbackLocalesIter) {
Expand All @@ -134,11 +138,13 @@ private MessageCacheItem createCacheItem(Iterator<Locale> fallbackLocalesIter) {
if (!cacheItem.getCachedData().isEmpty()) {
cacheService.addCacheOfComponent(cacheItem);
} else if (!dto.getLocale().equals(ConstantsKeys.SOURCE) && fallbackLocalesIter!=null && fallbackLocalesIter.hasNext()) {
// If failed to fetch message for the requetsed DTO, use MessageCacheItem of the next fallback locale.
// If failed to fetch message for the requested DTO, use MessageCacheItem of the next fallback locale.
MessagesDTO fallbackLocaleDTO = new MessagesDTO(dto.getComponent(), fallbackLocalesIter.next().toLanguageTag(), dto.getProductID(), dto.getVersion());
cacheItem = new ComponentService(fallbackLocaleDTO).getMessages(fallbackLocalesIter);
if (!cacheItem.getCachedData().isEmpty()) {
cacheService.addCacheOfComponent(cacheItem);
// Cache a copy of the fallback locale's cacheItem, but with only the locale and maxAgeMillis. Use current timestamp.
MessageCacheItem cacheItemCopy = new MessageCacheItem(cacheItem.getLocale(), null, null, System.currentTimeMillis(), cacheItem.getMaxAgeMillis());
cacheService.addCacheOfComponent(cacheItemCopy);
}
}
return cacheItem;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2019 VMware, Inc.
* Copyright 2019-2020 VMware, Inc.
* SPDX-License-Identifier: EPL-2.0
*/
package com.vmware.vipclient.i18n.messages.service;
Expand All @@ -25,6 +25,8 @@
import org.junit.Before;
import org.junit.Test;
import static org.junit.Assert.*;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;

public class OfflineModeTest extends BaseTestClass {

Expand Down Expand Up @@ -174,9 +176,10 @@ public void testGetMsgsFailedUseDefault() {
// Returns the message in the default locale
assertEquals(FormatUtils.format(source, args), message);

// Cache for "es" locale is now pointing to the cache for the default locale
MessageCacheItem cacheItem = cs.getCacheOfComponent();
assertEquals(source, cacheItem.getCachedData().get(key));
// cacheItem for "es" locale has an empty data map. It's locale is the fallback locale.
MessageCacheItem cacheItem = cs.getCacheOfComponent();
assertEquals("en", cacheItem.getLocale());
assertTrue(cacheItem.getCachedData().isEmpty());

cfg.setOfflineResourcesBaseUrl(offlineResourcesBaseUrlOrig);
cfg.setMsgOriginsQueue(msgOriginsQueueOrig);
Expand Down Expand Up @@ -326,8 +329,9 @@ public void testGetMsgsBothOfflineAndOnlineFailed() {
CacheService csDefault = new CacheService(defaultLocaleDTO);
MessageCacheItem cacheItemDefaultLocale = csDefault.getCacheOfComponent();

// Cache of default locale and cache of Locale.ITALIAN refer to the same object
assertEquals(cacheItemDefaultLocale, cacheItem);
// cacheItem of Locale.ITALIAN's data map is empty. Its locale is the fallback locale
assertTrue(cacheItem.getCachedData().isEmpty());
assertEquals("en", cacheItem.getLocale());

cfg.setOfflineResourcesBaseUrl(offlineResourcesBaseUrlOrig);
cfg.setMsgOriginsQueue(msgOriginsQueueOrig);
Expand Down