Skip to content

Commit a13c244

Browse files
mgmt, compute, improve instanceView (Azure#26694)
1 parent 8e26bd4 commit a13c244

11 files changed

+1464
-666
lines changed

sdk/resourcemanager/azure-resourcemanager-compute/CHANGELOG.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,11 @@
22

33
## 2.12.0-beta.1 (Unreleased)
44

5+
### Features Added
6+
7+
- Supported option of `filter` and `expand` for list instances of virtual machines by `VirtualMachineScaleSetVMs.list`.
8+
- Changed to include the instance view of the virtual machine, when getting the virtual machine by `VirtualMachineScaleSetVMs.getInstance`.
9+
510
### Other Changes
611

712
#### Dependency Updates
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
// Copyright (c) Microsoft Corporation. All rights reserved.
2+
// Licensed under the MIT License.
3+
4+
package com.azure.resourcemanager.compute.implementation;
5+
6+
import com.fasterxml.jackson.annotation.JsonProperty;
7+
import com.fasterxml.jackson.databind.ObjectMapper;
8+
import com.fasterxml.jackson.databind.introspect.Annotated;
9+
import com.fasterxml.jackson.databind.introspect.JacksonAnnotationIntrospector;
10+
11+
public final class SerializerUtils {
12+
13+
private static ObjectMapper objectMapper;
14+
15+
public static synchronized ObjectMapper getObjectMapper() {
16+
if (objectMapper == null) {
17+
objectMapper = new ObjectMapper();
18+
JacksonAnnotationIntrospector annotationIntrospector =
19+
new JacksonAnnotationIntrospector() {
20+
@Override
21+
public JsonProperty.Access findPropertyAccess(Annotated annotated) {
22+
JsonProperty.Access access = super.findPropertyAccess(annotated);
23+
if (access == JsonProperty.Access.WRITE_ONLY) {
24+
return JsonProperty.Access.AUTO;
25+
}
26+
return access;
27+
}
28+
};
29+
objectMapper.setAnnotationIntrospector(annotationIntrospector);
30+
}
31+
return objectMapper;
32+
}
33+
}

sdk/resourcemanager/azure-resourcemanager-compute/src/main/java/com/azure/resourcemanager/compute/implementation/VirtualMachineImpl.java

Lines changed: 1 addition & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -86,11 +86,7 @@
8686
import com.azure.resourcemanager.resources.fluentcore.utils.ResourceManagerUtils;
8787
import com.azure.resourcemanager.storage.models.StorageAccount;
8888
import com.azure.resourcemanager.storage.StorageManager;
89-
import com.fasterxml.jackson.annotation.JsonProperty;
9089
import com.fasterxml.jackson.core.JsonProcessingException;
91-
import com.fasterxml.jackson.databind.ObjectMapper;
92-
import com.fasterxml.jackson.databind.introspect.Annotated;
93-
import com.fasterxml.jackson.databind.introspect.JacksonAnnotationIntrospector;
9490
import reactor.core.Exceptions;
9591
import reactor.core.publisher.Flux;
9692
import reactor.core.publisher.Mono;
@@ -186,19 +182,6 @@ class VirtualMachineImpl
186182
private static final SerializerAdapter SERIALIZER_ADAPTER =
187183
SerializerFactory.createDefaultManagementSerializerAdapter();
188184

189-
private final ObjectMapper mapper;
190-
private static final JacksonAnnotationIntrospector ANNOTATION_INTROSPECTOR =
191-
new JacksonAnnotationIntrospector() {
192-
@Override
193-
public JsonProperty.Access findPropertyAccess(Annotated annotated) {
194-
JsonProperty.Access access = super.findPropertyAccess(annotated);
195-
if (access == JsonProperty.Access.WRITE_ONLY) {
196-
return JsonProperty.Access.AUTO;
197-
}
198-
return access;
199-
}
200-
};
201-
202185
VirtualMachineImpl(
203186
String name,
204187
VirtualMachineInner innerModel,
@@ -224,9 +207,6 @@ public JsonProperty.Access findPropertyAccess(Annotated annotated) {
224207
this.virtualMachineMsiHandler = new VirtualMachineMsiHandler(authorizationManager, this);
225208
this.newProximityPlacementGroupName = null;
226209
this.newProximityPlacementGroupType = null;
227-
228-
this.mapper = new ObjectMapper();
229-
this.mapper.setAnnotationIntrospector(ANNOTATION_INTROSPECTOR);
230210
}
231211

232212
// Verbs
@@ -419,7 +399,7 @@ public Mono<String> captureAsync(String containerName, String vhdPrefix, boolean
419399
.map(
420400
captureResultInner -> {
421401
try {
422-
return mapper.writeValueAsString(captureResultInner);
402+
return SerializerUtils.getObjectMapper().writeValueAsString(captureResultInner);
423403
} catch (JsonProcessingException ex) {
424404
throw logger.logExceptionAsError(Exceptions.propagate(ex));
425405
}

sdk/resourcemanager/azure-resourcemanager-compute/src/main/java/com/azure/resourcemanager/compute/implementation/VirtualMachineScaleSetVMImpl.java

Lines changed: 30 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
import com.azure.resourcemanager.compute.models.DiskCreateOptionTypes;
1616
import com.azure.resourcemanager.compute.models.DiskState;
1717
import com.azure.resourcemanager.compute.models.ImageReference;
18+
import com.azure.resourcemanager.compute.models.InstanceViewTypes;
1819
import com.azure.resourcemanager.compute.models.ManagedDiskParameters;
1920
import com.azure.resourcemanager.compute.models.NetworkInterfaceReference;
2021
import com.azure.resourcemanager.compute.models.OSProfile;
@@ -76,17 +77,7 @@ class VirtualMachineScaleSetVMImpl
7677
this.computeManager = computeManager;
7778
VirtualMachineScaleSetVMInstanceViewInner instanceViewInner = this.innerModel().instanceView();
7879
if (instanceViewInner != null) {
79-
this.virtualMachineInstanceView =
80-
new VirtualMachineInstanceViewImpl(
81-
new VirtualMachineInstanceViewInner()
82-
.withBootDiagnostics(instanceViewInner.bootDiagnostics())
83-
.withDisks(instanceViewInner.disks())
84-
.withExtensions(instanceViewInner.extensions())
85-
.withPlatformFaultDomain(instanceViewInner.platformFaultDomain())
86-
.withPlatformUpdateDomain(instanceViewInner.platformUpdateDomain())
87-
.withRdpThumbPrint(instanceViewInner.rdpThumbPrint())
88-
.withStatuses(instanceViewInner.statuses())
89-
.withVmAgent(instanceViewInner.vmAgent()));
80+
updateInstanceView(instanceViewInner);
9081
} else {
9182
this.virtualMachineInstanceView = null;
9283
}
@@ -407,6 +398,23 @@ public DiagnosticsProfile diagnosticsProfile() {
407398
return this.innerModel().diagnosticsProfile();
408399
}
409400

401+
private void updateInstanceView(VirtualMachineScaleSetVMInstanceViewInner instanceViewInner) {
402+
this.virtualMachineInstanceView =
403+
new VirtualMachineInstanceViewImpl(
404+
new VirtualMachineInstanceViewInner()
405+
.withBootDiagnostics(instanceViewInner.bootDiagnostics())
406+
.withDisks(instanceViewInner.disks())
407+
.withExtensions(instanceViewInner.extensions())
408+
.withPlatformFaultDomain(instanceViewInner.platformFaultDomain())
409+
.withPlatformUpdateDomain(instanceViewInner.platformUpdateDomain())
410+
.withRdpThumbPrint(instanceViewInner.rdpThumbPrint())
411+
.withStatuses(instanceViewInner.statuses())
412+
.withVmAgent(instanceViewInner.vmAgent())
413+
.withMaintenanceRedeployStatus(instanceViewInner.maintenanceRedeployStatus()));
414+
// hyperVGeneration is not in spec
415+
// vmHealth and assignedHost
416+
}
417+
410418
@Override
411419
public VirtualMachineInstanceView instanceView() {
412420
if (this.virtualMachineInstanceView == null) {
@@ -426,17 +434,7 @@ public Mono<VirtualMachineInstanceView> refreshInstanceViewAsync() {
426434
.getInstanceViewAsync(this.parent().resourceGroupName(), this.parent().name(), this.instanceId())
427435
.map(
428436
instanceViewInner -> {
429-
virtualMachineInstanceView =
430-
new VirtualMachineInstanceViewImpl(
431-
new VirtualMachineInstanceViewInner()
432-
.withBootDiagnostics(instanceViewInner.bootDiagnostics())
433-
.withDisks(instanceViewInner.disks())
434-
.withExtensions(instanceViewInner.extensions())
435-
.withPlatformFaultDomain(instanceViewInner.platformFaultDomain())
436-
.withPlatformUpdateDomain(instanceViewInner.platformUpdateDomain())
437-
.withRdpThumbPrint(instanceViewInner.rdpThumbPrint())
438-
.withStatuses(instanceViewInner.statuses())
439-
.withVmAgent(instanceViewInner.vmAgent()));
437+
updateInstanceView(instanceViewInner);
440438
return virtualMachineInstanceView;
441439
})
442440
.switchIfEmpty(Mono.defer(() -> Mono.empty()));
@@ -518,16 +516,20 @@ public VirtualMachineScaleSetVM refresh() {
518516

519517
@Override
520518
public Mono<VirtualMachineScaleSetVM> refreshAsync() {
521-
final VirtualMachineScaleSetVMImpl self = this;
522519
return this
523520
.client
524-
.getAsync(this.parent().resourceGroupName(), this.parent().name(), this.instanceId())
521+
.getAsync(this.parent().resourceGroupName(), this.parent().name(), this.instanceId(),
522+
InstanceViewTypes.INSTANCE_VIEW)
525523
.map(
526524
vmInner -> {
527-
self.setInner(vmInner);
528-
self.clearCachedRelatedResources();
529-
self.initializeDataDisks();
530-
return self;
525+
this.setInner(vmInner);
526+
this.clearCachedRelatedResources();
527+
if (vmInner.instanceView() != null) {
528+
// load instance view
529+
updateInstanceView(vmInner.instanceView());
530+
}
531+
this.initializeDataDisks();
532+
return this;
531533
});
532534
}
533535

sdk/resourcemanager/azure-resourcemanager-compute/src/main/java/com/azure/resourcemanager/compute/implementation/VirtualMachineScaleSetVMsImpl.java

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,9 @@
88
import com.azure.resourcemanager.compute.fluent.VirtualMachineScaleSetVMsClient;
99
import com.azure.resourcemanager.compute.fluent.VirtualMachineScaleSetsClient;
1010
import com.azure.resourcemanager.compute.fluent.models.VirtualMachineScaleSetVMInner;
11+
import com.azure.resourcemanager.compute.models.InstanceViewTypes;
1112
import com.azure.resourcemanager.compute.models.VirtualMachineScaleSetVM;
13+
import com.azure.resourcemanager.compute.models.VirtualMachineScaleSetVMExpandType;
1214
import com.azure.resourcemanager.compute.models.VirtualMachineScaleSetVMInstanceRequiredIDs;
1315
import com.azure.resourcemanager.compute.models.VirtualMachineScaleSetVMs;
1416
import com.azure.resourcemanager.resources.fluentcore.arm.collection.implementation.ReadableWrappersImpl;
@@ -45,7 +47,7 @@ protected VirtualMachineScaleSetVMImpl wrapModel(VirtualMachineScaleSetVMInner i
4547

4648
@Override
4749
public PagedIterable<VirtualMachineScaleSetVM> list() {
48-
return super.wrapList(this.client.list(this.scaleSet.resourceGroupName(), this.scaleSet.name()));
50+
return new PagedIterable<>(this.listAsync());
4951
}
5052

5153
public VirtualMachineScaleSetVMsClient inner() {
@@ -86,14 +88,15 @@ public void deleteInstances(Collection<String> instanceIds, boolean forceDeletio
8688

8789
@Override
8890
public VirtualMachineScaleSetVM getInstance(String instanceId) {
89-
return this.wrapModel(client.get(this.scaleSet.resourceGroupName(), this.scaleSet.name(), instanceId));
91+
return this.getInstanceAsync(instanceId).block();
9092
}
9193

9294
@Override
9395
public Mono<VirtualMachineScaleSetVM> getInstanceAsync(String instanceId) {
9496
return this
9597
.client
96-
.getAsync(this.scaleSet.resourceGroupName(), this.scaleSet.name(), instanceId)
98+
.getAsync(this.scaleSet.resourceGroupName(), this.scaleSet.name(), instanceId,
99+
InstanceViewTypes.INSTANCE_VIEW)
97100
.map(this::wrapModel);
98101
}
99102

@@ -132,4 +135,15 @@ public Mono<Void> simulateEvictionAsync(String instanceId) {
132135
public void simulateEviction(String instanceId) {
133136
this.simulateEvictionAsync(instanceId).block();
134137
}
138+
139+
@Override
140+
public PagedIterable<VirtualMachineScaleSetVM> list(String filter, VirtualMachineScaleSetVMExpandType expand) {
141+
return new PagedIterable<>(this.listAsync(filter, expand));
142+
}
143+
144+
@Override
145+
public PagedFlux<VirtualMachineScaleSetVM> listAsync(String filter, VirtualMachineScaleSetVMExpandType expand) {
146+
return super.wrapPageAsync(this.client.listAsync(this.scaleSet.resourceGroupName(), this.scaleSet.name(),
147+
filter, null, expand.toString()));
148+
}
135149
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
// Copyright (c) Microsoft Corporation. All rights reserved.
2+
// Licensed under the MIT License.
3+
4+
package com.azure.resourcemanager.compute.models;
5+
6+
import com.azure.core.util.ExpandableStringEnum;
7+
import com.fasterxml.jackson.annotation.JsonCreator;
8+
9+
import java.util.Collection;
10+
11+
/**
12+
* Expand type for virtual machine in virtual machine scale set.
13+
*/
14+
public class VirtualMachineScaleSetVMExpandType extends ExpandableStringEnum<VirtualMachineScaleSetVMExpandType> {
15+
16+
/** Static value 'instanceView' for VirtualMachineScaleSetVMExpandType. */
17+
public static final VirtualMachineScaleSetVMExpandType INSTANCE_VIEW = fromString("instanceView");
18+
19+
/**
20+
* Creates or finds a VirtualMachineScaleSetVMExpandType from its string representation.
21+
* @param name a name to look for
22+
* @return the corresponding VirtualMachineScaleSetVMExpandType
23+
*/
24+
@JsonCreator
25+
public static VirtualMachineScaleSetVMExpandType fromString(String name) {
26+
return fromString(name, VirtualMachineScaleSetVMExpandType.class);
27+
}
28+
29+
/**
30+
* @return known VirtualMachineScaleSetVMExpandType values
31+
*/
32+
public static Collection<VirtualMachineScaleSetVMExpandType> values() {
33+
return values(VirtualMachineScaleSetVMExpandType.class);
34+
}
35+
}

sdk/resourcemanager/azure-resourcemanager-compute/src/main/java/com/azure/resourcemanager/compute/models/VirtualMachineScaleSetVMs.java

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44
package com.azure.resourcemanager.compute.models;
55

66
import com.azure.core.annotation.Fluent;
7+
import com.azure.core.http.rest.PagedFlux;
8+
import com.azure.core.http.rest.PagedIterable;
79
import com.azure.resourcemanager.resources.fluentcore.collection.SupportsListing;
810
import java.util.Collection;
911
import reactor.core.publisher.Mono;
@@ -106,4 +108,24 @@ public interface VirtualMachineScaleSetVMs extends SupportsListing<VirtualMachin
106108
* @param instanceId The instance ID of the virtual machine.
107109
*/
108110
void simulateEviction(String instanceId);
111+
112+
/**
113+
* Lists all the resources of the specified type in the currently selected subscription.
114+
*
115+
* @param filter The filter to apply to the operation. Allowed values are 'startswith(instanceView/statuses/code,
116+
* 'PowerState') eq true', 'properties/latestModelApplied eq true', 'properties/latestModelApplied eq false'.
117+
* @param expand The expand expression to apply to the operation. Allowed values are 'instanceView'.
118+
* @return A {@link PagedIterable} of resources
119+
*/
120+
PagedIterable<VirtualMachineScaleSetVM> list(String filter, VirtualMachineScaleSetVMExpandType expand);
121+
122+
/**
123+
* Lists all the resources of the specified type in the currently selected subscription.
124+
*
125+
* @param filter The filter to apply to the operation. Allowed values are 'startswith(instanceView/statuses/code,
126+
* 'PowerState') eq true', 'properties/latestModelApplied eq true', 'properties/latestModelApplied eq false'.
127+
* @param expand The expand expression to apply to the operation. Allowed values are 'instanceView'.
128+
* @return A {@link PagedFlux} of resources
129+
*/
130+
PagedFlux<VirtualMachineScaleSetVM> listAsync(String filter, VirtualMachineScaleSetVMExpandType expand);
109131
}

sdk/resourcemanager/azure-resourcemanager-compute/src/test/java/com/azure/resourcemanager/compute/VirtualMachineScaleSetOperationsTests.java

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
import com.azure.resourcemanager.compute.models.VirtualMachineScaleSetPublicIpAddressConfiguration;
3131
import com.azure.resourcemanager.compute.models.VirtualMachineScaleSetSkuTypes;
3232
import com.azure.resourcemanager.compute.models.VirtualMachineScaleSetVM;
33+
import com.azure.resourcemanager.compute.models.VirtualMachineScaleSetVMExpandType;
3334
import com.azure.resourcemanager.compute.models.VirtualMachineScaleSetVMs;
3435
import com.azure.resourcemanager.keyvault.models.Secret;
3536
import com.azure.resourcemanager.keyvault.models.Vault;
@@ -61,6 +62,7 @@
6162
import java.nio.charset.StandardCharsets;
6263
import java.time.Duration;
6364
import java.util.ArrayList;
65+
import java.util.Arrays;
6466
import java.util.Collections;
6567
import java.util.List;
6668
import java.util.Map;
@@ -1224,6 +1226,57 @@ public void canCreateLowPriorityVMSSInstance() throws Exception {
12241226
Assertions.assertEquals(vmss.billingProfile().maxPrice(), (Double) 2000.0);
12251227
}
12261228

1229+
@Test
1230+
public void canListInstancesIncludingInstanceView() {
1231+
// however, it is hard to verify in automation that we do not send redundant REST call after received the instance view (i.e., no REST call to virtualMachines/{instanceId}/instanceView)
1232+
// currently this is verified manually
1233+
1234+
final String vmssName = generateRandomResourceName("vmss", 10);
1235+
1236+
Network network = this.networkManager
1237+
.networks()
1238+
.define("vmssvnet")
1239+
.withRegion(region)
1240+
.withNewResourceGroup(rgName)
1241+
.withAddressSpace("10.0.0.0/28")
1242+
.withSubnet("subnet1", "10.0.0.0/28")
1243+
.create();
1244+
1245+
this.computeManager
1246+
.virtualMachineScaleSets()
1247+
.define(vmssName)
1248+
.withRegion(region)
1249+
.withExistingResourceGroup(rgName)
1250+
.withSku(VirtualMachineScaleSetSkuTypes.STANDARD_A0)
1251+
.withExistingPrimaryNetworkSubnet(network, "subnet1")
1252+
.withoutPrimaryInternetFacingLoadBalancer()
1253+
.withoutPrimaryInternalLoadBalancer()
1254+
.withPopularLinuxImage(KnownLinuxVirtualMachineImage.UBUNTU_SERVER_18_04_LTS)
1255+
.withRootUsername("jvuser")
1256+
.withSsh(sshPublicKey())
1257+
.withUpgradeMode(UpgradeMode.MANUAL)
1258+
.withCapacity(3)
1259+
.create();
1260+
1261+
// list with VirtualMachineScaleSetVMExpandType.INSTANCE_VIEW
1262+
VirtualMachineScaleSet vmss = computeManager.virtualMachineScaleSets().getByResourceGroup(rgName, vmssName);
1263+
List<VirtualMachineScaleSetVM> vmInstances = vmss.virtualMachines().list(null, VirtualMachineScaleSetVMExpandType.INSTANCE_VIEW).stream().collect(Collectors.toList());
1264+
Assertions.assertEquals(3, vmInstances.size());
1265+
List<PowerState> powerStates = vmInstances.stream().map(VirtualMachineScaleSetVM::powerState).collect(Collectors.toList());
1266+
Assertions.assertEquals(Arrays.asList(PowerState.RUNNING, PowerState.RUNNING, PowerState.RUNNING), powerStates);
1267+
1268+
// update status of VM and check again
1269+
String firstInstanceId = vmInstances.get(0).instanceId();
1270+
computeManager.serviceClient().getVirtualMachineScaleSetVMs().deallocate(rgName, vmssName, firstInstanceId);
1271+
vmInstances.get(0).refresh();
1272+
powerStates = vmInstances.stream().map(VirtualMachineScaleSetVM::powerState).collect(Collectors.toList());
1273+
Assertions.assertEquals(Arrays.asList(PowerState.DEALLOCATED, PowerState.RUNNING, PowerState.RUNNING), powerStates);
1274+
1275+
// check single VM
1276+
VirtualMachineScaleSetVM vmInstance0 = vmss.virtualMachines().getInstance(firstInstanceId);
1277+
Assertions.assertEquals(PowerState.DEALLOCATED, vmInstance0.powerState());
1278+
}
1279+
12271280
@Test
12281281
public void canPerformSimulateEvictionOnSpotVMSSInstance() {
12291282
final String vmssName = generateRandomResourceName("vmss", 10);

0 commit comments

Comments
 (0)