Skip to content

Commit 3dabf51

Browse files
author
Fabrício Duarte
committed
Merge branch 'heuristics-to-avoid-template-redownload' into '4.20.0.0-scclouds'
Injeção de informações sobre o _download_ do _template_ nos seletores de _secondary storage_ Closes #2598 See merge request scclouds/scclouds!1177
2 parents 625ce1f + 9c7d07f commit 3dabf51

File tree

4 files changed

+109
-19
lines changed

4 files changed

+109
-19
lines changed

server/src/main/java/org/apache/cloudstack/storage/heuristics/HeuristicRuleHelper.java

Lines changed: 29 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -36,9 +36,12 @@
3636
import org.apache.cloudstack.secstorage.heuristics.HeuristicType;
3737
import org.apache.cloudstack.storage.datastore.db.ImageStoreDao;
3838
import org.apache.cloudstack.storage.datastore.db.ImageStoreVO;
39+
import org.apache.cloudstack.storage.datastore.db.TemplateDataStoreDao;
40+
import org.apache.cloudstack.storage.datastore.db.TemplateDataStoreVO;
3941
import org.apache.cloudstack.storage.heuristics.presetvariables.Account;
4042
import org.apache.cloudstack.storage.heuristics.presetvariables.Backup;
4143
import org.apache.cloudstack.storage.heuristics.presetvariables.Domain;
44+
import org.apache.cloudstack.storage.heuristics.presetvariables.DownloadDetails;
4245
import org.apache.cloudstack.storage.heuristics.presetvariables.PresetVariables;
4346
import org.apache.cloudstack.storage.heuristics.presetvariables.SecondaryStorage;
4447
import org.apache.cloudstack.storage.heuristics.presetvariables.Snapshot;
@@ -77,6 +80,9 @@ public class HeuristicRuleHelper {
7780
@Inject
7881
private AccountDao accountDao;
7982

83+
@Inject
84+
private TemplateDataStoreDao templateDataStoreDao;
85+
8086
@Inject
8187
private BackupOfferingDao backupOfferingDao;
8288

@@ -197,6 +203,22 @@ protected Template setTemplatePresetVariable(VMTemplateVO templateVO) {
197203
template.setName(templateVO.getName());
198204
template.setFormat(templateVO.getFormat());
199205
template.setHypervisorType(templateVO.getHypervisorType());
206+
template.setTemplateType(templateVO.getTemplateType());
207+
template.setPublic(templateVO.isPublicTemplate());
208+
209+
List<DownloadDetails> downloadDetails = new ArrayList<>();
210+
List<TemplateDataStoreVO> templateDataStoreVOs = templateDataStoreDao.listByTemplate(templateVO.getId());
211+
212+
for (TemplateDataStoreVO templateDataStoreVO : templateDataStoreVOs) {
213+
ImageStoreVO imageStore = imageStoreDao.findById(templateDataStoreVO.getDataStoreId());
214+
215+
DownloadDetails downloadDetail = new DownloadDetails();
216+
downloadDetail.setDataStoreId(imageStore.getUuid());
217+
downloadDetail.setDownloadState(templateDataStoreVO.getDownloadState());
218+
downloadDetails.add(downloadDetail);
219+
}
220+
221+
template.setDownloadDetails(downloadDetails);
200222

201223
return template;
202224
}
@@ -268,30 +290,30 @@ protected Domain setDomainPresetVariable(long domainId) {
268290
* in the code scope.
269291
* <br>
270292
* <br>
271-
* The JS script needs to return a valid UUID ({@link String}) of a secondary storage, otherwise a {@link CloudRuntimeException} is thrown.
293+
* The JS script needs to either return the valid UUID ({@link String}) of a secondary storage or nothing. If a valid UUID is returned,
294+
* this method returns the specific secondary storage; if nothing is returned, this method returns null in order to allow allocation in any
295+
* available secondary storage; otherwise a {@link CloudRuntimeException} is thrown.
272296
* @param rule the {@link String} representing the JS script.
273297
* @param heuristicType used for building the preset variables accordingly to the {@link HeuristicType} specified.
274298
* @param obj can be from the following classes: {@link VMTemplateVO}, {@link SnapshotInfo} and {@link VolumeVO}.
275299
* They are used to retrieve attributes for injecting in the JS rule.
276300
* @param zoneId used for injecting the {@link SecondaryStorage} preset variables.
277-
* @return the {@link DataStore} returned by the script.
301+
* @return the {@link DataStore} returned by the script, or null.
278302
*/
279303
public DataStore interpretHeuristicRule(String rule, HeuristicType heuristicType, Object obj, long zoneId) {
280304
try (JsInterpreter jsInterpreter = new JsInterpreter(HEURISTICS_SCRIPT_TIMEOUT, StorageManager.HEURISTICS_SCRIPT_TIMEOUT.key())) {
281305
buildPresetVariables(jsInterpreter, heuristicType, zoneId, obj);
282306
Object scriptReturn = jsInterpreter.executeScript(rule);
283307

284308
if (!(scriptReturn instanceof String)) {
285-
throw new CloudRuntimeException(String.format("Error while interpreting heuristic rule [%s], the rule did not return a String.", rule));
309+
logger.debug("Script did not return a string; allocating resource in any available secondary storage.");
310+
return null;
286311
}
287312

288313
DataStore dataStore = dataStoreManager.getImageStoreByUuid((String) scriptReturn);
289-
290314
if (dataStore == null) {
291-
throw new CloudRuntimeException(String.format("Unable to find a secondary storage with the UUID [%s] returned by the heuristic rule [%s]. Check if the rule is " +
292-
"returning a valid UUID.", scriptReturn, rule));
315+
logger.debug("Script did not return a valid secondary storage; allocating resource in any available secondary storage.");
293316
}
294-
295317
return dataStore;
296318
} catch (IOException ex) {
297319
String message = String.format("Error while executing script [%s].", rule);
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
// Licensed to the Apache Software Foundation (ASF) under one
2+
// or more contributor license agreements. See the NOTICE file
3+
// distributed with this work for additional information
4+
// regarding copyright ownership. The ASF licenses this file
5+
// to you under the Apache License, Version 2.0 (the
6+
// "License"); you may not use this file except in compliance
7+
// with the License. You may obtain a copy of the License at
8+
//
9+
// http://www.apache.org/licenses/LICENSE-2.0
10+
//
11+
// Unless required by applicable law or agreed to in writing,
12+
// software distributed under the License is distributed on an
13+
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14+
// KIND, either express or implied. See the License for the
15+
// specific language governing permissions and limitations
16+
// under the License.
17+
package org.apache.cloudstack.storage.heuristics.presetvariables;
18+
19+
import com.cloud.storage.VMTemplateStorageResourceAssoc;
20+
21+
public class DownloadDetails extends GenericHeuristicPresetVariable {
22+
23+
private String dataStoreId;
24+
25+
private VMTemplateStorageResourceAssoc.Status downloadState;
26+
27+
public String getDataStoreId() {
28+
return dataStoreId;
29+
}
30+
31+
public void setDataStoreId(String dataStoreId) {
32+
this.dataStoreId = dataStoreId;
33+
fieldNamesToIncludeInToString.add("dataStoreId");
34+
}
35+
36+
public VMTemplateStorageResourceAssoc.Status getDownloadState() {
37+
return downloadState;
38+
}
39+
40+
public void setDownloadState(VMTemplateStorageResourceAssoc.Status downloadState) {
41+
this.downloadState = downloadState;
42+
fieldNamesToIncludeInToString.add("downloadState");
43+
}
44+
}

server/src/main/java/org/apache/cloudstack/storage/heuristics/presetvariables/Template.java

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@
1919
import com.cloud.hypervisor.Hypervisor;
2020
import com.cloud.storage.Storage;
2121

22+
import java.util.List;
23+
2224
public class Template extends GenericHeuristicPresetVariable {
2325

2426
private Hypervisor.HypervisorType hypervisorType;
@@ -27,6 +29,10 @@ public class Template extends GenericHeuristicPresetVariable {
2729

2830
private Storage.TemplateType templateType;
2931

32+
private boolean isPublic;
33+
34+
private List<DownloadDetails> downloadDetails;
35+
3036
public Hypervisor.HypervisorType getHypervisorType() {
3137
return hypervisorType;
3238
}
@@ -53,4 +59,22 @@ public void setTemplateType(Storage.TemplateType templateType) {
5359
this.templateType = templateType;
5460
fieldNamesToIncludeInToString.add("templateType");
5561
}
62+
63+
public boolean isPublic() {
64+
return isPublic;
65+
}
66+
67+
public void setPublic(boolean isPublic) {
68+
this.isPublic = isPublic;
69+
fieldNamesToIncludeInToString.add("isPublic");
70+
}
71+
72+
public List<DownloadDetails> getDownloadDetails() {
73+
return downloadDetails;
74+
}
75+
76+
public void setDownloadDetails(List<DownloadDetails> downloadDetails) {
77+
this.downloadDetails = downloadDetails;
78+
fieldNamesToIncludeInToString.add("downloadDetails");
79+
}
5680
}

server/src/test/java/org/apache/cloudstack/storage/heuristics/HeuristicRuleHelperTest.java

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -18,14 +18,14 @@
1818

1919
import com.cloud.storage.VMTemplateVO;
2020
import com.cloud.storage.VolumeVO;
21-
import com.cloud.utils.exception.CloudRuntimeException;
2221
import org.apache.cloudstack.backup.BackupVO;
2322
import org.apache.cloudstack.engine.subsystem.api.storage.DataStore;
2423
import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreManager;
2524
import org.apache.cloudstack.engine.subsystem.api.storage.SnapshotInfo;
2625
import org.apache.cloudstack.secstorage.HeuristicVO;
2726
import org.apache.cloudstack.secstorage.dao.SecondaryStorageHeuristicDao;
2827
import org.apache.cloudstack.secstorage.heuristics.HeuristicType;
28+
import org.apache.cloudstack.storage.datastore.db.TemplateDataStoreDao;
2929
import org.apache.cloudstack.storage.heuristics.presetvariables.PresetVariables;
3030
import org.apache.cloudstack.utils.jsinterpreter.JsInterpreter;
3131
import org.apache.logging.log4j.Logger;
@@ -65,6 +65,9 @@ public class HeuristicRuleHelperTest {
6565
@Mock
6666
DataStore dataStoreMock;
6767

68+
@Mock
69+
TemplateDataStoreDao templateDataStoreDaoMock;
70+
6871
@Mock
6972
Logger loggerMock;
7073

@@ -172,31 +175,28 @@ public void buildPresetVariablesTestWithBackupHeuristicTypeShouldSetBackupAndSec
172175
}
173176

174177
@Test
175-
public void interpretHeuristicRuleTestHeuristicRuleDoesNotReturnAStringShouldThrowCloudRuntimeException() {
178+
public void interpretHeuristicRuleTestHeuristicRuleDoesNotReturnAStringShouldReturnNull() {
176179
String heuristicRule = "1";
177180

178181
Mockito.doNothing().when(heuristicRuleHelperSpy).buildPresetVariables(Mockito.any(JsInterpreter.class), Mockito.any(HeuristicType.class), Mockito.anyLong(),
179182
Mockito.any());
180183

181-
String expectedMessage = String.format("Error while interpreting heuristic rule [%s], the rule did not return a String.", heuristicRule);
182-
CloudRuntimeException assertThrows = Assert.assertThrows(CloudRuntimeException.class,
183-
() -> heuristicRuleHelperSpy.interpretHeuristicRule(heuristicRule, HeuristicType.TEMPLATE, volumeVOMock, 1L));
184-
Assert.assertEquals(expectedMessage, assertThrows.getMessage());
184+
DataStore result = heuristicRuleHelperSpy.interpretHeuristicRule(heuristicRule, HeuristicType.TEMPLATE, volumeVOMock, 1L);
185+
186+
Assert.assertNull(result);
185187
}
186188

187189
@Test
188-
public void interpretHeuristicRuleTestHeuristicRuleReturnAStringWithInvalidUuidShouldThrowCloudRuntimeException() {
190+
public void interpretHeuristicRuleTestHeuristicRuleReturnAStringWithInvalidUuidShouldReturnNull() {
189191
String heuristicRule = "'uuid'";
190192

191193
Mockito.doNothing().when(heuristicRuleHelperSpy).buildPresetVariables(Mockito.any(JsInterpreter.class), Mockito.any(HeuristicType.class), Mockito.anyLong(),
192194
Mockito.any());
193195
Mockito.doReturn(null).when(dataStoreManagerMock).getImageStoreByUuid(Mockito.anyString());
194196

195-
String expectedMessage = String.format("Unable to find a secondary storage with the UUID [%s] returned by the heuristic rule [%s]. Check if the rule is " +
196-
"returning a valid UUID.", "uuid", heuristicRule);
197-
CloudRuntimeException assertThrows = Assert.assertThrows(CloudRuntimeException.class,
198-
() -> heuristicRuleHelperSpy.interpretHeuristicRule(heuristicRule, HeuristicType.TEMPLATE, volumeVOMock, 1L));
199-
Assert.assertEquals(expectedMessage, assertThrows.getMessage());
197+
DataStore result = heuristicRuleHelperSpy.interpretHeuristicRule(heuristicRule, HeuristicType.TEMPLATE, volumeVOMock, 1L);
198+
199+
Assert.assertNull(result);
200200
}
201201

202202
@Test

0 commit comments

Comments
 (0)