瀏覽代碼

move driver testing into CloudServiceDAO

tags/v0.1.6
Jonathan Cobb 4 年之前
父節點
當前提交
440a30ea37
共有 6 個檔案被更改,包括 90 行新增70 行删除
  1. +24
    -4
      bubble-server/src/main/java/bubble/dao/cloud/CloudServiceDAO.java
  2. +56
    -12
      bubble-server/src/main/java/bubble/model/cloud/CloudService.java
  3. +0
    -9
      bubble-server/src/main/java/bubble/resources/cloud/CloudServicesResource.java
  4. +9
    -44
      bubble-server/src/main/java/bubble/service/boot/ActivationService.java
  5. +0
    -1
      bubble-server/src/main/resources/message_templates/en_US/server/pre_auth/ResourceMessages.properties
  6. +1
    -0
      bubble-server/src/main/resources/models/defaults/cloudService_payment.json

+ 24
- 4
bubble-server/src/main/java/bubble/dao/cloud/CloudServiceDAO.java 查看文件

@@ -2,30 +2,50 @@ package bubble.dao.cloud;

import bubble.cloud.storage.local.LocalStorageDriver;
import bubble.dao.account.AccountOwnedTemplateDAO;
import bubble.model.cloud.BubbleNetwork;
import bubble.model.cloud.CloudService;
import bubble.cloud.CloudServiceType;
import bubble.server.BubbleConfiguration;
import org.cobbzilla.wizard.validation.ValidationResult;
import org.hibernate.criterion.Order;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;

import java.util.List;

import static bubble.ApiConstants.ROOT_NETWORK_UUID;
import static bubble.cloud.storage.local.LocalStorageDriver.LOCAL_STORAGE;
import static bubble.model.cloud.CloudService.testDriver;
import static org.cobbzilla.wizard.resources.ResourceUtil.invalidEx;

@Repository
public class CloudServiceDAO extends AccountOwnedTemplateDAO<CloudService> {

@Autowired private BubbleConfiguration configuration;

@Override public Order getDefaultSortOrder() { return Order.desc("priority"); }

@Override public Object preCreate(CloudService cloud) {
if (cloud.getType() == CloudServiceType.storage
&& cloud.getName().equals(LOCAL_STORAGE)
&& !cloud.getDriver().getClass().equals(LocalStorageDriver.class)) {
throw invalidEx("err.cloud.localStorageIsReservedName");
if (cloud.getType() == CloudServiceType.storage) {
if (cloud.getName().equals(LOCAL_STORAGE) && !cloud.getDriver().getClass().equals(LocalStorageDriver.class)) {
throw invalidEx("err.cloud.localStorageIsReservedName");
} else if (cloud.isNotLocalStorage()) {
final BubbleNetwork thisNetwork = configuration.getThisNetwork();
final String networkUuid = thisNetwork == null ? ROOT_NETWORK_UUID : thisNetwork.getUuid();
if (cloud.hasCredentials() && cloud.getCredentials().needsNewNetworkKey(networkUuid)) {
cloud.setCredentials(cloud.getCredentials().initNetworkKey(networkUuid));
}
}
}
return super.preCreate(cloud);
}

@Override public CloudService postCreate(CloudService cloud, Object context) {
final ValidationResult errors = testDriver(cloud, configuration);
if (errors.isInvalid()) throw invalidEx(errors);
return super.postCreate(cloud, context);
}

@Override public CloudService postUpdate(CloudService cloud, Object context) {
CloudService.clearDriverCache(cloud.getUuid());
return super.postUpdate(cloud, context);


+ 56
- 12
bubble-server/src/main/java/bubble/model/cloud/CloudService.java 查看文件

@@ -33,6 +33,7 @@ import org.cobbzilla.wizard.model.Identifiable;
import org.cobbzilla.wizard.model.entityconfig.IdentifiableBaseParentEntity;
import org.cobbzilla.wizard.model.entityconfig.annotations.*;
import org.cobbzilla.wizard.validation.HasValue;
import org.cobbzilla.wizard.validation.SimpleViolationException;
import org.cobbzilla.wizard.validation.ValidationResult;
import org.hibernate.annotations.Type;

@@ -68,6 +69,7 @@ public class CloudService extends IdentifiableBaseParentEntity implements Accoun
new ScrubbableField(CloudService.class, "credentials", CloudCredentials.class),
new ScrubbableField(CloudService.class, "credentialsJson", String.class)
};

@Override public ScrubbableField[] fieldsToScrub() { return SCRUB_FIELDS; }

public static final String[] UPDATE_FIELDS = {"description", "template", "enabled", "driverConfig", "priority"};
@@ -227,20 +229,26 @@ public class CloudService extends IdentifiableBaseParentEntity implements Accoun
public <T extends CloudServiceDriver> T wireAndSetup (BubbleConfiguration configuration) {
// note: CloudServiceDAO calls clearDriverCache when driver config is updated,
// then the updated class/config/credentials will be used.
return (T) driverCache.computeIfAbsent(getUuid(), k -> {
final T driver;
if (delegated()) {
if (type.hasDelegateDriverClass()) {
driver = (T) configuration.autowire(instantiate(type.getDelegateDriverClass(), this));
} else {
return die("wireAndSetup: cloud service type " + type + " does not support delegation: class not found: "+type.getDelegateDriverClassName());
}
if (!hasUuid()) {
// this is a test before creation, just try to wire it up, but do not cache the result
return _wireAndSetup(configuration);
}
return (T) driverCache.computeIfAbsent(getUuid(), k -> _wireAndSetup(configuration));
}

private <T extends CloudServiceDriver> T _wireAndSetup (BubbleConfiguration configuration) {
final T driver;
if (delegated()) {
if (type.hasDelegateDriverClass()) {
driver = (T) configuration.autowire(instantiate(type.getDelegateDriverClass(), this));
} else {
driver = (T) configuration.autowire(getDriver());
driver.postSetup();
return die("wireAndSetup: cloud service type " + type + " does not support delegation: class not found: "+type.getDelegateDriverClassName());
}
return driver;
});
} else {
driver = (T) configuration.autowire(getDriver());
driver.postSetup();
}
return driver;
}

public CloudService configure(CloudServiceConfig config, ValidationResult errors) {
@@ -290,4 +298,40 @@ public class CloudService extends IdentifiableBaseParentEntity implements Accoun
}
return config;
}

@Transient @JsonIgnore @Getter @Setter private Object testArg = null;

public static ValidationResult testDriver(CloudService cloud, BubbleConfiguration configuration) {
return testDriver(cloud, configuration, new ValidationResult());
}

public static ValidationResult testDriver(CloudService cloud, BubbleConfiguration configuration, ValidationResult errors) {
final String prefix = cloud.getName()+": ";
final Object arg = cloud.getTestArg();
final String argString = arg != null ? " with arg=" + arg : "";
final String invalidValue = arg == null ? null : arg.toString();
final String driverClass = cloud.getDriverClass();
final String errTestFailed = "err."+cloud.getType()+".testFailed";
final String errException = "err."+cloud.getType()+".unknownError";

final CloudServiceDriver driver;
try {
driver = cloud.getConfiguredDriver(configuration);
} catch (SimpleViolationException e) {
return errors.addViolation(e.getBean());

} catch (Exception e) {
return errors.addViolation(errTestFailed, prefix+"driver initialization failed: "+driverClass+": "+shortError(e));
}
try {
if (!driver.test(arg)) {
return errors.addViolation(errTestFailed, prefix+"test failed for driver: "+driverClass+argString, invalidValue);
}
} catch (SimpleViolationException e) {
return errors.addViolation(e.getBean());
} catch (Exception e) {
return errors.addViolation(errException, prefix+"test failed for driver: "+driverClass+argString+": "+shortError(e), invalidValue);
}
return errors;
}
}

+ 0
- 9
bubble-server/src/main/java/bubble/resources/cloud/CloudServicesResource.java 查看文件

@@ -26,15 +26,6 @@ public class CloudServicesResource extends AccountOwnedResource<CloudService, Cl

public CloudServicesResource(Account account) { super(account); }

@Override protected Object daoCreate(CloudService cloud) {
try {
cloud.wireAndSetup(configuration);
} catch (Exception e) {
throw invalidEx("err.driverConfig.initFailure");
}
return super.daoCreate(cloud);
}

@Override protected List<CloudService> list(Request req, ContainerRequest ctx) {
final Map<String, String> queryParams = queryParams(req.getQueryString());
final String type = queryParams.get("type");


+ 9
- 44
bubble-server/src/main/java/bubble/service/boot/ActivationService.java 查看文件

@@ -1,6 +1,5 @@
package bubble.service.boot;

import bubble.cloud.CloudServiceDriver;
import bubble.cloud.CloudServiceType;
import bubble.cloud.compute.ComputeNodeSizeType;
import bubble.cloud.compute.local.LocalComputeDriver;
@@ -21,7 +20,6 @@ import org.cobbzilla.wizard.api.CrudOperation;
import org.cobbzilla.wizard.client.ApiClientBase;
import org.cobbzilla.wizard.model.Identifiable;
import org.cobbzilla.wizard.model.ModelSetupService;
import org.cobbzilla.wizard.validation.SimpleViolationException;
import org.cobbzilla.wizard.validation.ValidationResult;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@@ -128,24 +126,19 @@ public class ActivationService {
.setTemplate(true));
}

// create all clouds
// create clouds, test cloud drivers
for (CloudService cloud : toCreate) {
cloudDAO.create(cloud
.setTemplate(true)
.setEnabled(true)
.setAccount(account.getUuid()));
final Object testArg;
if (cloud == publicDns) {
checkDriver(cloud, errors, request.getDomain().getName(), "err.dns.testFailed", "err.dns.unknownError");

} else if (cloud == networkStorage) {
if (networkStorage.getCredentials().needsNewNetworkKey(ROOT_NETWORK_UUID)) {
networkStorage.setCredentials(networkStorage.getCredentials().initNetworkKey(ROOT_NETWORK_UUID));
}
checkDriver(cloud, errors, null, "err.storage.testFailed", "err.storage.unknownError");

testArg = request.getDomain().getName();
} else {
checkDriver(cloud, errors, null, "err."+cloud.getType()+".testFailed", "err."+cloud.getType()+".unknownError");
testArg = null;
}
cloudDAO.create(cloud
.setTemplate(true)
.setEnabled(true)
.setAccount(account.getUuid())
.setTestArg(testArg));
}
if (errors.isInvalid()) throw invalidEx(errors);

@@ -235,34 +228,6 @@ public class ActivationService {
return node;
}

public ValidationResult checkDriver(CloudService cloud, ValidationResult errors, Object arg, String errTestFailed, String errException) {

final String prefix = cloud.getName()+": ";
final String argString = arg != null ? " with arg=" + arg : "";
final String invalidValue = arg == null ? null : arg.toString();
final String driverClass = cloud.getDriverClass();

final CloudServiceDriver driver;
try {
driver = cloud.getConfiguredDriver(configuration);
} catch (SimpleViolationException e) {
return errors.addViolation(e.getBean());

} catch (Exception e) {
return errors.addViolation(errTestFailed, prefix+"driver initialization failed: "+driverClass);
}
try {
if (!driver.test(arg)) {
return errors.addViolation(errTestFailed, prefix+"test failed for driver: "+driverClass+argString, invalidValue);
}
} catch (SimpleViolationException e) {
return errors.addViolation(e.getBean());
} catch (Exception e) {
return errors.addViolation(errException, prefix+"test failed for driver: "+driverClass+argString+": "+shortError(e), invalidValue);
}
return errors;
}

public String loadDefaultRoles() {
if (configuration.testMode()) {
final File roleFile = new File("target/classes/"+DEFAULT_ROLES);


+ 0
- 1
bubble-server/src/main/resources/message_templates/en_US/server/pre_auth/ResourceMessages.properties 查看文件

@@ -140,7 +140,6 @@ button_label_submit_verify_code=Verify
err.token.invalid=Code is incorrect

# Low-level errors and activation errors
err.driverConfig.initFailure=Cloud driver failed to initialize properlyu
err.cloud.noSuchField=A cloud driver config field name is invalid
err.cloud.invalidFieldType=Cloud driver config field type invalid
err.cloud.notFound=No cloud exists with this name


+ 1
- 0
bubble-server/src/main/resources/models/defaults/cloudService_payment.json 查看文件

@@ -26,6 +26,7 @@
{
"name": "FreePlay",
"type": "payment",
"priority": 300,
"driverClass": "bubble.cloud.payment.free.FreePaymentDriver",
"driverConfig": {},
"credentials": {},


Loading…
取消
儲存