j-easy/easy-batch: The simple, stupid batch framework for Java の
作った
注意点
EasyBatch の version に ついて
作成時期が4.0.0
で、5.1.0
に
5.0.0
で5.0.0
以上を
Echonest に ついて
以下のような
2016/05/29
日に
Greetings again from The Echo Nest Team at Spotify. If you are receiving this email we have noticed you are still making active API calls to The Echo Nest API.
As a follow-up to the news on March 29th, this is a friendly reminder that on Tuesday, May 31st, The Echo Nest platform will no longer serve requests and you will need to move over to the Spotify API. If you currently have an app that uses The Echo Nest API, check out the Spotify Web API. Thanks for helping us build the future of music together! The Echo Nest
Spotify Echo Nest API - Spotify Developer に
ただ、
Github repository
以下に
kemsakurai/easybatch-framework-example
実装した 内容
本家と
本家では
Twitter API と 連携する Sample が あるので、 The Echo Nest の API と 連携する。 RecordMapper で
1.
で取得した Artist
情報を別の オブジェクトに 変換する。 2.
で変換、 作成した オブジェクトを csv に 出力する。 Job の
処理結果を HTML レポートと して 出力する。 1
QuickStart
Echonest の
QuickStart
easybatch-framework-example の 説明
1. Main.java の 説明
以下、
// Execute jobs JobReport jobReport = JobBuilder.aNewJob() .reader(new EchonestReader()) .mapper(new ArtistCsvRowMapper()) .marshaller(new DelimitedRecordMarshaller(ArtistCsvRowMapper.Result.class, new String[]{"name", "familiarity", "hotttnesss"})) .writer(new FileRecordWriter("./outputs/echonest_result.csv")) .call(); // Output Reports HtmlJobReportFormatter htmlJobReportFormatter = new HtmlJobReportFormatter(); String html = htmlJobReportFormatter.formatReport(jobReport); try (FileWriter fw = new FileWriter("./outputs/job_report.html")) { fw.write(html); }
補足説明
JobBuilder.aNewJob()
でJobBuilder の 生成を 行います。 new JobBuilder() でも 動作に 変わりは ありません。 JobBuilder#reader()
でRecordReader を 設定します。 RecordReader で 複数件データを 読み 込んでも、 後続処理では、 1件ずつ 処理が 行われます。 2 JobBuilder#mapper()
でRecordMapper を 設定します。
RecordReader で読み込んだ Artist を、 別オブジェクトに 変換します。 JobBuilder#marshaller()
で、DelimitedRecordMarshaller を 設定。
オブジェクトをCSV 形式に 変換します。 使用可能な Marshaller は marshallers · j-easy/easy-batch Wiki に 記載されています。
DelimitedRecordMarshaller の変換元 Java クラスは、 フィールド の getter , setter を 実装する 必要が あり、 未実装だと 4.0.0
ではエラーに なります。 JobBuilder#writer()
でRecordWriter を 設定します。 CSV に 書き込みたいので、 FileRecordWriter を 使用します。 HtmlJobReportFormatter で、
JobBuilder#call()
の戻りの JobReport を HTML に 変換して、 File に 書き出します。
HTML レポートとして 以下のような ファイルが 出力されます。
2. EchonestReader.java
以下、
/** * EchonestReader * * @author Kem */ public class EchonestReader implements RecordReader { private final List<Artist> artists = new ArrayList<>(); private int index = 0; private EchoNestAPI en; private final String key = "XXXXXXXXXXXXXXXXX"; public EchonestReader() { en = new EchoNestAPI(key); } public boolean hasNextRecord() { return index < artists.size(); } public Long getTotalRecords() { return (long) artists.size(); } public void open() throws RecordReaderOpeningException { int start = 0; while (start % 100 == 0) { try { Params param = new Params(); param.add("genre", "hip house"); param.add("start", start); param.add("results", 100); param.add("bucket", "familiarity"); param.add("bucket", "hotttnesss"); List<Artist> results = en.searchArtists(param); start += results.size(); artists.addAll(results); try { Thread.sleep(4000); } catch (InterruptedException ex) { Logger.getLogger(EchonestReader.class.getName()).log(Level.SEVERE, null, ex); } } catch (EchoNestException ex) { Logger.getLogger(EchonestReader.class.getName()).log(Level.SEVERE, null, ex); } } } public Record readNextRecord() throws RecordReadingException { Artist artist = artists.get(index); Header header = new Header((long) index, artist.toString(), new Date()); index++; return new GenericRecord<>(header, artist); } public String getDataSourceName() { return "Echonest result"; } public void close() throws RecordReaderClosingException { en = null; } }
補足説明
RecordReader#open()
データ取得を行います。 EchonestReader は Echonest に 対して ジャンル hip house
に属する artist を 問い 合わせします。
問い合わせた 後、 4秒 sleep して、 リクエスト制限を 超えないように しています。
デフォルトの取得属性に 加えて、 familiarity
(どれくらい一般的に 知られているかを 示す 指標)、 hotttnesss
(どれくらいアツい artist かを 示す 指標) を 取得します。 RecordReader#hasNextRecord()
次に処理すべき レコードが あるのかを boolean 値で 返します。 RecordReader#getTotalRecords()
open()
で読み込んだ レコード総数を 返します。 RecordReader#readNextRecord()
open()
メソッドで読み込んだ データを 1件ずつ 取得します。
取得して、次の 1件への ロジックを 記載する 必要が あります。 RecordReader#getDataSourceName()
データソース名を返します。 ログに 出力したり、 Header名称と して 使用したりします。 RecordReader#close()
open()
したものに 対しての close 処理を 記述します。
jdbc リソースであれば、Connection#close()、 ResultSet#close() を 行う 必要が あります。
3. ArtistCsvRowMapper.java
/** * ArtistCsvRowMapper * * @author Kem */ public class ArtistCsvRowMapper implements RecordMapper<Record<Artist>, Record<ArtistCsvRowMapper.Result>> { @Override public GenericRecord<Result> processRecord(Record<Artist> record) throws RecordMappingException { Result result = null; try { Artist artist = record.getPayload(); result = new Result(); result.name = artist.getName(); result.familiarity = String.valueOf(artist.getFamiliarity()); result.hotttnesss = String.valueOf(artist.getHotttnesss()); } catch (EchoNestException ex) { Logger.getLogger(ArtistCsvRowMapper.class.getName()).log(Level.SEVERE, null, ex); } Header header = record.getHeader(); return new GenericRecord<>(header, result); } public static class Result { private String name; private String familiarity; private String hotttnesss; public String getName() { return name; } public void setName(String name) { this.name = name; } public String getFamiliarity() { return familiarity; } public void setFamiliarity(String familiarity) { this.familiarity = familiarity; } public String getHotttnesss() { return hotttnesss; } public void setHotttnesss(String hotttnesss) { this.hotttnesss = hotttnesss; } } }
補足説明
ArtistCsvRowMapper#processRecord()
Record からRecord へ 変換する メソッドです。
入力 Record のRecord#getPayload()
でオブジェクト実体を 取得して、 出力 Record に 変換します。 Result.java
戻り値の 出力 Record に 設定する データクラスです。
その他補足 と 感想
HtmlJobReportFormatter、
FileRecordWriterを 使用するには、 以下の ライブラリを 追加する 必要が あります。 以下、 build.gradleの 抜粋です。 compile 'org.easybatch:easybatch-tools:4.0.0' compile 'org.easybatch:easybatch-flatfile:4.0.0'
Writer や
Marshaller は ライブラリで 提供されている ものを 使いましたが、 提供される 実装は 他にもあります。
Home · j-easy/easy-batch WikiのComponent reference
のページに 詳しく 記載されています。 拡張ライブラリも
ありますが、 MongoDB の 依存関係で pom 地獄に 陥りました。 途中導入は たいへんかもしれません。 個人的には
設定ファイルレスは 非常に よいかと 思います。 書きやすいです。 reader()
、wirter()
メソッドに対象クラスを インスタンス化 して 設定して、 JOB定義を 作る 方式なので、 guice 経由で インスタンス化すれば、 DI も 可能です。 3
EasyBatch の
説明は
HTML レポート、
CSV は outputs ディレクトリ配下に 出力されます。 ↩ 5.1.0
だと、batchSize()
で処理件数を 設定できるようです。 Home · j-easy/easy-batch Wiki ↩ DI を
実行する JobBuilder を 作ってもよいかもしれません。 ↩
コメント