package org.openstack.atlas.api.validation.validators;
import org.openstack.atlas.api.validation.Validator;
import org.openstack.atlas.api.validation.ValidatorBuilder;
import org.openstack.atlas.api.validation.results.ValidatorResult;
import org.openstack.atlas.api.validation.verifiers.*;
import org.openstack.atlas.docs.loadbalancers.api.v1.AlgorithmType;
import org.openstack.atlas.docs.loadbalancers.api.v1.LoadBalancer;
import org.openstack.atlas.docs.loadbalancers.api.v1.ProtocolPortBindings;
import org.openstack.atlas.service.domain.entities.LoadBalancerProtocol;
import static org.openstack.atlas.api.validation.ValidatorBuilder.build;
import static org.openstack.atlas.api.validation.context.HttpRequestType.POST;
import static org.openstack.atlas.api.validation.context.HttpRequestType.PUT;
public class LoadBalancerValidator implements ResourceValidator<LoadBalancer> {
private Validator<LoadBalancer> validator;
private final int MIN_PORT = 1;
private final int MAX_PORT = 65535;
final int MIN_TIMEOUT = 30;
private final int MAX_TIMEOUT = 120;
private final int LB_NAME_LENGTH = 128;
public LoadBalancerValidator() {
validator = build(new ValidatorBuilder<LoadBalancer>(LoadBalancer.class) {
{
// SHARED EXPECTATIONS
result(validationTarget().getProtocol()).if_().exist().then().must().adhereTo(new MustBeInArray(ProtocolPortBindings.getKeysAsArray())).withMessage("Load balancer protocol is invalid. Please specify a valid protocol.");
result(validationTarget().getAlgorithm()).if_().exist().then().must().adhereTo(new MustBeInArray(AlgorithmType.values())).withMessage("Load balancer algorithm is invalid. Please specify a valid algorithm.");
result(validationTarget().getSslTermination()).must().not().exist().withMessage("Please visit {account id}/loadbalancers/{load balancer id}/ssltermination to configure ssl termination.");
result(validationTarget().getPort()).if_().exist().then().must().adhereTo(new MustBeIntegerInRange(MIN_PORT, MAX_PORT)).withMessage("Load balancer port is invalid. Please specify a valid port.");
result(validationTarget().getTimeout()).if_().exist().then().must().adhereTo(new MustBeIntegerInRange(MIN_TIMEOUT, MAX_TIMEOUT)).withMessage("Load balancer timeout is invalid. Please specify a valid timeout value.");
result(validationTarget().getId()).must().not().exist().withMessage("Load balancer id field cannot be modified.");
result(validationTarget().getStatus()).must().not().exist().withMessage("Load balancer status field cannot be modified.");
result(validationTarget().getLoadBalancerUsage()).must().beEmptyOrNull().withMessage("Load balancer current usage field cannot be modified.");
result(validationTarget().getCluster()).must().not().exist().withMessage("Load balancer cluster field cannot be modified.");
result(validationTarget().getCreated()).must().not().exist().withMessage("Load balancer created field cannot be modified.");
result(validationTarget().getUpdated()).must().not().exist().withMessage("Load balancer updated field cannot be modified.");
result(validationTarget().getName()).if_().exist().then().must().adhereTo(new MustHaveLengthVerifier(LB_NAME_LENGTH)).withMessage("Load Balancer name must be less than or equal to " + LB_NAME_LENGTH);
result(validationTarget().isHalfClosed()).if_().exist().then().must().adhereTo(new MustBeBooleanVerifier()).withMessage("Must provide valid boolean value of either true or false. ");
result(validationTarget().isHttpsRedirect()).if_().exist().then().must().adhereTo(new MustBeBooleanVerifier()).withMessage("Must provide valid boolean value of either true or false. ");
// POST EXPECTATIONS
result(validationTarget().getName()).must().exist().forContext(POST).withMessage("Must provide a name for the load balancer.");
result(validationTarget().getName()).must().not().beEmptyOrNull().forContext(POST).withMessage("Load balancer name is invalid. Please specify a valid name");
result(validationTarget().getProtocol()).must().exist().forContext(POST).withMessage("Must provide a valid protocol for the load balancer.");
result(validationTarget().getVirtualIps()).must().exist().forContext(POST).withMessage("Must provide at least one virtual ip for the load balancer.");
result(validationTarget().getVirtualIps()).must().haveSizeOfAtLeast(1).forContext(POST).withMessage("Must have at least one virtual ip for the load balancer");
result(validationTarget().getVirtualIps()).if_().exist().then().must().adhereTo(new SharedOrNewVipVerifier()).forContext(POST).withMessage("Must specify either a shared or new virtual ip.");
result(validationTarget().getVirtualIps()).if_().exist().then().must().delegateTo(new VirtualIpValidator().getValidator(), POST).forContext(POST);
result(validationTarget().getConnectionLogging()).if_().exist().then().must().delegateTo(new ConnectionLoggingValidator().getValidator(), POST);
result(validationTarget().getContentCaching()).if_().exist().then().must().delegateTo(new ContentCachingValidator().getValidator(), POST);
// Need to determine how to get validation working for the collections.
result(validationTarget().getAccessList()).if_().exist().then().must().cannotExceedSize(100).withMessage("Must not provide more than one hundred access list items");
result(validationTarget().getAccessList()).if_().exist().then().must().delegateTo(new NetworkItemValidator().getValidator(), POST).forContext(POST);
result(validationTarget().getNodes()).must().adhereTo(new DuplicateNodeVerifier()).forContext(POST).withMessage("Duplicate nodes detected. Please ensure that the ip address and port are unique for each node.");
result(validationTarget().getNodes()).if_().exist().then().must().delegateTo(new NodeValidator().getValidator(), POST).forContext(POST);
result(validationTarget().getNodes()).if_().exist().then().must().cannotExceedSize(25).withMessage("Must not provide more than twenty five nodes per load balancer.");
result(validationTarget().getMetadata()).if_().exist().then().must().delegateTo(new MetaValidator().getValidator(), POST).forContext(POST);
result(validationTarget().getMetadata()).if_().exist().then().must().adhereTo(new DuplicateMetaVerifier()).forContext(POST).withMessage("Duplicate nodes detected. Please ensure that the ip address and port are unique for each node.");
result(validationTarget().getMetadata()).if_().exist().then().must().cannotExceedSize(25).withMessage("Must not provide more than twenty five metadata items per load balancer.");
result(validationTarget().getSessionPersistence()).if_().exist().then().must().delegateTo(new SessionPersistenceValidator().getValidator(), POST).forContext(POST);
result(validationTarget().getHealthMonitor()).if_().exist().then().must().delegateTo(new HealthMonitorValidator().getValidator(), POST).forContext(POST);
result(validationTarget().getConnectionThrottle()).if_().exist().then().must().delegateTo(new ConnectionThrottleValidator().getValidator(), POST).forContext(POST);
// PUT EXPECTATIONS
must().adhereTo(new Verifier<LoadBalancer>() {
@Override
public VerifierResult verify(LoadBalancer obj) {
return new VerifierResult(obj.getName() != null || obj.getAlgorithm() != null || obj.getPort() != null || obj.getProtocol() != null
|| obj.getConnectionLogging() != null || obj.getTimeout() != null || obj.isHalfClosed() != null || obj.isHttpsRedirect() != null);
}
}).forContext(PUT).withMessage("The load balancer must have at least one of the following to update: name, algorithm, protocol, port, timeout, halfClosed, or httpsRedirect.");
result(validationTarget().getNodes()).must().beEmptyOrNull().forContext(PUT).withMessage("Please visit {account id}/loadbalancers/{load balancer id}/nodes to configure nodes.");
result(validationTarget().getMetadata()).must().beEmptyOrNull().forContext(PUT).withMessage("Please visit {account id}/loadbalancers/{load balancer id}/metadata to configure metadata.");
result(validationTarget().getVirtualIps()).must().beEmptyOrNull().forContext(PUT).withMessage("Please visit {account id}/loadbalancers/{load balancer id}/virtualips/{virtual ip id} to configure a virtual ip.");
result(validationTarget().getSessionPersistence()).must().not().exist().forContext(PUT).withMessage("Please visit {account id}/loadbalancers/{load balancer id}/sessionpersistence to configure session persistence.");
result(validationTarget().getHealthMonitor()).must().not().exist().forContext(PUT).withMessage("Please visit {account id}/loadbalancers/{load balancer id}/healthmonitor to configure your health monitor.");
result(validationTarget().getConnectionThrottle()).must().not().exist().forContext(PUT).withMessage("Please visit {account id}/loadbalancers/{load balancer id}/throttles to configure connection throttling.");
result(validationTarget().getAccessList()).must().beEmptyOrNull().forContext(PUT).withMessage("Please visit {account id}/loadbalancers/{load balancer id}/accesslist to configure access lists.");
result(validationTarget().getConnectionLogging()).must().not().exist().forContext(PUT).withMessage("Please visit {account id}/loadbalancers/{load balancer id}/connecitonlogging to configure connection logging.");
result(validationTarget().getContentCaching()).must().not().exist().forContext(PUT).withMessage("Please visit {account id}/loadbalancers/{load balancer id}/contentcaching to configure content caching.");
}
});
}
@Override
public ValidatorResult validate(LoadBalancer lb, Object httpRequestType) {
ValidatorResult result = validator.validate(lb, httpRequestType);
return ValidatorUtilities.removeEmptyMessages(result);
}
@Override
public Validator<LoadBalancer> getValidator() {
return validator;
}
}