GAE/Jで本番環境のデータをローカルに取り込みたいことがあったので、Remote APIを利用してみました。ここでは、ローカル環境のGAEから本番へのリモートアクセスでデータを取得し、取得したデータをローカルのDatastoreに保存する方法を説明します。
#前提
以下のバージョンで実装を行なっています。
- Java: Java8
- appengine-java-sdk: 1.9.57
#準備
###Remote APIの有効化
プロジェクトのweb.xmlに以下を追記します。
web.xml
<servlet>
<display-name>Remote API Servlet</display-name>
<servlet-name>RemoteApiServlet</servlet-name>
<servlet-class>com.google.apphosting.utils.remoteapi.RemoteApiServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>RemoteApiServlet</servlet-name>
<url-pattern>/remote_api</url-pattern>
</servlet-mapping>
appengine-remote-api.jarの追加
Remote APIのクライアントコンポーネントを利用するために、${JAVA-SDK-ROOT}/lib/appengine-remote-api.jar
をWEB-INF/lib
ディレクトリに追加し、クラスパスを通します。
#実装
Kind名"book"のデータをローカルに取り込みます。
import com.google.appengine.tools.remoteapi.RemoteApiInstaller;
import com.google.appengine.tools.remoteapi.RemoteApiOptions;
// ...
RemoteApiOptions options = new RemoteApiOptions()
.server("your_app_id.appspot.com", 443)
.useApplicationDefaultCredential();
RemoteApiInstaller installer = new RemoteApiInstaller();
DatastoreService datastore = DatastoreServiceFactory.getDatastoreService();
List<Entity> books;
try {
installer.install(options);
Query q = new Query("book");
books = datastore.prepare(q).asList(FetchOptions.Builder.withDefaults());
} finally {
installer.uninstall();
}
// ローカルに保存するために、データを移し替える
List<Entity> devBooks = new ArrayList<>();
for (Entity book : books) {
Entity devBook = new Entity(book.getKind(), book.getKey().getName());
devBook.setPropertiesFrom(book);
devBooks.add(devBook);
}
datastore.put(devBooks);
本番から取得したデータをそのままdatastore.put()
した場合はうまくいきませんでしたが、上記の方法でローカルに取り込むことができました。