PageRenderTime 51ms CodeModel.GetById 21ms RepoModel.GetById 0ms app.codeStats 0ms

/sdk/compute/mgmt/src/main/java/com/azure/management/compute/implementation/VirtualMachineScaleSetVMImpl.java

http://github.com/WindowsAzure/azure-sdk-for-java
Java | 727 lines | 630 code | 89 blank | 8 comment | 114 complexity | 9c310415fc7a6219c8fd24904354718e MD5 | raw file
Possible License(s): MIT
  1. // Copyright (c) Microsoft Corporation. All rights reserved.
  2. // Licensed under the MIT License.
  3. package com.azure.management.compute.implementation;
  4. import com.azure.core.http.rest.PagedFlux;
  5. import com.azure.core.http.rest.PagedIterable;
  6. import com.azure.core.util.logging.ClientLogger;
  7. import com.azure.management.compute.CachingTypes;
  8. import com.azure.management.compute.DataDisk;
  9. import com.azure.management.compute.DiagnosticsProfile;
  10. import com.azure.management.compute.Disk;
  11. import com.azure.management.compute.DiskCreateOptionTypes;
  12. import com.azure.management.compute.DiskState;
  13. import com.azure.management.compute.ImageReference;
  14. import com.azure.management.compute.ManagedDiskParameters;
  15. import com.azure.management.compute.NetworkInterfaceReference;
  16. import com.azure.management.compute.OSProfile;
  17. import com.azure.management.compute.OperatingSystemTypes;
  18. import com.azure.management.compute.PowerState;
  19. import com.azure.management.compute.Sku;
  20. import com.azure.management.compute.StorageAccountTypes;
  21. import com.azure.management.compute.StorageProfile;
  22. import com.azure.management.compute.VirtualMachineCustomImage;
  23. import com.azure.management.compute.VirtualMachineDataDisk;
  24. import com.azure.management.compute.VirtualMachineImage;
  25. import com.azure.management.compute.VirtualMachineInstanceView;
  26. import com.azure.management.compute.VirtualMachineScaleSet;
  27. import com.azure.management.compute.VirtualMachineScaleSetVM;
  28. import com.azure.management.compute.VirtualMachineScaleSetVMInstanceExtension;
  29. import com.azure.management.compute.VirtualMachineScaleSetVMNetworkProfileConfiguration;
  30. import com.azure.management.compute.VirtualMachineScaleSetVMProtectionPolicy;
  31. import com.azure.management.compute.VirtualMachineSizeTypes;
  32. import com.azure.management.compute.VirtualMachineUnmanagedDataDisk;
  33. import com.azure.management.compute.models.VirtualMachineExtensionInner;
  34. import com.azure.management.compute.models.VirtualMachineInstanceViewInner;
  35. import com.azure.management.compute.models.VirtualMachineScaleSetVMInner;
  36. import com.azure.management.compute.models.VirtualMachineScaleSetVMInstanceViewInner;
  37. import com.azure.management.compute.models.VirtualMachineScaleSetVMsInner;
  38. import com.azure.management.network.VirtualMachineScaleSetNetworkInterface;
  39. import com.azure.management.resources.fluentcore.arm.Region;
  40. import com.azure.management.resources.fluentcore.arm.models.implementation.ChildResourceImpl;
  41. import com.azure.management.resources.fluentcore.utils.Utils;
  42. import reactor.core.publisher.Mono;
  43. import java.util.ArrayList;
  44. import java.util.Collections;
  45. import java.util.HashMap;
  46. import java.util.Iterator;
  47. import java.util.LinkedHashMap;
  48. import java.util.List;
  49. import java.util.Map;
  50. /** Implementation of {@link VirtualMachineScaleSetVM}. */
  51. class VirtualMachineScaleSetVMImpl
  52. extends ChildResourceImpl<VirtualMachineScaleSetVMInner, VirtualMachineScaleSetImpl, VirtualMachineScaleSet>
  53. implements VirtualMachineScaleSetVM, VirtualMachineScaleSetVM.Update {
  54. private VirtualMachineInstanceView virtualMachineInstanceView;
  55. private final VirtualMachineScaleSetVMsInner client;
  56. private final ComputeManager computeManager;
  57. private final ClientLogger logger = new ClientLogger(VirtualMachineScaleSetVMImpl.class);
  58. // To track the managed data disks
  59. private final ManagedDataDiskCollection managedDataDisks = new ManagedDataDiskCollection();
  60. VirtualMachineScaleSetVMImpl(
  61. VirtualMachineScaleSetVMInner inner,
  62. final VirtualMachineScaleSetImpl parent,
  63. final VirtualMachineScaleSetVMsInner client,
  64. final ComputeManager computeManager) {
  65. super(inner, parent);
  66. this.client = client;
  67. this.computeManager = computeManager;
  68. VirtualMachineScaleSetVMInstanceViewInner instanceViewInner = this.inner().instanceView();
  69. if (instanceViewInner != null) {
  70. this.virtualMachineInstanceView =
  71. new VirtualMachineInstanceViewImpl(
  72. new VirtualMachineInstanceViewInner()
  73. .withBootDiagnostics(instanceViewInner.bootDiagnostics())
  74. .withDisks(instanceViewInner.disks())
  75. .withExtensions(instanceViewInner.extensions())
  76. .withPlatformFaultDomain(instanceViewInner.platformFaultDomain())
  77. .withPlatformUpdateDomain(instanceViewInner.platformUpdateDomain())
  78. .withRdpThumbPrint(instanceViewInner.rdpThumbPrint())
  79. .withStatuses(instanceViewInner.statuses())
  80. .withVmAgent(instanceViewInner.vmAgent()));
  81. } else {
  82. this.virtualMachineInstanceView = null;
  83. }
  84. }
  85. @Override
  86. public String id() {
  87. return this.inner().id();
  88. }
  89. @Override
  90. public String name() {
  91. return this.inner().name();
  92. }
  93. @Override
  94. public String regionName() {
  95. return this.inner().location();
  96. }
  97. @Override
  98. public Region region() {
  99. return Region.fromName(this.regionName());
  100. }
  101. @Override
  102. public String type() {
  103. return this.inner().type();
  104. }
  105. @Override
  106. public Map<String, String> tags() {
  107. if (this.inner().tags() == null) {
  108. return Collections.unmodifiableMap(new LinkedHashMap<>());
  109. }
  110. return Collections.unmodifiableMap(this.inner().tags());
  111. }
  112. @Override
  113. public String instanceId() {
  114. return this.inner().instanceId();
  115. }
  116. @Override
  117. public Sku sku() {
  118. return this.inner().sku();
  119. }
  120. @Override
  121. public VirtualMachineSizeTypes size() {
  122. if (this.inner().hardwareProfile() != null && this.inner().hardwareProfile().vmSize() != null) {
  123. return this.inner().hardwareProfile().vmSize();
  124. }
  125. if (this.sku() != null && this.sku().name() != null) {
  126. return VirtualMachineSizeTypes.fromString(this.sku().name());
  127. }
  128. return null;
  129. }
  130. @Override
  131. public boolean isLatestScaleSetUpdateApplied() {
  132. return this.inner().latestModelApplied();
  133. }
  134. @Override
  135. public boolean isOSBasedOnPlatformImage() {
  136. ImageReference imageReference = this.inner().storageProfile().imageReference();
  137. if (imageReference != null
  138. && imageReference.publisher() != null
  139. && imageReference.sku() != null
  140. && imageReference.offer() != null
  141. && imageReference.version() != null) {
  142. return true;
  143. }
  144. return false;
  145. }
  146. @Override
  147. public boolean isOSBasedOnCustomImage() {
  148. ImageReference imageReference = this.inner().storageProfile().imageReference();
  149. if (imageReference != null && imageReference.id() != null) {
  150. return true;
  151. }
  152. return false;
  153. }
  154. @Override
  155. public boolean isOSBasedOnStoredImage() {
  156. if (this.inner().storageProfile().osDisk() != null && this.inner().storageProfile().osDisk().image() != null) {
  157. return this.inner().storageProfile().osDisk().image().uri() != null;
  158. }
  159. return false;
  160. }
  161. @Override
  162. public ImageReference platformImageReference() {
  163. if (isOSBasedOnPlatformImage()) {
  164. return this.inner().storageProfile().imageReference();
  165. }
  166. return null;
  167. }
  168. @Override
  169. public VirtualMachineImage getOSPlatformImage() {
  170. if (this.isOSBasedOnPlatformImage()) {
  171. ImageReference imageReference = this.platformImageReference();
  172. return this
  173. .computeManager
  174. .virtualMachineImages()
  175. .getImage(
  176. this.region(),
  177. imageReference.publisher(),
  178. imageReference.offer(),
  179. imageReference.sku(),
  180. imageReference.version());
  181. }
  182. return null;
  183. }
  184. @Override
  185. public VirtualMachineCustomImage getOSCustomImage() {
  186. if (this.isOSBasedOnCustomImage()) {
  187. ImageReference imageReference = this.inner().storageProfile().imageReference();
  188. return this.computeManager.virtualMachineCustomImages().getById(imageReference.id());
  189. }
  190. return null;
  191. }
  192. @Override
  193. public String storedImageUnmanagedVhdUri() {
  194. if (this.inner().storageProfile().osDisk().image() != null) {
  195. return this.inner().storageProfile().osDisk().image().uri();
  196. }
  197. return null;
  198. }
  199. @Override
  200. public String osDiskName() {
  201. return this.inner().storageProfile().osDisk().name();
  202. }
  203. @Override
  204. public String osUnmanagedDiskVhdUri() {
  205. if (this.inner().storageProfile().osDisk().vhd() != null) {
  206. return this.inner().storageProfile().osDisk().vhd().uri();
  207. }
  208. return null;
  209. }
  210. @Override
  211. public String osDiskId() {
  212. if (this.storageProfile().osDisk().managedDisk() != null) {
  213. return this.storageProfile().osDisk().managedDisk().id();
  214. }
  215. return null;
  216. }
  217. @Override
  218. public Map<Integer, VirtualMachineUnmanagedDataDisk> unmanagedDataDisks() {
  219. Map<Integer, VirtualMachineUnmanagedDataDisk> dataDisks = new HashMap<>();
  220. if (!isManagedDiskEnabled()) {
  221. List<DataDisk> innerDataDisks = this.inner().storageProfile().dataDisks();
  222. if (innerDataDisks != null) {
  223. for (DataDisk innerDataDisk : innerDataDisks) {
  224. dataDisks.put(innerDataDisk.lun(), new UnmanagedDataDiskImpl(innerDataDisk, null));
  225. }
  226. }
  227. }
  228. return Collections.unmodifiableMap(dataDisks);
  229. }
  230. @Override
  231. public Map<Integer, VirtualMachineDataDisk> dataDisks() {
  232. Map<Integer, VirtualMachineDataDisk> dataDisks = new HashMap<>();
  233. if (isManagedDiskEnabled()) {
  234. List<DataDisk> innerDataDisks = this.inner().storageProfile().dataDisks();
  235. if (innerDataDisks != null) {
  236. for (DataDisk innerDataDisk : innerDataDisks) {
  237. dataDisks.put(innerDataDisk.lun(), new VirtualMachineDataDiskImpl(innerDataDisk));
  238. }
  239. }
  240. }
  241. return Collections.unmodifiableMap(dataDisks);
  242. }
  243. @Override
  244. public CachingTypes osDiskCachingType() {
  245. return this.inner().storageProfile().osDisk().caching();
  246. }
  247. @Override
  248. public int osDiskSizeInGB() {
  249. return Utils.toPrimitiveInt(this.inner().storageProfile().osDisk().diskSizeGB());
  250. }
  251. @Override
  252. public String computerName() {
  253. return this.inner().osProfile().computerName();
  254. }
  255. @Override
  256. public String administratorUserName() {
  257. return this.inner().osProfile().adminUsername();
  258. }
  259. @Override
  260. public OperatingSystemTypes osType() {
  261. return this.inner().storageProfile().osDisk().osType();
  262. }
  263. @Override
  264. public boolean isLinuxPasswordAuthenticationEnabled() {
  265. if (this.inner().osProfile().linuxConfiguration() != null) {
  266. return !Utils
  267. .toPrimitiveBoolean(this.inner().osProfile().linuxConfiguration().disablePasswordAuthentication());
  268. }
  269. return false;
  270. }
  271. @Override
  272. public boolean isWindowsVMAgentProvisioned() {
  273. if (this.inner().osProfile().windowsConfiguration() != null) {
  274. return Utils.toPrimitiveBoolean(this.inner().osProfile().windowsConfiguration().provisionVMAgent());
  275. }
  276. return false;
  277. }
  278. @Override
  279. public boolean isWindowsAutoUpdateEnabled() {
  280. if (this.inner().osProfile().windowsConfiguration() != null) {
  281. return Utils.toPrimitiveBoolean(this.inner().osProfile().windowsConfiguration().enableAutomaticUpdates());
  282. }
  283. return false;
  284. }
  285. @Override
  286. public String windowsTimeZone() {
  287. if (this.inner().osProfile().windowsConfiguration() != null) {
  288. return this.inner().osProfile().windowsConfiguration().timeZone();
  289. }
  290. return null;
  291. }
  292. @Override
  293. public boolean bootDiagnosticEnabled() {
  294. if (this.inner().diagnosticsProfile() != null && this.inner().diagnosticsProfile().bootDiagnostics() != null) {
  295. return Utils.toPrimitiveBoolean(this.inner().diagnosticsProfile().bootDiagnostics().enabled());
  296. }
  297. return false;
  298. }
  299. @Override
  300. public String bootDiagnosticStorageAccountUri() {
  301. if (this.inner().diagnosticsProfile() != null && this.inner().diagnosticsProfile().bootDiagnostics() != null) {
  302. return this.inner().diagnosticsProfile().bootDiagnostics().storageUri();
  303. }
  304. return null;
  305. }
  306. @Override
  307. public String availabilitySetId() {
  308. if (this.inner().availabilitySet() != null) {
  309. return this.inner().availabilitySet().id();
  310. }
  311. return null;
  312. }
  313. @Override
  314. public List<String> networkInterfaceIds() {
  315. List<String> resourceIds = new ArrayList<>();
  316. for (NetworkInterfaceReference reference : this.inner().networkProfile().networkInterfaces()) {
  317. resourceIds.add(reference.id());
  318. }
  319. return Collections.unmodifiableList(resourceIds);
  320. }
  321. @Override
  322. public String primaryNetworkInterfaceId() {
  323. for (NetworkInterfaceReference reference : this.inner().networkProfile().networkInterfaces()) {
  324. if (reference.primary() != null && reference.primary()) {
  325. return reference.id();
  326. }
  327. }
  328. return null;
  329. }
  330. @Override
  331. public Map<String, VirtualMachineScaleSetVMInstanceExtension> extensions() {
  332. Map<String, VirtualMachineScaleSetVMInstanceExtension> extensions = new LinkedHashMap<>();
  333. if (this.inner().resources() != null) {
  334. for (VirtualMachineExtensionInner extensionInner : this.inner().resources()) {
  335. extensions
  336. .put(
  337. extensionInner.name(),
  338. new VirtualMachineScaleSetVMInstanceExtensionImpl(extensionInner, this));
  339. }
  340. }
  341. return Collections.unmodifiableMap(extensions);
  342. }
  343. @Override
  344. public StorageProfile storageProfile() {
  345. return this.inner().storageProfile();
  346. }
  347. @Override
  348. public OSProfile osProfile() {
  349. return this.inner().osProfile();
  350. }
  351. @Override
  352. public DiagnosticsProfile diagnosticsProfile() {
  353. return this.inner().diagnosticsProfile();
  354. }
  355. @Override
  356. public VirtualMachineInstanceView instanceView() {
  357. if (this.virtualMachineInstanceView == null) {
  358. refreshInstanceView();
  359. }
  360. return this.virtualMachineInstanceView;
  361. }
  362. @Override
  363. public VirtualMachineInstanceView refreshInstanceView() {
  364. return refreshInstanceViewAsync().block();
  365. }
  366. public Mono<VirtualMachineInstanceView> refreshInstanceViewAsync() {
  367. return this
  368. .client
  369. .getInstanceViewAsync(this.parent().resourceGroupName(), this.parent().name(), this.instanceId())
  370. .map(
  371. instanceViewInner -> {
  372. virtualMachineInstanceView =
  373. new VirtualMachineInstanceViewImpl(
  374. new VirtualMachineInstanceViewInner()
  375. .withBootDiagnostics(instanceViewInner.bootDiagnostics())
  376. .withDisks(instanceViewInner.disks())
  377. .withExtensions(instanceViewInner.extensions())
  378. .withPlatformFaultDomain(instanceViewInner.platformFaultDomain())
  379. .withPlatformUpdateDomain(instanceViewInner.platformUpdateDomain())
  380. .withRdpThumbPrint(instanceViewInner.rdpThumbPrint())
  381. .withStatuses(instanceViewInner.statuses())
  382. .withVmAgent(instanceViewInner.vmAgent()));
  383. return virtualMachineInstanceView;
  384. })
  385. .switchIfEmpty(Mono.defer(() -> Mono.empty()));
  386. }
  387. @Override
  388. public PowerState powerState() {
  389. return PowerState.fromInstanceView(this.instanceView());
  390. }
  391. @Override
  392. public void reimage() {
  393. this.reimageAsync().block();
  394. }
  395. @Override
  396. public Mono<Void> reimageAsync() {
  397. return this
  398. .client
  399. .reimageAsync(this.parent().resourceGroupName(), this.parent().name(), this.instanceId(), null);
  400. }
  401. @Override
  402. public void deallocate() {
  403. this.deallocateAsync().block();
  404. }
  405. @Override
  406. public Mono<Void> deallocateAsync() {
  407. return this.client.deallocateAsync(this.parent().resourceGroupName(), this.parent().name(), this.instanceId());
  408. }
  409. @Override
  410. public void powerOff() {
  411. this.powerOffAsync().block();
  412. }
  413. @Override
  414. public Mono<Void> powerOffAsync() {
  415. return this
  416. .client
  417. .powerOffAsync(this.parent().resourceGroupName(), this.parent().name(), this.instanceId(), null);
  418. }
  419. @Override
  420. public void start() {
  421. this.startAsync().block();
  422. }
  423. @Override
  424. public Mono<Void> startAsync() {
  425. return this.client.startAsync(this.parent().resourceGroupName(), this.parent().name(), this.instanceId());
  426. }
  427. @Override
  428. public void restart() {
  429. this.restartAsync().block();
  430. }
  431. @Override
  432. public Mono<Void> restartAsync() {
  433. return this.client.restartAsync(this.parent().resourceGroupName(), this.parent().name(), this.instanceId());
  434. }
  435. @Override
  436. public void delete() {
  437. deleteAsync().block();
  438. }
  439. @Override
  440. public Mono<Void> deleteAsync() {
  441. return this.client.deleteAsync(this.parent().resourceGroupName(), this.parent().name(), this.instanceId());
  442. }
  443. @Override
  444. public VirtualMachineScaleSetVM refresh() {
  445. return this.refreshAsync().block();
  446. }
  447. @Override
  448. public Mono<VirtualMachineScaleSetVM> refreshAsync() {
  449. final VirtualMachineScaleSetVMImpl self = this;
  450. return this
  451. .client
  452. .getAsync(this.parent().resourceGroupName(), this.parent().name(), this.instanceId())
  453. .map(
  454. vmInner -> {
  455. self.setInner(vmInner);
  456. self.clearCachedRelatedResources();
  457. self.initializeDataDisks();
  458. return self;
  459. });
  460. }
  461. @Override
  462. public VirtualMachineScaleSetNetworkInterface getNetworkInterface(String name) {
  463. return this.parent().getNetworkInterfaceByInstanceId(this.instanceId(), name);
  464. }
  465. @Override
  466. public PagedIterable<VirtualMachineScaleSetNetworkInterface> listNetworkInterfaces() {
  467. return this.parent().listNetworkInterfacesByInstanceId(this.instanceId());
  468. }
  469. @Override
  470. public PagedFlux<VirtualMachineScaleSetNetworkInterface> listNetworkInterfacesAsync() {
  471. return this.parent().listNetworkInterfacesByInstanceIdAsync(this.instanceId());
  472. }
  473. @Override
  474. public String modelDefinitionApplied() {
  475. return this.inner().modelDefinitionApplied();
  476. }
  477. @Override
  478. public VirtualMachineScaleSetVMProtectionPolicy protectionPolicy() {
  479. return this.inner().protectionPolicy();
  480. }
  481. @Override
  482. public VirtualMachineScaleSetVMNetworkProfileConfiguration networkProfileConfiguration() {
  483. return this.inner().networkProfileConfiguration();
  484. }
  485. private void clearCachedRelatedResources() {
  486. this.virtualMachineInstanceView = null;
  487. }
  488. @Override
  489. public boolean isManagedDiskEnabled() {
  490. if (isOSBasedOnCustomImage()) {
  491. return true;
  492. }
  493. if (isOSBasedOnStoredImage()) {
  494. return false;
  495. }
  496. if (isOSBasedOnPlatformImage()) {
  497. if (this.inner().storageProfile().osDisk() != null
  498. && this.inner().storageProfile().osDisk().vhd() != null) {
  499. return false;
  500. }
  501. }
  502. return true;
  503. }
  504. @Override
  505. public Update withExistingDataDisk(Disk dataDisk, int lun, CachingTypes cachingTypes) {
  506. return this
  507. .withExistingDataDisk(
  508. dataDisk, lun, cachingTypes, StorageAccountTypes.fromString(dataDisk.sku().accountType().toString()));
  509. }
  510. @Override
  511. public Update withExistingDataDisk(
  512. Disk dataDisk, int lun, CachingTypes cachingTypes, StorageAccountTypes storageAccountTypes) {
  513. if (!this.isManagedDiskEnabled()) {
  514. throw logger.logExceptionAsError(new IllegalStateException(
  515. ManagedUnmanagedDiskErrors.VM_BOTH_UNMANAGED_AND_MANAGED_DISK_NOT_ALLOWED));
  516. }
  517. if (dataDisk.inner().diskState() != DiskState.UNATTACHED) {
  518. throw logger.logExceptionAsError(new IllegalStateException("Disk need to be in unattached state"));
  519. }
  520. ManagedDiskParameters managedDiskParameters =
  521. new ManagedDiskParameters().withStorageAccountType(storageAccountTypes);
  522. managedDiskParameters.withId(dataDisk.id());
  523. DataDisk attachDataDisk =
  524. new DataDisk()
  525. .withCreateOption(DiskCreateOptionTypes.ATTACH)
  526. .withLun(lun)
  527. .withCaching(cachingTypes)
  528. .withManagedDisk(managedDiskParameters);
  529. return this.withExistingDataDisk(attachDataDisk, lun);
  530. }
  531. private Update withExistingDataDisk(DataDisk dataDisk, int lun) {
  532. if (this.tryFindDataDisk(lun, this.inner().storageProfile().dataDisks()) != null) {
  533. throw logger.logExceptionAsError(new IllegalStateException(
  534. String.format("A data disk with lun '%d' already attached", lun)));
  535. } else if (this.tryFindDataDisk(lun, this.managedDataDisks.existingDisksToAttach) != null) {
  536. throw logger.logExceptionAsError(new IllegalStateException(
  537. String.format("A data disk with lun '%d' already scheduled to be attached", lun)));
  538. }
  539. this.managedDataDisks.existingDisksToAttach.add(dataDisk);
  540. return this;
  541. }
  542. @Override
  543. public Update withoutDataDisk(int lun) {
  544. DataDisk dataDisk = this.tryFindDataDisk(lun, this.inner().storageProfile().dataDisks());
  545. if (dataDisk == null) {
  546. throw logger.logExceptionAsError(new IllegalStateException(
  547. String.format("A data disk with lun '%d' not found", lun)));
  548. }
  549. if (dataDisk.createOption() != DiskCreateOptionTypes.ATTACH) {
  550. throw logger.logExceptionAsError(new IllegalStateException(
  551. String
  552. .format(
  553. "A data disk with lun '%d' cannot be detached, as it is part of Virtual Machine Scale Set"
  554. + " model",
  555. lun)));
  556. }
  557. this.managedDataDisks.diskLunsToRemove.add(lun);
  558. return this;
  559. }
  560. @Override
  561. public VirtualMachineScaleSetVM apply() {
  562. return this.applyAsync().block();
  563. }
  564. @Override
  565. public Mono<VirtualMachineScaleSetVM> applyAsync() {
  566. final VirtualMachineScaleSetVMImpl self = this;
  567. this.managedDataDisks.syncToVMDataDisks(this.inner().storageProfile());
  568. return this
  569. .parent()
  570. .virtualMachines()
  571. .inner()
  572. .updateAsync(this.parent().resourceGroupName(), this.parent().name(), this.instanceId(), this.inner())
  573. .map(
  574. vmInner -> {
  575. self.setInner(vmInner);
  576. self.clearCachedRelatedResources();
  577. self.initializeDataDisks();
  578. return self;
  579. });
  580. }
  581. @Override
  582. public VirtualMachineScaleSetVM.Update update() {
  583. initializeDataDisks();
  584. return this;
  585. }
  586. private void initializeDataDisks() {
  587. this.managedDataDisks.clear();
  588. }
  589. private DataDisk tryFindDataDisk(int lun, List<DataDisk> dataDisks) {
  590. DataDisk disk = null;
  591. if (dataDisks != null) {
  592. for (DataDisk dataDisk : dataDisks) {
  593. if (dataDisk.lun() == lun) {
  594. disk = dataDisk;
  595. break;
  596. }
  597. }
  598. }
  599. return disk;
  600. }
  601. /** Class to manage data disk collection. */
  602. private static class ManagedDataDiskCollection {
  603. private final List<DataDisk> existingDisksToAttach = new ArrayList<>();
  604. private final List<Integer> diskLunsToRemove = new ArrayList<>();
  605. void syncToVMDataDisks(StorageProfile storageProfile) {
  606. if (storageProfile != null && this.isPending()) {
  607. // remove disks from VM inner
  608. if (storageProfile.dataDisks() != null && !diskLunsToRemove.isEmpty()) {
  609. Iterator<DataDisk> iterator = storageProfile.dataDisks().iterator();
  610. while (iterator.hasNext()) {
  611. DataDisk dataDisk = iterator.next();
  612. if (diskLunsToRemove.contains(dataDisk.lun())) {
  613. iterator.remove();
  614. }
  615. }
  616. }
  617. // add disks to VM inner
  618. if (!existingDisksToAttach.isEmpty()) {
  619. for (DataDisk dataDisk : existingDisksToAttach) {
  620. if (storageProfile.dataDisks() == null) {
  621. storageProfile.withDataDisks(new ArrayList<DataDisk>());
  622. }
  623. storageProfile.dataDisks().add(dataDisk);
  624. }
  625. }
  626. // clear ManagedDataDiskCollection after it is synced into VM inner
  627. this.clear();
  628. }
  629. }
  630. private void clear() {
  631. existingDisksToAttach.clear();
  632. diskLunsToRemove.clear();
  633. }
  634. private boolean isPending() {
  635. return !(existingDisksToAttach.isEmpty() && diskLunsToRemove.isEmpty());
  636. }
  637. }
  638. }