@Override
  public void initialize(ExtensionContext context) {
    // Note: initialize could be called twice in an account migration scenario
    // where we import and export to the same service provider. So just return
    // rather than throwing if called multiple times.
    if (initialized) return;

    JobStore jobStore = context.getService(JobStore.class);
    HttpTransport httpTransport = context.getService(HttpTransport.class);
    JsonFactory jsonFactory = context.getService(JsonFactory.class);
    OkHttpClient client = new OkHttpClient.Builder().build();
    ObjectMapper mapper = new ObjectMapper();

    AppCredentials appCredentials;
    try {
      appCredentials =
          context
              .getService(AppCredentialStore.class)
              .getAppCredentials("KOOFR_KEY", "KOOFR_SECRET");
    } catch (IOException e) {
      Monitor monitor = context.getMonitor();
      monitor.info(
          () -> "Unable to retrieve Koofr AppCredentials. Did you set KOOFR_KEY and KOOFR_SECRET?");
      return;
    }

    // Create the KoofrCredentialFactory with the given {@link AppCredentials}.
    KoofrCredentialFactory credentialFactory =
        new KoofrCredentialFactory(httpTransport, jsonFactory, appCredentials);

    Monitor monitor = context.getMonitor();

    int fileUploadReadTimeout = context.getSetting("koofrFileUploadReadTimeout", 60000);
    int fileUploadWriteTimeout = context.getSetting("koofrFileUploadWriteTimeout", 60000);

    monitor.info(
        () ->
            format(
                "Configuring Koofr HTTP file upload client with read timeout %d ms and write timeout %d ms",
                fileUploadReadTimeout, fileUploadWriteTimeout));

    OkHttpClient fileUploadClient =
        client
            .newBuilder()
            .readTimeout(fileUploadReadTimeout, TimeUnit.MILLISECONDS)
            .writeTimeout(fileUploadReadTimeout, TimeUnit.MILLISECONDS)
            .build();

    KoofrClientFactory koofrClientFactory =
        new KoofrClientFactory(
            BASE_API_URL, client, fileUploadClient, mapper, monitor, credentialFactory);

    ImmutableMap.Builder<DataVertical, Importer> importBuilder = ImmutableMap.builder();
    importBuilder.put(PHOTOS, new KoofrPhotosImporter(koofrClientFactory, monitor, jobStore));
    importBuilder.put(VIDEOS, new KoofrVideosImporter(koofrClientFactory, monitor, jobStore));
    importerMap = importBuilder.build();

    ImmutableMap.Builder<DataVertical, Exporter> exportBuilder = ImmutableMap.builder();
    exportBuilder.put(PHOTOS, new KoofrPhotosExporter(koofrClientFactory, monitor));
    exportBuilder.put(VIDEOS, new KoofrVideosExporter(koofrClientFactory, monitor));
    exporterMap = exportBuilder.build();

    initialized = true;
  }
Bootstraps the Koofr data transfer services.
extensions/data-transfer/portability-data-transfer-koofr/src/main/java/org/datatransferproject/transfer/koofr/KoofrTransferExtension.java