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

main.misk.cloud.gcp.GoogleCloudModule.kt Maven / Gradle / Ivy

The newest version!
package misk.cloud.gcp

import com.google.auth.Credentials
import com.google.auth.oauth2.ServiceAccountCredentials
import com.google.cloud.NoCredentials
import com.google.cloud.datastore.Datastore
import com.google.cloud.datastore.DatastoreOptions
import com.google.cloud.http.HttpTransportOptions
import com.google.cloud.storage.Storage
import com.google.cloud.storage.StorageOptions
import com.google.common.util.concurrent.AbstractIdleService
import com.google.inject.Provides
import jakarta.inject.Singleton
import misk.ReadyService
import misk.ServiceModule
import misk.cloud.gcp.datastore.DatastoreConfig
import misk.cloud.gcp.storage.LocalStorageRpc
import misk.cloud.gcp.storage.StorageConfig
import misk.inject.KAbstractModule
import wisp.deployment.Deployment
import wisp.logging.getLogger
import java.nio.file.Paths
import jakarta.inject.Inject

/** Installs support for talking to real GCP services, either direct or via emulator */
class GoogleCloudModule(
  private val datastoreConfig: DatastoreConfig,
  private val storageConfig: StorageConfig
) : KAbstractModule() {
  override fun configure() {
    bind().toInstance(datastoreConfig)
    bind().toInstance(storageConfig)
    install(ServiceModule().enhancedBy())
  }

  @Provides
  @Singleton
  fun provideServiceCredentials(deployment: Deployment): Credentials =
    if (deployment.isLocalDevelopment) NoCredentials.getInstance()
    else ServiceAccountCredentials.getApplicationDefault()

  @Provides
  @Singleton
  fun provideCloudDatastore(credentials: Credentials, config: DatastoreConfig): Datastore =
    DatastoreOptions.newBuilder()
      .setCredentials(credentials)
      .setHost(config.transport.host)
      .setTransportOptions(
        HttpTransportOptions.newBuilder()
          .setConnectTimeout(config.transport.connect_timeout_ms)
          .setReadTimeout(config.transport.read_timeout_ms)
          .build()
      )
      .build()
      .service

  @Provides
  @Singleton
  fun provideCloudStorage(credentials: Credentials, config: StorageConfig): Storage {
    if (config.use_local_storage) {
      val localStorageConfig = config.local_storage
        ?: throw IllegalArgumentException(
          "if use_local_storage is true, local_storage.data_dir must be set"
        )

      val dataDir = localStorageConfig.data_dir
      require(dataDir.isNotBlank()) {
        "if use_local_storage is true, local_storage.data_dir must be set"
      }

      val localStorageRpc = LocalStorageRpc(Paths.get(dataDir))
      return StorageOptions.newBuilder()
        .setCredentials(NoCredentials.getInstance())
        .setServiceRpcFactory { _ -> localStorageRpc }
        .build()
        .service
    } else {
      return StorageOptions.newBuilder()
        .setCredentials(credentials)
        .setHost(config.transport.host)
        .setTransportOptions(
          HttpTransportOptions.newBuilder()
            .setConnectTimeout(config.transport.connect_timeout_ms)
            .setReadTimeout(config.transport.read_timeout_ms)
            .build()
        )
        .build()
        .service
    }
  }
}

/** Logs cloud configuration on startup */
@Singleton
private class GoogleCloud @Inject constructor(
  private val datastore: Datastore,
  private val storage: Storage
) : AbstractIdleService() {
  override fun startUp() {
    log.info { "running as project ${datastore.options.projectId}" }
    log.info { "connected to datastore on ${datastore.options.host}" }
    log.info {
      "connected to GCS as ${storage.options.rpc.javaClass.simpleName} on ${storage.options.host}"
    }
  }

  override fun shutDown() {}

  companion object {
    private val log = getLogger()
  }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy