Skip to content

Commit fd601b1

Browse files
Merge branch 'endgame-202305' into develop
2 parents f1c913c + 0234d54 commit fd601b1

13 files changed

Lines changed: 127 additions & 69 deletions

File tree

azure-spring-apps-maven-plugin/src/main/java/com/microsoft/azure/maven/springcloud/AbstractMojoBase.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,7 @@ public abstract class AbstractMojoBase extends AbstractAzureMojo {
8383
* <ul>
8484
* <li>cpu: Core numbers for deployment. </li>
8585
* <li>memoryInGB: Memory for deployment. </li>
86-
* <li>instanceCount: Instance count for deployment. </li>
86+
* <li>instanceCount: Max replicas num for apps of standard consumption plan or instance num for apps of other plans. </li>
8787
* <li>deploymentName: Name for deployment. </li>
8888
* <li>jvmOptions: JVM options for the deployed app. </li>
8989
* <li>runtimeVersion: The runtime version for Spring app, supported values are `Java 11`, `Java 17` and `Java 8`. </li>

azure-spring-apps-maven-plugin/src/main/java/com/microsoft/azure/maven/springcloud/ConfigMojo.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -269,7 +269,7 @@ private void confirmAndSave() throws IOException {
269269
} else {
270270
changesToConfirm.put("App name", this.appSettings.getAppName());
271271
changesToConfirm.put("Public access", this.appSettings.getIsPublic());
272-
changesToConfirm.put("Instance count", this.deploymentSettings.getInstanceCount());
272+
changesToConfirm.put("Instance count/max replicas", this.deploymentSettings.getInstanceCount());
273273
changesToConfirm.put("CPU count", this.deploymentSettings.getCpu());
274274
changesToConfirm.put("Memory size(GB)", this.deploymentSettings.getMemoryInGB());
275275
changesToConfirm.put("JVM options", this.deploymentSettings.getJvmOptions());

azure-spring-apps-maven-plugin/src/main/java/com/microsoft/azure/maven/springcloud/config/AppDeploymentMavenConfig.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,9 @@
1919
public class AppDeploymentMavenConfig {
2020
private Double cpu;
2121
private Double memoryInGB;
22+
/**
23+
* {@code max replicas} for apps of standard consumption plan or {@code instance num} for apps of other plans.
24+
*/
2225
private Integer instanceCount;
2326
private String deploymentName;
2427
private String jvmOptions;

azure-spring-apps-maven-plugin/src/main/resources/MessageTemplates.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ property: isPublic
6363
required: false
6464
---
6565
id: configure-instance-count
66-
promote: "Input instance count [***${schema.minimum}***-***${schema.maximum}***] (***${schema.default}***):"
66+
promote: "Input instance count (or max replicas for apps of standard consumption plan) [***${schema.minimum}***-***${schema.maximum}***] (***${schema.default}***):"
6767
resource: Deployment
6868
property: instanceCount
6969

azure-spring-apps-maven-plugin/src/main/resources/schema/Deployment.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@
3838
]
3939
},
4040
"instanceCount": {
41-
"description": "instance count",
41+
"description": "instance count/max replicas",
4242
"type": "integer",
4343
"default": 1,
4444
"minimum": 1,

azure-toolkit-libs/azure-toolkit-common-lib/src/main/java/com/microsoft/azure/toolkit/lib/common/model/AbstractAzResource.java

Lines changed: 20 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
package com.microsoft.azure.toolkit.lib.common.model;
77

88
import com.azure.core.exception.HttpResponseException;
9+
import com.azure.core.http.HttpResponse;
910
import com.azure.resourcemanager.resources.fluentcore.arm.ResourceId;
1011
import com.azure.resourcemanager.resources.fluentcore.arm.models.HasId;
1112
import com.azure.resourcemanager.resources.fluentcore.model.Refreshable;
@@ -230,10 +231,9 @@ protected final R loadRemote() {
230231
log.debug("[{}:{}]:loadRemote()", this.module.getName(), this.getName());
231232
try {
232233
return this.getModule().loadResourceFromAzure(this.getName(), this.getResourceGroupName());
233-
} catch (Exception e) {
234+
} catch (final Exception e) {
234235
log.debug("[{}:{}]:loadRemote()=EXCEPTION", this.module.getName(), this.getName(), e);
235-
final Throwable cause = e instanceof HttpResponseException ? e : ExceptionUtils.getRootCause(e);
236-
if (cause instanceof HttpResponseException && HttpStatus.SC_NOT_FOUND == ((HttpResponseException) cause).getResponse().getStatusCode()) {
236+
if (isNotFoundException(e)) {
237237
return null;
238238
}
239239
throw e;
@@ -247,10 +247,9 @@ protected final R loadRemote() {
247247
private R refreshRemote(@Nonnull R remote) {
248248
try {
249249
return this.refreshRemoteFromAzure(remote);
250-
} catch (Exception e) {
250+
} catch (final Exception e) {
251251
log.debug("[{}:{}]:refreshRemoteFromAzure()=EXCEPTION", this.module.getName(), this.getName(), e);
252-
final Throwable cause = e instanceof HttpResponseException ? e : ExceptionUtils.getRootCause(e);
253-
if (cause instanceof HttpResponseException && HttpStatus.SC_NOT_FOUND == ((HttpResponseException) cause).getResponse().getStatusCode()) {
252+
if (isNotFoundException(e)) {
254253
return null;
255254
}
256255
throw e;
@@ -297,9 +296,8 @@ private void deleteFromAzure() {
297296
log.debug("[{}:{}]:delete->module.deleteResourceFromAzure({})", this.module.getName(), this.getName(), this.getId());
298297
try {
299298
this.getModule().deleteResourceFromAzure(this.getId());
300-
} catch (Exception e) {
301-
final Throwable cause = e instanceof HttpResponseException ? e : ExceptionUtils.getRootCause(e);
302-
if (cause instanceof HttpResponseException && HttpStatus.SC_NOT_FOUND == ((HttpResponseException) cause).getResponse().getStatusCode()) {
299+
} catch (final Exception e) {
300+
if (isNotFoundException(e)) {
303301
log.debug("[{}]:delete()->deleteResourceFromAzure()=SC_NOT_FOUND", this.name, e);
304302
} else {
305303
this.getSubModules().stream().flatMap(m -> m.listCachedResources().stream()).forEach(r -> r.setStatus(Status.UNKNOWN));
@@ -365,9 +363,8 @@ protected void doModify(@Nonnull Runnable body, @Nullable String status) {
365363
final R refreshed = Optional.ofNullable(this.remoteRef.get()).map(this::refreshRemote).orElse(null);
366364
log.debug("[{}:{}]:doModify->setRemote({})", this.module.getName(), this.getName(), this.remoteRef.get());
367365
this.setRemote(refreshed);
368-
} catch (Throwable t) {
369-
final Throwable cause = t instanceof HttpResponseException ? t : ExceptionUtils.getRootCause(t);
370-
if (cause instanceof HttpResponseException && HttpStatus.SC_NOT_FOUND == ((HttpResponseException) cause).getResponse().getStatusCode()) {
366+
} catch (final Throwable t) {
367+
if (isNotFoundException(t)) {
371368
this.setRemote(null);
372369
} else {
373370
this.syncTimeRef.compareAndSet(0, System.currentTimeMillis());
@@ -382,6 +379,16 @@ protected void doModify(@Nonnull Runnable body, @Nullable String status) {
382379
}
383380
}
384381

382+
static boolean isNotFoundException(Throwable t) {
383+
final Throwable cause = t instanceof HttpResponseException ? t : ExceptionUtils.getRootCause(t);
384+
return Optional.ofNullable(cause).filter(c -> cause instanceof HttpResponseException)
385+
.map(c -> ((HttpResponseException) c))
386+
.map(HttpResponseException::getResponse)
387+
.map(HttpResponse::getStatusCode)
388+
.filter(c -> c == HttpStatus.SC_NOT_FOUND)
389+
.isPresent();
390+
}
391+
385392
@Nullable
386393
public R doModify(@Nonnull Callable<R> body, @Nullable String status) {
387394
if (!this.lock.tryLock()) {
@@ -396,7 +403,7 @@ public R doModify(@Nonnull Callable<R> body, @Nullable String status) {
396403
log.debug("[{}:{}]:doModify->setRemote({})", this.module.getName(), this.getName(), remote);
397404
this.setRemote(remote);
398405
return remote;
399-
} catch (Throwable t) {
406+
} catch (final Throwable t) {
400407
final Throwable cause = t instanceof HttpResponseException ? t : ExceptionUtils.getRootCause(t);
401408
if (cause instanceof HttpResponseException && HttpStatus.SC_NOT_FOUND == ((HttpResponseException) cause).getResponse().getStatusCode()) {
402409
this.setRemote(null);

azure-toolkit-libs/azure-toolkit-common-lib/src/main/java/com/microsoft/azure/toolkit/lib/common/model/AbstractAzResourceModule.java

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,6 @@
3838
import org.apache.commons.lang3.StringUtils;
3939
import org.apache.commons.lang3.exception.ExceptionUtils;
4040
import org.apache.commons.lang3.tuple.Pair;
41-
import org.apache.http.HttpStatus;
4241

4342
import javax.annotation.Nonnull;
4443
import javax.annotation.Nullable;
@@ -60,6 +59,7 @@
6059
import java.util.concurrent.locks.ReentrantLock;
6160
import java.util.stream.Collectors;
6261

62+
import static com.microsoft.azure.toolkit.lib.common.model.AbstractAzResource.isNotFoundException;
6363
import static com.microsoft.azure.toolkit.lib.common.model.AzResource.RESOURCE_GROUP_PLACEHOLDER;
6464

6565
@Slf4j
@@ -148,10 +148,9 @@ private void reloadResources() {
148148
.collect(Collectors.toMap(r -> this.newResource(r).getId().toLowerCase(), r -> r));
149149
log.debug("[{}]:reloadResources->setResources(xxx)", this.name);
150150
this.setResources(loadedResources);
151-
} catch (Exception e) {
151+
} catch (final Exception e) {
152152
log.debug("[{}]:reloadResources->setResources([])", this.name);
153-
final Throwable cause = e instanceof HttpResponseException ? e : ExceptionUtils.getRootCause(e);
154-
if (cause instanceof HttpResponseException && HttpStatus.SC_NOT_FOUND == ((HttpResponseException) cause).getResponse().getStatusCode()) {
153+
if (isNotFoundException(e)) {
155154
log.debug("[{}]:reloadResources->loadResourceFromAzure()=SC_NOT_FOUND", this.name, e);
156155
this.setResources(Collections.emptyMap());
157156
} else {
@@ -263,11 +262,11 @@ public T get(@Nonnull String name, @Nullable String rgName) {
263262
try {
264263
log.debug("[{}]:get({}, {})->loadResourceFromAzure()", this.name, name, resourceGroup);
265264
remote = loadResourceFromAzure(name, resourceGroup);
266-
} catch (Exception e) {
265+
} catch (final Exception e) {
267266
log.debug("[{}]:get({}, {})->loadResourceFromAzure()=EXCEPTION", this.name, name, resourceGroup, e);
268267
final Throwable cause = e instanceof HttpResponseException ? e : ExceptionUtils.getRootCause(e);
269268
if (cause instanceof HttpResponseException) {
270-
if (HttpStatus.SC_NOT_FOUND != ((HttpResponseException) cause).getResponse().getStatusCode()) {
269+
if (!isNotFoundException(e)) {
271270
log.debug("[{}]:get({}, {})->loadResourceFromAzure()=SC_NOT_FOUND", this.name, name, resourceGroup, e);
272271
throw e;
273272
}

azure-toolkit-libs/azure-toolkit-common-lib/src/main/java/com/microsoft/azure/toolkit/lib/common/utils/StreamingLogSupport.java

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,14 @@
66
package com.microsoft.azure.toolkit.lib.common.utils;
77

88
import com.microsoft.azure.toolkit.lib.common.exception.AzureToolkitRuntimeException;
9+
import com.microsoft.azure.toolkit.lib.common.messager.AzureMessager;
910
import org.apache.commons.lang3.NotImplementedException;
1011
import org.apache.http.client.utils.URIBuilder;
1112
import reactor.core.publisher.Flux;
1213

1314
import javax.annotation.Nonnull;
1415
import java.io.BufferedReader;
16+
import java.io.FileNotFoundException;
1517
import java.io.IOException;
1618
import java.io.InputStream;
1719
import java.io.InputStreamReader;
@@ -44,13 +46,15 @@ default Flux<String> streamingLogs(boolean follow, @Nonnull Map<String, String>
4446
return Flux.create((fluxSink) -> {
4547
try {
4648
final InputStream is = connection.getInputStream();
47-
BufferedReader rd = new BufferedReader(new InputStreamReader(is));
49+
final BufferedReader rd = new BufferedReader(new InputStreamReader(is));
4850
String line;
4951
while ((line = rd.readLine()) != null) {
5052
fluxSink.next(line);
5153
}
5254
rd.close();
53-
} catch (final Exception e) {
55+
} catch (final FileNotFoundException e) {
56+
AzureMessager.getMessager().error("app/instance may be deactivated, please refresh and try again later.");
57+
} catch (final IOException e) {
5458
throw new AzureToolkitRuntimeException(e);
5559
}
5660
});

azure-toolkit-libs/azure-toolkit-containerapps-lib/src/main/java/com/microsoft/azure/toolkit/lib/containerapps/containerapp/ReplicaContainer.java

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -7,13 +7,11 @@
77

88
package com.microsoft.azure.toolkit.lib.containerapps.containerapp;
99

10-
import com.azure.resourcemanager.appcontainers.ContainerAppsApiManager;
1110
import com.microsoft.azure.toolkit.lib.common.bundle.AzureString;
1211
import com.microsoft.azure.toolkit.lib.common.exception.AzureToolkitRuntimeException;
1312
import com.microsoft.azure.toolkit.lib.common.model.AbstractAzResource;
1413
import com.microsoft.azure.toolkit.lib.common.model.AbstractAzResourceModule;
1514
import com.microsoft.azure.toolkit.lib.common.utils.StreamingLogSupport;
16-
import com.microsoft.azure.toolkit.lib.containerapps.AzureContainerAppsServiceSubscription;
1715
import org.apache.commons.lang3.BooleanUtils;
1816
import org.jetbrains.annotations.NotNull;
1917

@@ -22,7 +20,6 @@
2220
import java.util.Collections;
2321
import java.util.List;
2422
import java.util.Objects;
25-
import java.util.Optional;
2623

2724
public class ReplicaContainer extends AbstractAzResource<ReplicaContainer, Replica, com.azure.resourcemanager.appcontainers.models.ReplicaContainer>
2825
implements StreamingLogSupport {
@@ -67,9 +64,6 @@ public String loadStatus(@NotNull com.azure.resourcemanager.appcontainers.models
6764

6865
@Override
6966
public String getLogStreamAuthorization() {
70-
final AzureContainerAppsServiceSubscription subs = this.getParent().getParent().getParent().getParent();
71-
final ContainerAppsApiManager manager = subs.getRemote();
72-
final String authToken = Optional.ofNullable(manager).map(m -> m.containerApps().getAuthToken(getResourceGroupName(), getName()).token()).orElse(null);
73-
return "Bearer " + authToken;
67+
return this.getParent().getParent().getParent().getLogStreamAuthorization();
7468
}
7569
}

azure-toolkit-libs/azure-toolkit-springcloud-lib/src/main/java/com/microsoft/azure/toolkit/lib/springcloud/SpringCloudAppDraft.java

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
import com.azure.resourcemanager.appplatform.models.Sku;
2020
import com.azure.resourcemanager.appplatform.models.SpringApp;
2121
import com.azure.resourcemanager.appplatform.models.SpringService;
22+
import com.azure.resourcemanager.appplatform.models.TemporaryDisk;
2223
import com.microsoft.azure.toolkit.lib.common.bundle.AzureString;
2324
import com.microsoft.azure.toolkit.lib.common.messager.AzureMessager;
2425
import com.microsoft.azure.toolkit.lib.common.messager.IAzureMessager;
@@ -51,6 +52,8 @@ public class SpringCloudAppDraft extends SpringCloudApp implements AzResource.Dr
5152
* @see <a href="https://azure.microsoft.com/en-us/pricing/details/spring-cloud/">Pricing - Azure Spring Apps</a>
5253
*/
5354
public static final int STANDARD_TIER_DEFAULT_DISK_SIZE = 50;
55+
public static final int DEFAULT_TEMP_DISK_SIZE = 5;
56+
public static final String DEFAULT_TEMP_DISK_MOUNT_PATH = "/tmp";
5457
@Getter
5558
@Nullable
5659
private final SpringCloudApp origin;
@@ -113,6 +116,7 @@ public SpringApp createResourceInAzure() {
113116
final boolean newPublicEndpointEnabled = this.isPublicEndpointEnabled();
114117
final Integer newDiskSize = this.isPersistentDiskEnabled() ? this.getParent().isStandardTier() ? STANDARD_TIER_DEFAULT_DISK_SIZE : BASIC_TIER_DEFAULT_DISK_SIZE : null;
115118
final PersistentDisk newDisk = this.isPersistentDiskEnabled() ? new PersistentDisk().withSizeInGB(newDiskSize).withMountPath(DEFAULT_DISK_MOUNT_PATH) : null;
119+
final TemporaryDisk tmpDisk = this.getParent().isEnterpriseTier() ? null : new TemporaryDisk().withSizeInGB(DEFAULT_TEMP_DISK_SIZE).withMountPath(DEFAULT_TEMP_DISK_MOUNT_PATH);
116120
// refer https://github.com/Azure/azure-sdk-for-java/blob/main/sdk/resourcemanager/azure-resourcemanager-samples/src/main/java/com/azure/
117121
// resourcemanager/appplatform/samples/ManageSpringCloud.java#L122-L129
118122
final Optional<SpringCloudDeploymentConfig> d = Optional.of(this.getConfig()).map(SpringCloudAppConfig::getDeployment);
@@ -121,6 +125,7 @@ public SpringApp createResourceInAzure() {
121125
final AppResourceInner appResource = new AppResourceInner()
122126
.withProperties(new AppResourceProperties()
123127
.withPersistentDisk(newDisk)
128+
.withTemporaryDisk(tmpDisk)
124129
.withPublicProperty(newPublicEndpointEnabled));
125130

126131
final DeploymentResourceProperties properties = new DeploymentResourceProperties()
@@ -221,7 +226,7 @@ public void setPersistentDiskEnabled(Boolean enabled) {
221226

222227
public boolean isPersistentDiskEnabled() {
223228
final Boolean enabled = Optional.ofNullable(config).map(Config::getPersistentDiskEnabled).orElseGet(super::isPersistentDiskEnabled);
224-
return enabled && !this.getParent().isEnterpriseTier();
229+
return enabled && !this.getParent().isEnterpriseTier() && !this.getParent().isConsumptionTier();
225230
}
226231

227232
public void setActiveDeploymentName(String name) {

0 commit comments

Comments
 (0)