All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.cloudfoundry.operations.applications.PushApplicationRequest Maven / Gradle / Ivy

There is a newer version: 5.12.2.RELEASE
Show newest version
package org.cloudfoundry.operations.applications;

import java.nio.file.Path;
import java.time.Duration;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import org.cloudfoundry.Nullable;
import org.immutables.value.Generated;

/**
 * The request options for the push application operation
 */
@Generated(from = "_PushApplicationRequest", generator = "Immutables")
@SuppressWarnings({"all", "deprecation"})
@javax.annotation.Generated("org.immutables.processor.ProxyProcessor")
public final class PushApplicationRequest
    extends org.cloudfoundry.operations.applications._PushApplicationRequest {
  private final @Nullable Path application;
  private final @Nullable String buildpack;
  private final @Nullable String command;
  private final @Nullable Integer diskQuota;
  private final @Nullable String dockerImage;
  private final @Nullable String dockerPassword;
  private final @Nullable String dockerUsername;
  private final @Nullable String domain;
  private final @Nullable ApplicationHealthCheck healthCheckType;
  private final @Nullable String host;
  private final @Nullable Integer instances;
  private final @Nullable Integer memory;
  private final String name;
  private final @Nullable Boolean noHostname;
  private final @Nullable Boolean noRoute;
  private final @Nullable Boolean noStart;
  private final @Nullable Path path;
  private final @Nullable Boolean randomRoute;
  private final @Nullable String routePath;
  private final @Nullable String stack;
  private final Duration stagingTimeout;
  private final Duration startupTimeout;
  private final @Nullable Integer timeout;

  private PushApplicationRequest(PushApplicationRequest.Builder builder) {
    this.application = builder.application;
    this.buildpack = builder.buildpack;
    this.command = builder.command;
    this.diskQuota = builder.diskQuota;
    this.dockerImage = builder.dockerImage;
    this.dockerPassword = builder.dockerPassword;
    this.dockerUsername = builder.dockerUsername;
    this.domain = builder.domain;
    this.healthCheckType = builder.healthCheckType;
    this.host = builder.host;
    this.instances = builder.instances;
    this.memory = builder.memory;
    this.name = builder.name;
    this.noHostname = builder.noHostname;
    this.noRoute = builder.noRoute;
    this.noStart = builder.noStart;
    this.path = builder.path;
    this.randomRoute = builder.randomRoute;
    this.routePath = builder.routePath;
    this.stack = builder.stack;
    this.timeout = builder.timeout;
    if (builder.stagingTimeout != null) {
      initShim.stagingTimeout(builder.stagingTimeout);
    }
    if (builder.startupTimeout != null) {
      initShim.startupTimeout(builder.startupTimeout);
    }
    this.stagingTimeout = initShim.getStagingTimeout();
    this.startupTimeout = initShim.getStartupTimeout();
    this.initShim = null;
  }

  private static final byte STAGE_INITIALIZING = -1;
  private static final byte STAGE_UNINITIALIZED = 0;
  private static final byte STAGE_INITIALIZED = 1;
  private transient volatile InitShim initShim = new InitShim();

  @Generated(from = "_PushApplicationRequest", generator = "Immutables")
  private final class InitShim {
    private byte stagingTimeoutBuildStage = STAGE_UNINITIALIZED;
    private Duration stagingTimeout;

    Duration getStagingTimeout() {
      if (stagingTimeoutBuildStage == STAGE_INITIALIZING) throw new IllegalStateException(formatInitCycleMessage());
      if (stagingTimeoutBuildStage == STAGE_UNINITIALIZED) {
        stagingTimeoutBuildStage = STAGE_INITIALIZING;
        this.stagingTimeout = Objects.requireNonNull(PushApplicationRequest.super.getStagingTimeout(), "stagingTimeout");
        stagingTimeoutBuildStage = STAGE_INITIALIZED;
      }
      return this.stagingTimeout;
    }

    void stagingTimeout(Duration stagingTimeout) {
      this.stagingTimeout = stagingTimeout;
      stagingTimeoutBuildStage = STAGE_INITIALIZED;
    }

    private byte startupTimeoutBuildStage = STAGE_UNINITIALIZED;
    private Duration startupTimeout;

    Duration getStartupTimeout() {
      if (startupTimeoutBuildStage == STAGE_INITIALIZING) throw new IllegalStateException(formatInitCycleMessage());
      if (startupTimeoutBuildStage == STAGE_UNINITIALIZED) {
        startupTimeoutBuildStage = STAGE_INITIALIZING;
        this.startupTimeout = Objects.requireNonNull(PushApplicationRequest.super.getStartupTimeout(), "startupTimeout");
        startupTimeoutBuildStage = STAGE_INITIALIZED;
      }
      return this.startupTimeout;
    }

    void startupTimeout(Duration startupTimeout) {
      this.startupTimeout = startupTimeout;
      startupTimeoutBuildStage = STAGE_INITIALIZED;
    }

    private String formatInitCycleMessage() {
      List attributes = new ArrayList<>();
      if (stagingTimeoutBuildStage == STAGE_INITIALIZING) attributes.add("stagingTimeout");
      if (startupTimeoutBuildStage == STAGE_INITIALIZING) attributes.add("startupTimeout");
      return "Cannot build PushApplicationRequest, attribute initializers form cycle " + attributes;
    }
  }

  /**
   * The path to the application
   * @see #getPath()
   * @see PushApplicationRequest.Builder#path(Path)
   * @deprecated in favor of variants of {@code path}
   */
  @Deprecated
  @Override
  public @Nullable Path getApplication() {
    return application;
  }

  /**
   * The buildpack for the application
   */
  @Override
  public @Nullable String getBuildpack() {
    return buildpack;
  }

  /**
   * The custom start command for the application
   */
  @Override
  public @Nullable String getCommand() {
    return command;
  }

  /**
   * The disk quota in megabytes for the application
   */
  @Override
  public @Nullable Integer getDiskQuota() {
    return diskQuota;
  }

  /**
   * The Docker image for the application
   */
  @Override
  public @Nullable String getDockerImage() {
    return dockerImage;
  }

  /**
   * The Docker repository password
   */
  @Override
  public @Nullable String getDockerPassword() {
    return dockerPassword;
  }

  /**
   * The Docker repository username
   */
  @Override
  public @Nullable String getDockerUsername() {
    return dockerUsername;
  }

  /**
   * The domain for the application
   */
  @Override
  public @Nullable String getDomain() {
    return domain;
  }

  /**
   * The health check type for the application
   */
  @Override
  public @Nullable ApplicationHealthCheck getHealthCheckType() {
    return healthCheckType;
  }

  /**
   * The host for the application
   */
  @Override
  public @Nullable String getHost() {
    return host;
  }

  /**
   * The number of instances for the application
   */
  @Override
  public @Nullable Integer getInstances() {
    return instances;
  }

  /**
   * The memory in megabytes for the application
   */
  @Override
  public @Nullable Integer getMemory() {
    return memory;
  }

  /**
   * The name for the application
   */
  @Override
  public String getName() {
    return name;
  }

  /**
   * Map the root domain to the application
   */
  @Override
  public @Nullable Boolean getNoHostname() {
    return noHostname;
  }

  /**
   * Do not create a route for the application
   */
  @Override
  public @Nullable Boolean getNoRoute() {
    return noRoute;
  }

  /**
   * Do not start the application after pushing
   */
  @Override
  public @Nullable Boolean getNoStart() {
    return noStart;
  }

  /**
   * The path for the application
   */
  @Override
  public @Nullable Path getPath() {
    return path;
  }

  /**
   * Use a random route for the application
   */
  @Override
  public @Nullable Boolean getRandomRoute() {
    return randomRoute;
  }

  /**
   * The route path for the application
   */
  @Override
  public @Nullable String getRoutePath() {
    return routePath;
  }

  /**
   * The stack for the application
   */
  @Override
  public @Nullable String getStack() {
    return stack;
  }

  /**
   * How long to wait for staging
   */
  @Override
  public Duration getStagingTimeout() {
    InitShim shim = this.initShim;
    return shim != null
        ? shim.getStagingTimeout()
        : this.stagingTimeout;
  }

  /**
   * How long to wait for startup
   */
  @Override
  public Duration getStartupTimeout() {
    InitShim shim = this.initShim;
    return shim != null
        ? shim.getStartupTimeout()
        : this.startupTimeout;
  }

  /**
   * The health check timeout
   */
  @Override
  public @Nullable Integer getTimeout() {
    return timeout;
  }

  /**
   * This instance is equal to all instances of {@code PushApplicationRequest} that have equal attribute values.
   * @return {@code true} if {@code this} is equal to {@code another} instance
   */
  @Override
  public boolean equals(Object another) {
    if (this == another) return true;
    return another instanceof PushApplicationRequest
        && equalTo((PushApplicationRequest) another);
  }

  private boolean equalTo(PushApplicationRequest another) {
    return Objects.equals(application, another.application)
        && Objects.equals(buildpack, another.buildpack)
        && Objects.equals(command, another.command)
        && Objects.equals(diskQuota, another.diskQuota)
        && Objects.equals(dockerImage, another.dockerImage)
        && Objects.equals(dockerPassword, another.dockerPassword)
        && Objects.equals(dockerUsername, another.dockerUsername)
        && Objects.equals(domain, another.domain)
        && Objects.equals(healthCheckType, another.healthCheckType)
        && Objects.equals(host, another.host)
        && Objects.equals(instances, another.instances)
        && Objects.equals(memory, another.memory)
        && name.equals(another.name)
        && Objects.equals(noHostname, another.noHostname)
        && Objects.equals(noRoute, another.noRoute)
        && Objects.equals(noStart, another.noStart)
        && Objects.equals(path, another.path)
        && Objects.equals(randomRoute, another.randomRoute)
        && Objects.equals(routePath, another.routePath)
        && Objects.equals(stack, another.stack)
        && stagingTimeout.equals(another.stagingTimeout)
        && startupTimeout.equals(another.startupTimeout)
        && Objects.equals(timeout, another.timeout);
  }

  /**
   * Computes a hash code from attributes: {@code application}, {@code buildpack}, {@code command}, {@code diskQuota}, {@code dockerImage}, {@code dockerPassword}, {@code dockerUsername}, {@code domain}, {@code healthCheckType}, {@code host}, {@code instances}, {@code memory}, {@code name}, {@code noHostname}, {@code noRoute}, {@code noStart}, {@code path}, {@code randomRoute}, {@code routePath}, {@code stack}, {@code stagingTimeout}, {@code startupTimeout}, {@code timeout}.
   * @return hashCode value
   */
  @Override
  public int hashCode() {
    int h = 5381;
    h += (h << 5) + Objects.hashCode(application);
    h += (h << 5) + Objects.hashCode(buildpack);
    h += (h << 5) + Objects.hashCode(command);
    h += (h << 5) + Objects.hashCode(diskQuota);
    h += (h << 5) + Objects.hashCode(dockerImage);
    h += (h << 5) + Objects.hashCode(dockerPassword);
    h += (h << 5) + Objects.hashCode(dockerUsername);
    h += (h << 5) + Objects.hashCode(domain);
    h += (h << 5) + Objects.hashCode(healthCheckType);
    h += (h << 5) + Objects.hashCode(host);
    h += (h << 5) + Objects.hashCode(instances);
    h += (h << 5) + Objects.hashCode(memory);
    h += (h << 5) + name.hashCode();
    h += (h << 5) + Objects.hashCode(noHostname);
    h += (h << 5) + Objects.hashCode(noRoute);
    h += (h << 5) + Objects.hashCode(noStart);
    h += (h << 5) + Objects.hashCode(path);
    h += (h << 5) + Objects.hashCode(randomRoute);
    h += (h << 5) + Objects.hashCode(routePath);
    h += (h << 5) + Objects.hashCode(stack);
    h += (h << 5) + stagingTimeout.hashCode();
    h += (h << 5) + startupTimeout.hashCode();
    h += (h << 5) + Objects.hashCode(timeout);
    return h;
  }

  /**
   * Prints the immutable value {@code PushApplicationRequest} with attribute values.
   * @return A string representation of the value
   */
  @Override
  public String toString() {
    return "PushApplicationRequest{"
        + "application=" + application
        + ", buildpack=" + buildpack
        + ", command=" + command
        + ", diskQuota=" + diskQuota
        + ", dockerImage=" + dockerImage
        + ", dockerPassword=" + dockerPassword
        + ", dockerUsername=" + dockerUsername
        + ", domain=" + domain
        + ", healthCheckType=" + healthCheckType
        + ", host=" + host
        + ", instances=" + instances
        + ", memory=" + memory
        + ", name=" + name
        + ", noHostname=" + noHostname
        + ", noRoute=" + noRoute
        + ", noStart=" + noStart
        + ", path=" + path
        + ", randomRoute=" + randomRoute
        + ", routePath=" + routePath
        + ", stack=" + stack
        + ", stagingTimeout=" + stagingTimeout
        + ", startupTimeout=" + startupTimeout
        + ", timeout=" + timeout
        + "}";
  }


  private static PushApplicationRequest validate(PushApplicationRequest instance) {
    instance.check();
    return instance;
  }

  /**
   * Creates a builder for {@link PushApplicationRequest PushApplicationRequest}.
   * @return A new PushApplicationRequest builder
   */
  public static PushApplicationRequest.Builder builder() {
    return new PushApplicationRequest.Builder();
  }

  /**
   * Builds instances of type {@link PushApplicationRequest PushApplicationRequest}.
   * Initialize attributes and then invoke the {@link #build()} method to create an
   * immutable instance.
   * 

{@code Builder} is not thread-safe and generally should not be stored in a field or collection, * but instead used immediately to create instances. */ @Generated(from = "_PushApplicationRequest", generator = "Immutables") public static final class Builder { private static final long INIT_BIT_NAME = 0x1L; private long initBits = 0x1L; private Path application; private String buildpack; private String command; private Integer diskQuota; private String dockerImage; private String dockerPassword; private String dockerUsername; private String domain; private ApplicationHealthCheck healthCheckType; private String host; private Integer instances; private Integer memory; private String name; private Boolean noHostname; private Boolean noRoute; private Boolean noStart; private Path path; private Boolean randomRoute; private String routePath; private String stack; private Duration stagingTimeout; private Duration startupTimeout; private Integer timeout; private Builder() { } /** * Fill a builder with attribute values from the provided {@code PushApplicationRequest} instance. * Regular attribute values will be replaced with those from the given instance. * Absent optional values will not replace present values. * @param instance The instance from which to copy values * @return {@code this} builder for use in a chained invocation */ public final Builder from(PushApplicationRequest instance) { return from((_PushApplicationRequest) instance); } /** * Copy abstract value type {@code _PushApplicationRequest} instance into builder. * @param instance The instance from which to copy values * @return {@code this} builder for use in a chained invocation */ final Builder from(_PushApplicationRequest instance) { Objects.requireNonNull(instance, "instance"); Path applicationValue = instance.getApplication(); if (applicationValue != null) { application(applicationValue); } String buildpackValue = instance.getBuildpack(); if (buildpackValue != null) { buildpack(buildpackValue); } String commandValue = instance.getCommand(); if (commandValue != null) { command(commandValue); } Integer diskQuotaValue = instance.getDiskQuota(); if (diskQuotaValue != null) { diskQuota(diskQuotaValue); } String dockerImageValue = instance.getDockerImage(); if (dockerImageValue != null) { dockerImage(dockerImageValue); } String dockerPasswordValue = instance.getDockerPassword(); if (dockerPasswordValue != null) { dockerPassword(dockerPasswordValue); } String dockerUsernameValue = instance.getDockerUsername(); if (dockerUsernameValue != null) { dockerUsername(dockerUsernameValue); } String domainValue = instance.getDomain(); if (domainValue != null) { domain(domainValue); } ApplicationHealthCheck healthCheckTypeValue = instance.getHealthCheckType(); if (healthCheckTypeValue != null) { healthCheckType(healthCheckTypeValue); } String hostValue = instance.getHost(); if (hostValue != null) { host(hostValue); } Integer instancesValue = instance.getInstances(); if (instancesValue != null) { instances(instancesValue); } Integer memoryValue = instance.getMemory(); if (memoryValue != null) { memory(memoryValue); } name(instance.getName()); Boolean noHostnameValue = instance.getNoHostname(); if (noHostnameValue != null) { noHostname(noHostnameValue); } Boolean noRouteValue = instance.getNoRoute(); if (noRouteValue != null) { noRoute(noRouteValue); } Boolean noStartValue = instance.getNoStart(); if (noStartValue != null) { noStart(noStartValue); } Path pathValue = instance.getPath(); if (pathValue != null) { path(pathValue); } Boolean randomRouteValue = instance.getRandomRoute(); if (randomRouteValue != null) { randomRoute(randomRouteValue); } String routePathValue = instance.getRoutePath(); if (routePathValue != null) { routePath(routePathValue); } String stackValue = instance.getStack(); if (stackValue != null) { stack(stackValue); } stagingTimeout(instance.getStagingTimeout()); startupTimeout(instance.getStartupTimeout()); Integer timeoutValue = instance.getTimeout(); if (timeoutValue != null) { timeout(timeoutValue); } return this; } /** * Initializes the value for the {@link PushApplicationRequest#getApplication() application} attribute. * @param application The value for application (can be {@code null}) * @return {@code this} builder for use in a chained invocation */ @Deprecated public final Builder application(@Nullable Path application) { this.application = application; return this; } /** * Initializes the value for the {@link PushApplicationRequest#getBuildpack() buildpack} attribute. * @param buildpack The value for buildpack (can be {@code null}) * @return {@code this} builder for use in a chained invocation */ public final Builder buildpack(@Nullable String buildpack) { this.buildpack = buildpack; return this; } /** * Initializes the value for the {@link PushApplicationRequest#getCommand() command} attribute. * @param command The value for command (can be {@code null}) * @return {@code this} builder for use in a chained invocation */ public final Builder command(@Nullable String command) { this.command = command; return this; } /** * Initializes the value for the {@link PushApplicationRequest#getDiskQuota() diskQuota} attribute. * @param diskQuota The value for diskQuota (can be {@code null}) * @return {@code this} builder for use in a chained invocation */ public final Builder diskQuota(@Nullable Integer diskQuota) { this.diskQuota = diskQuota; return this; } /** * Initializes the value for the {@link PushApplicationRequest#getDockerImage() dockerImage} attribute. * @param dockerImage The value for dockerImage (can be {@code null}) * @return {@code this} builder for use in a chained invocation */ public final Builder dockerImage(@Nullable String dockerImage) { this.dockerImage = dockerImage; return this; } /** * Initializes the value for the {@link PushApplicationRequest#getDockerPassword() dockerPassword} attribute. * @param dockerPassword The value for dockerPassword (can be {@code null}) * @return {@code this} builder for use in a chained invocation */ public final Builder dockerPassword(@Nullable String dockerPassword) { this.dockerPassword = dockerPassword; return this; } /** * Initializes the value for the {@link PushApplicationRequest#getDockerUsername() dockerUsername} attribute. * @param dockerUsername The value for dockerUsername (can be {@code null}) * @return {@code this} builder for use in a chained invocation */ public final Builder dockerUsername(@Nullable String dockerUsername) { this.dockerUsername = dockerUsername; return this; } /** * Initializes the value for the {@link PushApplicationRequest#getDomain() domain} attribute. * @param domain The value for domain (can be {@code null}) * @return {@code this} builder for use in a chained invocation */ public final Builder domain(@Nullable String domain) { this.domain = domain; return this; } /** * Initializes the value for the {@link PushApplicationRequest#getHealthCheckType() healthCheckType} attribute. * @param healthCheckType The value for healthCheckType (can be {@code null}) * @return {@code this} builder for use in a chained invocation */ public final Builder healthCheckType(@Nullable ApplicationHealthCheck healthCheckType) { this.healthCheckType = healthCheckType; return this; } /** * Initializes the value for the {@link PushApplicationRequest#getHost() host} attribute. * @param host The value for host (can be {@code null}) * @return {@code this} builder for use in a chained invocation */ public final Builder host(@Nullable String host) { this.host = host; return this; } /** * Initializes the value for the {@link PushApplicationRequest#getInstances() instances} attribute. * @param instances The value for instances (can be {@code null}) * @return {@code this} builder for use in a chained invocation */ public final Builder instances(@Nullable Integer instances) { this.instances = instances; return this; } /** * Initializes the value for the {@link PushApplicationRequest#getMemory() memory} attribute. * @param memory The value for memory (can be {@code null}) * @return {@code this} builder for use in a chained invocation */ public final Builder memory(@Nullable Integer memory) { this.memory = memory; return this; } /** * Initializes the value for the {@link PushApplicationRequest#getName() name} attribute. * @param name The value for name * @return {@code this} builder for use in a chained invocation */ public final Builder name(String name) { this.name = Objects.requireNonNull(name, "name"); initBits &= ~INIT_BIT_NAME; return this; } /** * Initializes the value for the {@link PushApplicationRequest#getNoHostname() noHostname} attribute. * @param noHostname The value for noHostname (can be {@code null}) * @return {@code this} builder for use in a chained invocation */ public final Builder noHostname(@Nullable Boolean noHostname) { this.noHostname = noHostname; return this; } /** * Initializes the value for the {@link PushApplicationRequest#getNoRoute() noRoute} attribute. * @param noRoute The value for noRoute (can be {@code null}) * @return {@code this} builder for use in a chained invocation */ public final Builder noRoute(@Nullable Boolean noRoute) { this.noRoute = noRoute; return this; } /** * Initializes the value for the {@link PushApplicationRequest#getNoStart() noStart} attribute. * @param noStart The value for noStart (can be {@code null}) * @return {@code this} builder for use in a chained invocation */ public final Builder noStart(@Nullable Boolean noStart) { this.noStart = noStart; return this; } /** * Initializes the value for the {@link PushApplicationRequest#getPath() path} attribute. * @param path The value for path (can be {@code null}) * @return {@code this} builder for use in a chained invocation */ public final Builder path(@Nullable Path path) { this.path = path; return this; } /** * Initializes the value for the {@link PushApplicationRequest#getRandomRoute() randomRoute} attribute. * @param randomRoute The value for randomRoute (can be {@code null}) * @return {@code this} builder for use in a chained invocation */ public final Builder randomRoute(@Nullable Boolean randomRoute) { this.randomRoute = randomRoute; return this; } /** * Initializes the value for the {@link PushApplicationRequest#getRoutePath() routePath} attribute. * @param routePath The value for routePath (can be {@code null}) * @return {@code this} builder for use in a chained invocation */ public final Builder routePath(@Nullable String routePath) { this.routePath = routePath; return this; } /** * Initializes the value for the {@link PushApplicationRequest#getStack() stack} attribute. * @param stack The value for stack (can be {@code null}) * @return {@code this} builder for use in a chained invocation */ public final Builder stack(@Nullable String stack) { this.stack = stack; return this; } /** * Initializes the value for the {@link PushApplicationRequest#getStagingTimeout() stagingTimeout} attribute. *

If not set, this attribute will have a default value as returned by the initializer of {@link PushApplicationRequest#getStagingTimeout() stagingTimeout}. * @param stagingTimeout The value for stagingTimeout * @return {@code this} builder for use in a chained invocation */ public final Builder stagingTimeout(Duration stagingTimeout) { this.stagingTimeout = Objects.requireNonNull(stagingTimeout, "stagingTimeout"); return this; } /** * Initializes the value for the {@link PushApplicationRequest#getStartupTimeout() startupTimeout} attribute. *

If not set, this attribute will have a default value as returned by the initializer of {@link PushApplicationRequest#getStartupTimeout() startupTimeout}. * @param startupTimeout The value for startupTimeout * @return {@code this} builder for use in a chained invocation */ public final Builder startupTimeout(Duration startupTimeout) { this.startupTimeout = Objects.requireNonNull(startupTimeout, "startupTimeout"); return this; } /** * Initializes the value for the {@link PushApplicationRequest#getTimeout() timeout} attribute. * @param timeout The value for timeout (can be {@code null}) * @return {@code this} builder for use in a chained invocation */ public final Builder timeout(@Nullable Integer timeout) { this.timeout = timeout; return this; } /** * Builds a new {@link PushApplicationRequest PushApplicationRequest}. * @return An immutable instance of PushApplicationRequest * @throws java.lang.IllegalStateException if any required attributes are missing */ public PushApplicationRequest build() { if (initBits != 0) { throw new IllegalStateException(formatRequiredAttributesMessage()); } return PushApplicationRequest.validate(new PushApplicationRequest(this)); } private String formatRequiredAttributesMessage() { List attributes = new ArrayList<>(); if ((initBits & INIT_BIT_NAME) != 0) attributes.add("name"); return "Cannot build PushApplicationRequest, some of required attributes are not set " + attributes; } } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy