Skip to content

Commit b343e84

Browse files
Merge pull request #5058 from microsoft/cache/appservice
apply new cache framework in webapp/functionapp listing
2 parents 9dc73d3 + 036e019 commit b343e84

File tree

11 files changed

+79
-145
lines changed

11 files changed

+79
-145
lines changed

PluginsAndFeatures/azure-toolkit-for-intellij/src/com/microsoft/azure/toolkit/intellij/common/AzureArtifactManager.java

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -47,11 +47,6 @@ public List<AzureArtifact> getSupportedAzureArtifactsForSpringCloud() {
4747
return prepareAzureArtifacts(packaging -> StringUtils.equals(packaging, MavenConstants.TYPE_JAR));
4848
}
4949

50-
@AzureOperation(
51-
name = "common|artifact.get_id",
52-
params = {"artifact.getName()"},
53-
type = AzureOperation.Type.TASK
54-
)
5550
public String getArtifactIdentifier(AzureArtifact artifact) {
5651
switch (artifact.getType()) {
5752
case Gradle:

PluginsAndFeatures/azure-toolkit-for-intellij/src/com/microsoft/azure/toolkit/intellij/common/operation/IntellijAzureOperationTitleProvider.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424

2525
import com.intellij.AbstractBundle;
2626
import com.microsoft.azure.toolkit.lib.common.operation.AzureOperationBundle;
27+
import org.jetbrains.annotations.NotNull;
2728

2829
public class IntellijAzureOperationTitleProvider extends AbstractBundle implements AzureOperationBundle.Provider {
2930

@@ -33,6 +34,11 @@ private IntellijAzureOperationTitleProvider() {
3334
super(AzureOperationBundle.TITLES);
3435
}
3536

37+
@Override
38+
public @NotNull String getMessage(@NotNull final String key, final Object @NotNull ... params) {
39+
return super.messageOrDefault(key, String.format("!%s!", key), params);
40+
}
41+
3642
public static void register() {
3743
AzureOperationBundle.register(INSTANCE);
3844
}

PluginsAndFeatures/azure-toolkit-for-intellij/src/com/microsoft/azure/toolkit/intellij/function/FunctionAppComboBox.java

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,12 @@
88
import com.intellij.openapi.project.Project;
99
import com.microsoft.azure.management.appservice.FunctionApp;
1010
import com.microsoft.azure.toolkit.intellij.appservice.AppServiceComboBox;
11+
import com.microsoft.azure.toolkit.intellij.webapp.WebAppComboBoxModel;
1112
import com.microsoft.azure.toolkit.lib.common.operation.AzureOperation;
1213
import com.microsoft.azuretools.azurecommons.helpers.NotNull;
1314
import com.microsoft.azuretools.core.mvp.model.ResourceEx;
1415
import com.microsoft.azuretools.core.mvp.model.function.AzureFunctionMvpModel;
16+
import com.microsoft.azuretools.core.mvp.model.webapp.AzureWebAppMvpModel;
1517
import com.microsoft.azuretools.utils.WebAppUtils;
1618
import com.microsoft.tooling.msservices.components.DefaultLoader;
1719
import org.apache.commons.lang3.StringUtils;
@@ -45,11 +47,9 @@ protected void createResource() {
4547
type = AzureOperation.Type.SERVICE
4648
)
4749
protected List<? extends FunctionAppComboBoxModel> loadItems() throws Exception {
48-
final List<ResourceEx<FunctionApp>> functions = AzureFunctionMvpModel.getInstance().listAllFunctions(false);
49-
return functions.stream()
50-
.filter(resource -> WebAppUtils.isJavaWebApp(resource.getResource()))
51-
.sorted((a, b) -> StringUtils.compareIgnoreCase(a.getResource().name(), b.getResource().name()))
50+
return AzureFunctionMvpModel.getInstance().listJavaFunctionApps(false).parallelStream()
5251
.map(FunctionAppComboBoxModel::new)
52+
.sorted((app1, app2) -> app1.getAppName().compareToIgnoreCase(app2.getAppName()))
5353
.collect(Collectors.toList());
5454
}
5555
}

PluginsAndFeatures/azure-toolkit-for-intellij/src/com/microsoft/azure/toolkit/intellij/springcloud/properties/SpringCloudAppPropertiesEditor.java

Lines changed: 11 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -5,36 +5,25 @@
55

66
package com.microsoft.azure.toolkit.intellij.springcloud.properties;
77

8-
import com.google.common.cache.CacheBuilder;
9-
import com.google.common.cache.CacheLoader;
10-
import com.google.common.cache.LoadingCache;
118
import com.google.common.collect.Maps;
12-
import com.intellij.openapi.fileEditor.FileEditor;
13-
import com.intellij.openapi.fileEditor.FileEditorPolicy;
14-
import com.intellij.openapi.fileEditor.FileEditorProvider;
15-
import com.intellij.openapi.project.DumbAware;
169
import com.intellij.openapi.project.Project;
1710
import com.intellij.openapi.ui.JBMenuItem;
1811
import com.intellij.openapi.ui.JBPopupMenu;
19-
import com.intellij.openapi.vfs.VirtualFile;
2012
import com.intellij.ui.DocumentAdapter;
2113
import com.intellij.ui.HideableDecorator;
2214
import com.intellij.ui.HyperlinkLabel;
2315
import com.intellij.ui.PopupMenuListenerAdapter;
2416
import com.intellij.ui.table.JBTable;
2517
import com.microsoft.azure.common.Utils;
2618
import com.microsoft.azure.common.exceptions.AzureExecutionException;
27-
import com.microsoft.azure.management.appplatform.v2020_07_01.AppResourceProperties;
28-
import com.microsoft.azure.management.appplatform.v2020_07_01.DeploymentResourceProperties;
29-
import com.microsoft.azure.management.appplatform.v2020_07_01.DeploymentResourceStatus;
30-
import com.microsoft.azure.management.appplatform.v2020_07_01.DeploymentSettings;
31-
import com.microsoft.azure.management.appplatform.v2020_07_01.PersistentDisk;
32-
import com.microsoft.azure.management.appplatform.v2020_07_01.RuntimeVersion;
19+
import com.microsoft.azure.management.appplatform.v2020_07_01.*;
3320
import com.microsoft.azure.management.appplatform.v2020_07_01.implementation.AppResourceInner;
3421
import com.microsoft.azure.management.appplatform.v2020_07_01.implementation.DeploymentResourceInner;
3522
import com.microsoft.azure.management.resources.Subscription;
23+
import com.microsoft.azure.toolkit.intellij.common.BaseEditor;
3624
import com.microsoft.azure.toolkit.intellij.common.EnvironmentVariablesTextFieldWithBrowseButton;
3725
import com.microsoft.azure.toolkit.intellij.springcloud.streaminglog.SpringCloudStreamingLogManager;
26+
import com.microsoft.azure.toolkit.lib.common.cache.Cacheable;
3827
import com.microsoft.azure.toolkit.lib.common.task.AzureTask;
3928
import com.microsoft.azure.toolkit.lib.common.task.AzureTaskManager;
4029
import com.microsoft.azuretools.core.mvp.model.AzureMvpModel;
@@ -43,8 +32,6 @@
4332
import com.microsoft.azuretools.telemetry.TelemetryConstants;
4433
import com.microsoft.azuretools.telemetrywrapper.EventUtil;
4534
import com.microsoft.intellij.helpers.ConsoleViewStatus;
46-
import com.microsoft.azure.toolkit.intellij.common.BaseEditor;
47-
import com.microsoft.intellij.helpers.UIHelperImpl;
4835
import com.microsoft.intellij.util.PluginUtil;
4936
import com.microsoft.tooling.msservices.components.DefaultLoader;
5037
import com.microsoft.tooling.msservices.serviceexplorer.azure.springcloud.SpringCloudMonitorUtil;
@@ -74,7 +61,6 @@
7461
import java.util.Map;
7562
import java.util.Objects;
7663
import java.util.concurrent.ExecutionException;
77-
import java.util.concurrent.TimeUnit;
7864
import java.util.function.Consumer;
7965
import java.util.stream.Collectors;
8066
import java.util.stream.IntStream;
@@ -148,13 +134,6 @@ public class SpringCloudAppPropertiesEditor extends BaseEditor {
148134
private DefaultTableModel instancesTableModel;
149135
private final Map<JComponent, Border> borderMap = new HashMap<>();
150136
private final Disposable rxSubscription;
151-
private static LoadingCache<String, String> testKeyCache = CacheBuilder.newBuilder()
152-
.expireAfterWrite(10, TimeUnit.MINUTES)
153-
.build(new CacheLoader<String, String>() {
154-
public String load(String key) throws IOException {
155-
return AzureSpringCloudMvpModel.getPrimaryTestEndpoint(key);
156-
}
157-
});
158137

159138
public SpringCloudAppPropertiesEditor(Project project, String clusterId, String appId) {
160139
this.project = project;
@@ -558,7 +537,7 @@ private void refreshData() {
558537
}
559538
DeploymentResourceInner deploy = StringUtils.isNotEmpty(app.properties().activeDeploymentName())
560539
? AzureSpringCloudMvpModel.getAppDeployment(appId, app.properties().activeDeploymentName()) : null;
561-
testKeyCache.refresh(clusterId);
540+
getTestKey(clusterId, true);
562541
return Pair.of(app, deploy);
563542
}).subscribeOn(Schedulers.io()).subscribe(pair -> AzureTaskManager.getInstance().runLater(
564543
() -> this.prepareViewModel(pair.getLeft(), pair.getRight())));
@@ -744,12 +723,8 @@ private void prepareViewModel(AppResourceInner app, DeploymentResourceInner depl
744723
this.appResourceInner = app;
745724
this.deploymentResourceInner = deploy;
746725
SpringCloudAppViewModel targetViewModel = new SpringCloudAppViewModel();
747-
try {
748-
String clusterKey = testKeyCache.get(clusterId);
749-
targetViewModel.setTestUrl(AzureSpringCloudMvpModel.getTestEndpointForApp(clusterKey, app.name()));
750-
} catch (ExecutionException e) {
751-
targetViewModel.setTestUrl(e.getMessage());
752-
}
726+
String clusterKey = getTestKey(clusterId);
727+
targetViewModel.setTestUrl(AzureSpringCloudMvpModel.getTestEndpointForApp(clusterKey, app.name()));
753728

754729
// persistent storage
755730
if (app.properties().persistentDisk() != null && app.properties().persistentDisk().sizeInGB().intValue() > 0) {
@@ -818,6 +793,11 @@ private void prepareViewModel(AppResourceInner app, DeploymentResourceInner depl
818793
}
819794
}
820795

796+
@Cacheable(value = "springcloud|cluster.testEndpoint", key = "$clusterId", condition = "!(force&&force[0])")
797+
private String getTestKey(String clusterId, boolean... force) {
798+
return AzureSpringCloudMvpModel.getPrimaryTestEndpoint(clusterId);
799+
}
800+
821801
private void updateModel(SpringCloudAppViewModel newModel) throws AzureExecutionException {
822802
try {
823803
this.viewModel = null;

PluginsAndFeatures/azure-toolkit-for-intellij/src/com/microsoft/azure/toolkit/intellij/webapp/WebAppComboBox.java

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -6,14 +6,11 @@
66
package com.microsoft.azure.toolkit.intellij.webapp;
77

88
import com.intellij.openapi.project.Project;
9-
import com.microsoft.azure.management.appservice.WebApp;
109
import com.microsoft.azure.toolkit.intellij.appservice.AppServiceComboBox;
1110
import com.microsoft.azure.toolkit.lib.common.operation.AzureOperation;
1211
import com.microsoft.azure.toolkit.lib.webapp.WebAppService;
1312
import com.microsoft.azuretools.azurecommons.helpers.NotNull;
14-
import com.microsoft.azuretools.core.mvp.model.ResourceEx;
1513
import com.microsoft.azuretools.core.mvp.model.webapp.AzureWebAppMvpModel;
16-
import com.microsoft.azuretools.utils.WebAppUtils;
1714
import com.microsoft.tooling.msservices.components.DefaultLoader;
1815

1916
import java.util.List;
@@ -48,11 +45,9 @@ protected void createResource() {
4845
type = AzureOperation.Type.SERVICE
4946
)
5047
protected List<WebAppComboBoxModel> loadItems() throws Exception {
51-
final List<ResourceEx<WebApp>> webApps = AzureWebAppMvpModel.getInstance().listAllWebApps(false);
52-
return webApps.stream()
53-
.filter(resource -> WebAppUtils.isJavaWebApp(resource.getResource()))
54-
.sorted((a, b) -> a.getResource().name().compareToIgnoreCase(b.getResource().name()))
48+
return AzureWebAppMvpModel.getInstance().listJavaWebApps(false).parallelStream()
5549
.map(WebAppComboBoxModel::new)
50+
.sorted((app1, app2) -> app1.getAppName().compareToIgnoreCase(app2.getAppName()))
5651
.collect(Collectors.toList());
5752
}
5853
}

PluginsAndFeatures/azure-toolkit-for-intellij/src/com/microsoft/azure/toolkit/intellij/webapp/runner/webappconfig/WebAppConfiguration.java

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,6 @@ public RunProfileState getState(@NotNull Executor executor, @NotNull ExecutionEn
7373

7474
@Override
7575
public void validate() throws ConfigurationException {
76-
checkAzurePreconditions();
7776
if (webAppSettingModel.isCreatingNew()) {
7877
if (Utils.isEmptyString(webAppSettingModel.getWebAppName())) {
7978
throw new ConfigurationException(message("webapp.deploy.validate.noWebAppName"));

PluginsAndFeatures/azure-toolkit-for-intellij/src/com/microsoft/intellij/AzureActionsListener.java

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,6 @@ public void appFrameCreated(@NotNull List<String> commandLineArgs) {
101101
toolbarGroup.addAll((DefaultActionGroup) am.getAction("AzureToolbarGroup"));
102102
DefaultActionGroup popupGroup = (DefaultActionGroup) am.getAction(IdeActions.GROUP_PROJECT_VIEW_POPUP);
103103
popupGroup.add(am.getAction("AzurePopupGroup"));
104-
loadWebApps();
105104
}
106105
try {
107106
PlatformDependent.isAndroid();
@@ -129,15 +128,6 @@ private void initAuthManage() {
129128
}
130129
}
131130

132-
private void loadWebApps() {
133-
System.out.println("AzurePlugin@loadWebApps");
134-
Runnable forceCleanWebAppsAction = () -> {
135-
AzureWebAppMvpModel.getInstance().clearWebAppsCache();
136-
};
137-
138-
AuthMethodManager.getInstance().addSignOutEventListener(forceCleanWebAppsAction);
139-
}
140-
141131
private void initLoggerFileHandler() {
142132
try {
143133
String loggerFilePath = Paths.get(CommonSettings.getSettingsBaseDir(), FILE_NAME_CORE_LIB_LOG).toString();

Utils/azuretools-core/src/com/microsoft/azuretools/authmanage/AuthMethodManager.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
import com.microsoft.azure.management.Azure;
1010
import com.microsoft.azure.management.appplatform.v2020_07_01.implementation.AppPlatformManager;
1111
import com.microsoft.azure.management.mysql.v2020_01_01.implementation.MySQLManager;
12+
import com.microsoft.azure.toolkit.lib.common.cache.CacheEvict;
1213
import com.microsoft.azure.toolkit.lib.common.exception.AzureToolkitRuntimeException;
1314
import com.microsoft.azure.toolkit.lib.common.operation.AzureOperation;
1415
import com.microsoft.azuretools.adauth.JsonHelper;
@@ -148,6 +149,7 @@ public AzureManager getAzureManager() {
148149
}
149150

150151
@AzureOperation(name = "account.sign_out", type = AzureOperation.Type.TASK)
152+
@CacheEvict(CacheEvict.ALL) // evict all caches on signing out
151153
public void signOut() {
152154
cleanAll();
153155
notifySignOutEventListener();

Utils/azuretools-core/src/com/microsoft/azuretools/core/mvp/model/function/AzureFunctionMvpModel.java

Lines changed: 26 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -8,30 +8,25 @@
88
import com.microsoft.azure.PagedList;
99
import com.microsoft.azure.management.Azure;
1010
import com.microsoft.azure.management.appservice.*;
11-
import com.microsoft.azure.management.resources.Subscription;
1211
import com.microsoft.azure.management.resources.fluentcore.arm.ResourceUtils;
12+
import com.microsoft.azure.toolkit.lib.common.cache.CacheEvict;
13+
import com.microsoft.azure.toolkit.lib.common.cache.Cacheable;
14+
import com.microsoft.azure.toolkit.lib.common.cache.Preload;
1315
import com.microsoft.azure.toolkit.lib.common.exception.AzureToolkitRuntimeException;
1416
import com.microsoft.azure.toolkit.lib.common.operation.AzureOperation;
1517
import com.microsoft.azuretools.authmanage.AuthMethodManager;
1618
import com.microsoft.azuretools.azurecommons.helpers.NotNull;
1719
import com.microsoft.azuretools.core.mvp.model.AzureMvpModel;
1820
import com.microsoft.azuretools.core.mvp.model.ResourceEx;
1921
import com.microsoft.azuretools.core.mvp.model.webapp.AppServiceUtils;
20-
import rx.Observable;
21-
import rx.schedulers.Schedulers;
22+
import com.microsoft.azuretools.utils.WebAppUtils;
2223

2324
import java.util.*;
24-
import java.util.concurrent.ConcurrentHashMap;
2525
import java.util.stream.Collectors;
2626

2727
public class AzureFunctionMvpModel {
2828
public static final PricingTier CONSUMPTION_PRICING_TIER = new PricingTier("Consumption", "");
29-
30-
private final Map<String, List<ResourceEx<FunctionApp>>> subscriptionIdToFunctionApps;
31-
32-
private AzureFunctionMvpModel() {
33-
subscriptionIdToFunctionApps = new ConcurrentHashMap<>();
34-
}
29+
public static final String SUBSCRIPTION_FUNCTIONS = "subscription-functions";
3530

3631
public static AzureFunctionMvpModel getInstance() {
3732
return SingletonHolder.INSTANCE;
@@ -67,9 +62,9 @@ public FunctionApp getFunctionByName(String sid, String resourceGroup, String na
6762
params = {"nameFromResourceId(appId)", "sid"},
6863
type = AzureOperation.Type.SERVICE
6964
)
65+
@CacheEvict(cacheName = SUBSCRIPTION_FUNCTIONS, key = "$sid")
7066
public void deleteFunction(String sid, String appId) {
7167
getFunctionAppsClient(sid).deleteById(appId);
72-
subscriptionIdToFunctionApps.remove(sid);
7368
}
7469

7570
@AzureOperation(
@@ -131,28 +126,29 @@ public List<AppServicePlan> listAppServicePlanBySubscriptionId(String sid) {
131126
/**
132127
* List all the Function Apps in selected subscriptions.
133128
*
134-
* @param forceReload flag indicating whether force to fetch latest data from server
129+
* @param force flag indicating whether force to fetch latest data from server
135130
* @return list of Function App
136131
*/
137132
@AzureOperation(
138133
name = "function.list.subscription|selected",
139134
type = AzureOperation.Type.SERVICE
140135
)
141-
public List<ResourceEx<FunctionApp>> listAllFunctions(final boolean forceReload) {
142-
final List<ResourceEx<FunctionApp>> functions = new ArrayList<>();
143-
List<Subscription> subs = AzureMvpModel.getInstance().getSelectedSubscriptions();
144-
if (subs.size() == 0) {
145-
return functions;
146-
}
147-
Observable.from(subs).flatMap((sd) ->
148-
Observable.create((subscriber) -> {
149-
List<ResourceEx<FunctionApp>> functionList = listFunctionsInSubscription(sd.subscriptionId(), forceReload);
150-
synchronized (functions) {
151-
functions.addAll(functionList);
152-
}
153-
subscriber.onCompleted();
154-
}).subscribeOn(Schedulers.io()), subs.size()).subscribeOn(Schedulers.io()).toBlocking().subscribe();
155-
return functions;
136+
public List<ResourceEx<FunctionApp>> listAllFunctions(final boolean... force) {
137+
return AzureMvpModel.getInstance().getSelectedSubscriptions().parallelStream()
138+
.flatMap((sd) -> listFunctionsInSubscription(sd.subscriptionId(), force).stream())
139+
.collect(Collectors.toList());
140+
}
141+
142+
@NotNull
143+
@AzureOperation(
144+
name = "function.list.java|subscription|selected",
145+
type = AzureOperation.Type.SERVICE
146+
)
147+
@Preload
148+
public List<ResourceEx<FunctionApp>> listJavaFunctionApps(final boolean... force) {
149+
return this.listAllFunctions(force).parallelStream()
150+
.filter(app -> WebAppUtils.isJavaWebApp(app.getResource()))
151+
.collect(Collectors.toList());
156152
}
157153

158154
@AzureOperation(
@@ -239,20 +235,14 @@ public static void enableApplicationLog(FunctionApp functionApp) {
239235
params = {"subscriptionId"},
240236
type = AzureOperation.Type.SERVICE
241237
)
242-
private List<ResourceEx<FunctionApp>> listFunctionsInSubscription(final String subscriptionId, final boolean forceReload) {
243-
if (!forceReload && subscriptionIdToFunctionApps.get(subscriptionId) != null) {
244-
return subscriptionIdToFunctionApps.get(subscriptionId);
245-
}
246-
238+
@Cacheable(cacheName = "subscription-functions", key = "$subscriptionId", condition = "!(force&&force[0])")
239+
private List<ResourceEx<FunctionApp>> listFunctionsInSubscription(final String subscriptionId, final boolean... force) {
247240
final Azure azure = AuthMethodManager.getInstance().getAzureClient(subscriptionId);
248-
List<ResourceEx<FunctionApp>> functions = azure.appServices().functionApps()
241+
return azure.appServices().functionApps()
249242
.inner().list().stream().filter(inner -> inner.kind() != null && Arrays.asList(inner.kind().split(",")).contains("functionapp"))
250243
.map(inner -> new FunctionAppWrapper(subscriptionId, inner))
251244
.map(app -> new ResourceEx<FunctionApp>(app, subscriptionId))
252245
.collect(Collectors.toList());
253-
subscriptionIdToFunctionApps.put(subscriptionId, functions);
254-
255-
return functions;
256246
}
257247

258248
private static FunctionApps getFunctionAppsClient(String sid) {

0 commit comments

Comments
 (0)