Логика экспорта хранилища данных в Java - PullRequest
0 голосов
/ 15 ноября 2018

К счастью, Google анонсировала логику экспорта из облачного хранилища данных. Я хотел бы настроить экспорт по расписанию на моей платформе. Однако это не Python, а Java. Поэтому мне нужно использовать cron.xml и логику Java для разработки этой логики.

Есть ли какая-либо ссылка на логику экспорта проекта Datastore (cloud_datastore_admin.py) в Java? Особенно мне нужно преобразовать эту часть в Java

app = webapp2.WSGIApplication(
[
    ('/cloud-datastore-export', Export),
], debug=True)

https://cloud.google.com/datastore/docs/schedule-export

Ответы [ 3 ]

0 голосов
/ 28 ноября 2018

Что я действительно понял, так это то, что app.yaml похож на Web.xml в java и cloud-datastore-export - это сервлет, который связывается с gae для экспорта данных, но я не могу сделать больше

0 голосов
/ 29 ноября 2018

Вы можете создать каркас для App Egnine с помощью , следуя этим инструкциям .

Получив скелет, добавьте что-то подобное для обработки запросов на экспорт:

CloudDatastoreExport.java

package com.google.example.datastore;

import com.google.appengine.api.appidentity.AppIdentityService;
import com.google.appengine.api.appidentity.AppIdentityServiceFactory;
import com.google.apphosting.api.ApiProxy;
import com.google.common.io.CharStreams;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.HttpURLConnection;
import java.net.URL;
import java.nio.charset.StandardCharsets;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.logging.Logger;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.json.JSONArray;
import org.json.JSONObject;
import org.json.JSONTokener;

@WebServlet(name = "CloudDatastoreExport", value = "/cloud-datastore-export")
public class CloudDatastoreExport extends HttpServlet {

  private static final Logger log = Logger.getLogger(CloudDatastoreExport.class.getName());

  @Override
  public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException {

    // Verify outputURL parameter
    String outputUrlPrefix = request.getParameter("output_url_prefix");

    if (outputUrlPrefix == null || !outputUrlPrefix.matches("^gs://.*")) {
      response.setStatus(HttpServletResponse.SC_CONFLICT);
      response.setContentType("text/plain");
      response.getWriter().println("Error: Must provide a valid output_url_prefix.");

    } else {

      // Get project ID
      String projectId = ApiProxy.getCurrentEnvironment().getAppId();
      // Remove partition information to get plain app ID
      String appId = projectId.replaceFirst("(.*~)", "");

      // Get access token
      ArrayList<String> scopes = new ArrayList<String>();
      scopes.add("https://www.googleapis.com/auth/datastore");
      final AppIdentityService appIdentity = AppIdentityServiceFactory.getAppIdentityService();
      final AppIdentityService.GetAccessTokenResult accessToken =
          appIdentity.getAccessToken(scopes);

      // Read export parameters
      // If output prefix does not end with slash, add a timestamp
      if (!outputUrlPrefix.substring(outputUrlPrefix.length() - 1).contentEquals("/")) {
        String timeStamp = new SimpleDateFormat("yyyyMMddHHmmss").format(new Date());
        outputUrlPrefix = outputUrlPrefix + "/" + timeStamp + "/";
      }

      String[] namespaces = request.getParameterValues("namespace_id");
      String[] kinds = request.getParameterValues("kind");

      // Build export request
      JSONObject exportRequest = new JSONObject();
      exportRequest.put("output_url_prefix", outputUrlPrefix);

      JSONObject entityFilter = new JSONObject();

      if (kinds != null) {
        JSONArray kindsJSON = new JSONArray(kinds);
        entityFilter.put("kinds", kinds);
      }

      if (namespaces != null) {
        JSONArray namespacesJSON = new JSONArray(namespaces);
        entityFilter.put("namespaceIds", namespacesJSON);
      }

      exportRequest.put("entityFilter", entityFilter);

      URL url = new URL("https://datastore.googleapis.com/v1/projects/" + appId + ":export");
      HttpURLConnection connection = (HttpURLConnection) url.openConnection();
      connection.setDoOutput(true);
      connection.setRequestMethod("POST");
      connection.addRequestProperty("Content-Type", "application/json");
      connection.addRequestProperty("Authorization", "Bearer " + accessToken.getAccessToken());

      OutputStreamWriter writer = new OutputStreamWriter(connection.getOutputStream());
      exportRequest.write(writer);
      writer.close();

      if (connection.getResponseCode() == HttpURLConnection.HTTP_OK) {

        JSONTokener exportResponseTokens = new JSONTokener(connection.getInputStream());
        JSONObject exportResponse = new JSONObject(exportResponseTokens);

        response.setContentType("text/plain");
        response.getWriter().println("Export started:\n" + exportResponse.toString(4));

      } else {
        InputStream s = connection.getErrorStream();
        InputStreamReader r = new InputStreamReader(s, StandardCharsets.UTF_8);
        String errorMessage =
            String.format(
                "got error (%d) response %s from %s",
                connection.getResponseCode(), CharStreams.toString(r), connection.toString());
        log.warning(errorMessage);
        response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
        response.setContentType("text/plain");
        response.getWriter().println("Failed to initiate export.");
      }
    }
  }
}

Вы можете использовать тот же cron.yaml из документов:

cron:
- description: "Daily Cloud Datastore Export"
  url: /cloud-datastore-export?namespace_id=&output_url_prefix=gs://BUCKET_NAME[/NAMESPACE_PATH]
  target: cloud-datastore-admin
  schedule: every 24 hours

Используйте gcloud для развертывания задания cron:

gcloud app deploy cron.yaml

Убедитесь, что вы выполнили эту часть, чтобы дать разрешения на экспорт и ведение GAE, иначе вы получите ошибки об отказе в разрешении:

https://cloud.google.com/datastore/docs/schedule-export#before_you_begin

0 голосов
/ 16 ноября 2018

Фрагмент кода, который вы показали, является лишь частью типичного каркаса приложения GAE, характерного для приложений Python стандартной среды 1-го поколения.Вы можете легко узнать это в разделе main.py быстрого запуска Python Обзор кода Hello World .

Код инициализирует переменную app (из модуля main python, то есть файла main.py), на которую в конфигурации обработчика app.yaml ссылаются как script: main.app.

Соответствующий скелет Java-приложения существенно отличается, см. Краткий старт Java Обзор кода Hello World .Но не беспокойтесь, вам не нужно специально преобразовывать этот фрагмент кода, вам просто нужно построить каркас Java-приложения и сосредоточиться на том, что фактически делает обработчик приложения - отправляя эти POST запросы в хранилище данных.Извините, я не могу помочь больше, но я не пользователь Java.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...