Spring Boot ã§æ¸ç±ã®è²¸åºç¶æ³ç¢ºèªã»è²¸åºç³è«ãã Web ã¢ããªã±ã¼ã·ã§ã³ãä½ã ( ãã®ï¼ï¼ )( 貸åºç¶æ³åå¾ã¿ã¹ã¯ã®ä½æ )
æ¦è¦
- ä»åã®æé ã§ç¢ºèªã§ããã®ã¯ä»¥ä¸ã®å
容ã§ããï¼ï½ï¼åã«åãã¦æ¸ãã¾ãã
- å¥ã®è¨äºãæ¸ãã¦ãã¦æ°ã¥ãã以ä¸ã®ï¼ç¹ãåæ ãã¾ãã
- Spring Boot 㧠Doma 2 ã使ç¨ããã«ã¯ ã§ä¿®æ£ãã DomaConfig ã¯ã©ã¹ã®åæ
- TestDataResource ã¯ã©ã¹ã® before ã¡ã½ããå ã®ã³ã¡ã³ãã¢ã¦ããã¦ããå¦çã®åé¤
- 貸åºç¶æ³åå¾ã¿ã¹ã¯ã®ä½æ
- RabbitMQ ãªã¹ãã¼ã®ä½æ
- ã«ã¼ãªã«ã®èµæ¸æ¤ç´¢ WebAPI ãå¼ã³åºãã¦è²¸åºç¶æ³ãåå¾ããå¦çã®ä½æ
- å¥ã®è¨äºãæ¸ãã¦ãã¦æ°ã¥ãã以ä¸ã®ï¼ç¹ãåæ ãã¾ãã
åç §ãããµã¤ãã»æ¸ç±
-
convert to different javatype when use @RabbitListener annonation
https://jira.spring.io/browse/AMQP-461- @RabbitListener ã¢ããã¼ã·ã§ã³ãä»å ããã¡ã½ããã§åä¿¡ããã¡ãã»ã¼ã¸ããªãã¸ã§ã¯ãã«å¤æããæ¹æ³ãåèã«ãã¾ããã
-
Java 8 "Optional" ï½ ããããã®nullã¨ã®ä»ãåãæ¹ ï½
http://qiita.com/shindooo/items/815d651a72f568112910- Java 8 ã§å°å ¥ããã Optional ã®ä½¿ãæ¹ãåèã«ãã¾ããã
ç®æ¬¡
- ã¯ããã«
- å¥ã®è¨äºãæ¸ãã¦ãã¦æ°ã¥ããç¹ã®åæ
- RabbitMQ ãªã¹ãã¼ã®ä½æ
- ã«ã¼ãªã«ã®èµæ¸æ¤ç´¢ WebAPI ã®ã¬ã¹ãã³ã¹ã®åºåå½¢å¼ãæ¤è¨ãã
- ã«ã¼ãªã«ã®èµæ¸æ¤ç´¢ WebAPI ãå¼ã³åºãã¦è²¸åºç¶æ³ãåå¾ããå¦çã®ä½æ
- åä½ç¢ºèª
- 次åã¯ããã
- ã¡ã¢æ¸ã
æé
ã¯ããã«
貸åºå¸ææ¸ç± CSV ãã¡ã¤ã«ã¢ãããã¼ãç»é¢ãããã¼ã¿ãç»é²ããããã«ã¼ãªã«ã®èµæ¸æ¤ç´¢ WebAPIã§è²¸åºç¶æ³ãåå¾ãã貸åºç¶æ³åå¾ã¿ã¹ã¯ãä½æãã¾ãã
- RabbitMQ ã®ãã¥ã¼ãç£è¦ãã貸åºå¸ææ¸ç± CSV ãã¡ã¤ã«ã¢ãããã¼ãç»é¢ãã貸åºç¶æ³åå¾ä¾é ¼ã®ã¡ãã»ã¼ã¸ãéä¿¡ããã¦ããããã§ãã¯ãã¾ãã
- ãã¼ã¿ãç»é²ããã¦ããå ´åã«ã¯ã«ã¼ãªã«ã®èµæ¸æ¤ç´¢ WebAPI ãå¼ã³åºãã¦è²¸åºç¶æ³ãåå¾ãã¾ãã
- å¦çãå®äºããããã¼ã¿ãç»é²ããã¦ã¼ã¶ã¸ã¡ã¼ã«ãéä¿¡ãã¾ãã
以ä¸ã®é åºã§é²ããäºå®ã§ãã
- RabbitMQ ãªã¹ãã¼ã®ä½æ
- ã«ã¼ãªã«ã®èµæ¸æ¤ç´¢ WebAPI ãå¼ã³åºãã¦è²¸åºç¶æ³ãåå¾ããå¦çã®ä½æ
- ã¡ã¼ã«éä¿¡å¦çã®ä½æ
- ãã¹ãã®ä½æ
å¥ã®è¨äºãæ¸ãã¦ãã¦æ°ã¥ããç¹ã®åæ
貸åºç¶æ³åå¾ã¿ã¹ã¯ã®ä½æã«å ¥ãåã« Spring Boot 㧠Doma 2 ã使ç¨ããã«ã¯ åã³ èªä½ãããã¹ãç¨ã¯ã©ã¹ ( src/test/java/ksbysample/common/test ) ã®ä½¿ãæ¹ ãæ¸ãã¦ãã¦ä¿®æ£ããæ¹ãããç¹ãè¦ã¤ããã®ã§åæ ãã¾ãã
DomaConfig ã¯ã©ã¹ã®ä¿®æ£
ä»åãããã©ã³ãåã "feature/" + [GitHubã®Issueã®çªå·] + "-issue" ã«ãã¾ããfeature/32-issue ãã©ã³ããä½æãã¾ãã
src/main/java/ksbysample/webapp/lending/config ã®ä¸ã® DomaConfig.java ã ãªã³ã¯å ã®å 容 ã«å¤æ´ãã¾ãã
Commitï¼Pushãfeature/32-issue -> 1.0.x 㸠Pull RequestãMergeãfeature/32-issue ãã©ã³ããåé¤ã#32 Issue ãã¯ãã¼ãºãã¾ãã
TestDataResource ã¯ã©ã¹ã® before ã¡ã½ããå ã®ã³ã¡ã³ãã¢ã¦ããã¦ããå¦çã®åé¤
feature/34-issue ãã©ã³ããä½æãã¾ãã
src/main/java/ksbysample/common/test ã®ä¸ã® TestDataResource.java ã ãªã³ã¯å ã®å 容 ã«å¤æ´ãã¾ãã
Commitï¼Pushãfeature/34-issue -> 1.0.x 㸠Pull RequestãMergeãfeature/34-issue ãã©ã³ããåé¤ã#34 Issue ãã¯ãã¼ãºãã¾ãã
RabbitMQ ãªã¹ãã¼ã®ä½æ
feature/37-issue ãã©ã³ããä½æãã¾ãã
src/main/java/ksbysample/webapp/lending ã®ä¸ã« listener.rabbitmq ããã±ã¼ã¸ãä½æãã¾ãã
MessageConverter ããªã¹ãã¼ã¯ã©ã¹ã§ãå ±éã§ä½¿ç¨ã§ããããã«ããããã« Bean ã¨ãã¦å®ç¾©ãã¾ããsrc/main/java/ksbysample/webapp/lending/config ã®ä¸ã® ApplicationConfig.java ã ãªã³ã¯å ã®å 容 ã«å¤æ´ãã¾ãã
src/main/java/ksbysample/webapp/lending/service/queue ã®ä¸ã® InquiringStatusOfBookQueueService.java ã ãªã³ã¯å ã®å 容 ã«å¤æ´ãã¾ãã
src/main/java/ksbysample/webapp/lending/listener/rabbitmq ã®ä¸ã« InquiringStatusOfBookQueueListener.java ãä½æãã¾ããä½æå¾ããªã³ã¯å ã®ãã®ï¼ã®å 容 ã«å¤æ´ãã¾ãã
ã«ã¼ãªã«ã®èµæ¸æ¤ç´¢ WebAPI ã®ã¬ã¹ãã³ã¹ã®åºåå½¢å¼ãæ¤è¨ãã
ã«ã¼ãªã«ã®èµæ¸æ¤ç´¢API 㯠format ãã©ã¡ã¼ã¿ãæå®ãããã¨ã§ JSONãXML ããããã®åºåå½¢å¼ãæå®ãããã¨ãã§ãã¾ãããå³æ¸é¤¨APIä»æ§æ¸ ã®çµæã®ä¾ãè¦ã㨠JSON ã®å ´åã« "é ç®å: å¤" ã®å½¢å¼ã§ã¯ãªãé ç®åã®é¨åã«å¤ãã»ããããã¦ããå ´åããããJackson ã§å¦çãããã®ãé£ãã ( ã¨ããããé ç®åã«ãå¤ãã»ããããã¦ããå ´åãã©ããã£ã¦å¦çãããã°ããã®ã ããï¼ ) ããã«æãã¾ãããXML ã®æ¹ãå¦çãããããã§ããã° XML ã«ãããã¨æãã¾ãã®ã§ãä¸æ¦ä¸¡æ¹ã®ãã©ã¼ãããã§åºåãã¦ã¿ããã¨ã«ãã¾ãã
ã¾ã㯠JSON ã®å ´åã§ããhttp://api.calil.jp/check?appkey={appkey}&systemid=Tokyo_NDL&isbn=9784774163666&format=json ã§å¼ã³åºãã¾ã ( {appkey} ã®é¨åã¯ç½®ãæãã¦ãã ãã )ã
callback({ "session": "f6e5.....6f70", "books": { "978-4-7741-6366-6": { "Tokyo_NDL": { "status": "Cache", "reserveurl": "https://ndlopac.ndl.go.jp/F/.....(é·ãã®ã§çç¥).....", "libkey": { "æ±äº¬æ¬é¤¨": "èµæ¸ãã" } } } }, "continue": 0 });
次㯠XML ã®å ´åã§ããhttp://api.calil.jp/check?appkey={appkey}&systemid=Tokyo_NDL&isbn=9784774163666&format=xml ã§å¼ã³åºãã¾ãã
<?xml version="1.0" encoding="UTF-8"?> <result> <session>169d.....654a</session> <continue>0</continue> <books> <book isbn="978-4-7741-6366-6" calilurl="http://calil.jp/book/477416366X"> <system systemid="Tokyo_NDL"> <status>Cache</status> <reserveurl> https://ndlopac.ndl.go.jp/.....(é·ãã®ã§çç¥)..... </reserveurl> <libkeys> <libkey name="æ±äº¬æ¬é¤¨">èµæ¸ãã</libkey> </libkeys> </system> </book> </books> </result>
XML ã®æ¹ããã¡ãã¨æ§é åããã¦ãã¦å¦çããããããªã®ã§ãXML ã使ç¨ãããã¨ã«ãã¾ãã
ã«ã¼ãªã«ã®èµæ¸æ¤ç´¢ WebAPI ãå¼ã³åºãã¦è²¸åºç¶æ³ãåå¾ããå¦çã®ä½æ
æåã«ã¬ã¹ãã³ã¹ã®ãã¼ã¿ãå±éããããã®ã¯ã©ã¹ãä½æãã¾ãã
src/main/java/ksbysample/webapp/lending/service/calilapi ã®ä¸ã« CheckApiResponse.java ãä½æãã¾ããä½æå¾ããªã³ã¯å ã®å 容 ã«å¤æ´ãã¾ãã
src/main/java/ksbysample/webapp/lending/service/calilapi ã®ä¸ã« Book.java ãä½æãã¾ããä½æå¾ããªã³ã¯å ã®å 容 ã«å¤æ´ãã¾ãã
src/main/java/ksbysample/webapp/lending/service/calilapi ã®ä¸ã« SystemData.java ãä½æãã¾ããä½æå¾ããªã³ã¯å ã®å 容 ã«å¤æ´ãã¾ãã
src/main/java/ksbysample/webapp/lending/service/calilapi ã®ä¸ã« Libkey.java ãä½æãã¾ããä½æå¾ããªã³ã¯å ã®å 容 ã«å¤æ´ãã¾ãã
èµæ¸æ¤ç´¢APIãå¼ã³åºãå¦çãå®è£ ãã¾ããsrc/main/java/ksbysample/webapp/lending/service/calilapi ã®ä¸ã® CalilApiService.java ã ãªã³ã¯å ã®å 容 ã«å¤æ´ãã¾ãã
lending_app ãã¼ãã«ã®ãã¼ã¿ãããã¯ããããã®ã¡ã½ããã追å ãã¾ããsrc/main/java/ksbysample/dao ã®ä¸ã® LendingAppDao.java ã ãªã³ã¯å ã®å 容 ã«å¤æ´ãã¾ãã
ãã¼ã¿ãããã¯ããããã®ã¡ã½ãã㨠lending_book.lending_state ã ãæ´æ°ããã¡ã½ãããä½æãã¾ããsrc/main/java/ksbysample/dao ã®ä¸ã® LendingBookDao.java ã ãªã³ã¯å ã®å 容 ã«å¤æ´ãã¾ãã
貸åºç¶æ³ãæªç¢ºèªã®æã¨ç¢ºèªæ¸ã®æ㧠lending_app ãã¼ãã«ã® status ã®å¤ãç°ãªãããã«ãããã®ã§ãå¤ã追å ãã¾ããsrc/main/java/ksbysample/webapp/lending/values ã®ä¸ã® LendingAppStatusValues.java ã ãªã³ã¯å ã®å 容 ã«å¤æ´ãã¾ãã
â»Spring Boot ã§æ¸ç±ã®è²¸åºç¶æ³ç¢ºèªã»è²¸åºç³è«ãã Web ã¢ããªã±ã¼ã·ã§ã³ãä½ã ( ãã®ï¼ )( DBããã¼ãã«ã®ä½æ ) ã®è¨äºãä¿®æ£ãã¾ããã
ãã©ã³ã¶ã¯ã·ã§ã³ãéå§ãããããã«ãªã¹ãã¼ããå¼ã³åºã Service ã¯ã©ã¹ãä½æãã¾ããsrc/main/java/ksbysample/webapp/lending/listener/rabbitmq ã®ä¸ã« InquiringStatusOfBookQueueListenerService.java ãä½æãã¾ããä½æå¾ããªã³ã¯å ã®å 容 ã«å¤æ´ãã¾ãã
ãªã¹ãã¼ã®å¦çãå®è£ ãã¾ããsrc/main/java/ksbysample/webapp/lending/listener/rabbitmq ã®ä¸ã® InquiringStatusOfBookQueueListener.java ã ãªã³ã¯å ã®ãã®ï¼ã®å 容 ã«å¤æ´ãã¾ãã
åä½ç¢ºèª
ããã¾ã§ã®å®è£ ãåä½ç¢ºèªãã¾ãã
lending_appãlending_book ãã¼ãã«ã®ãã¼ã¿ãã¯ãªã¢ãã¾ãã
Gradle projects View ãã bootRun ã¿ã¹ã¯ãå®è¡ã㦠Tomcat ãèµ·åãã¾ãã
ãã©ã¦ã¶ãèµ·åã http://localhost:8080/booklist ã¸ã¢ã¯ã»ã¹ãã¾ããæåã¯ãã°ã¤ã³ç»é¢ã表示ããã¾ãã®ã§ ID ã« "[email protected]"ãPassword ã« "taro" ãå ¥åãã¦ãã次åããèªåçã«ãã°ã¤ã³ãããããã§ãã¯ããã«ããã°ã¤ã³ããã¿ã³ãã¯ãªãã¯ãã¾ãã
ãã¹ã.csv ãã¢ãããã¼ããã¾ãã
ãªã¹ãã¼ãå¼ã³åºããã¦å¦çãå®è¡ããã¾ãããã°ã«ã«ã¼ãªã«ã®èµæ¸æ¤ç´¢API ã®ã¬ã¹ãã³ã¹ãå±éããçµæãåºåããã¦ãããã¨ã確èªã§ãã¾ãã
ã«ã¼ãªã«ã®èµæ¸æ¤ç´¢API ãå¼ã³åºããã¬ã¹ãã³ã¹ãåå¾ãã¾ããã CheckApiResponse(session=cde7...4459, continueValue=0, bookList=[ Book(isbn=978-4-7973-8014-9, calilurl=http://calil.jp/book/4797380144, system=SystemData(systemid=Tokyo_NDL, status=Cache, reserveurl=https://ndlopac.ndl.go.jp/..., libkeyList=[Libkey(name=æ±äº¬æ¬é¤¨, value=èµæ¸ãã)])) , Book(isbn=978-4-7973-4778-4, calilurl=http://calil.jp/book/4797347783, system=SystemData(systemid=Tokyo_NDL, status=Cache, reserveurl=https://ndlopac.ndl.go.jp/..., libkeyList=[Libkey(name=æ±äº¬æ¬é¤¨, value=èµæ¸ãã)])) , Book(isbn=978-4-7741-6366-6, calilurl=http://calil.jp/book/477416366X, system=SystemData(systemid=Tokyo_NDL, status=Cache, reserveurl=https://ndlopac.ndl.go.jp/..., libkeyList=[Libkey(name=æ±äº¬æ¬é¤¨, value=èµæ¸ãã)])) , Book(isbn=978-4-87311-704-1, calilurl=http://calil.jp/book/4873117046, system=SystemData(systemid=Tokyo_NDL, status=Cache, reserveurl=https://ndlopac.ndl.go.jp/..., libkeyList=[Libkey(name=æ±äº¬æ¬é¤¨, value=èµæ¸ãã)])) , Book(isbn=978-4-7741-5377-3, calilurl=http://calil.jp/book/477415377X, system=SystemData(systemid=Tokyo_NDL, status=Cache, reserveurl=https://ndlopac.ndl.go.jp/..., libkeyList=[Libkey(name=æ±äº¬æ¬é¤¨, value=èµæ¸ãã)]))])
â»session, reserveurl ã®å¤ã¯çç¥ãã¦ãã¾ãã
lending_app, lending_book ãã¼ãã«ãæ´æ°ããã¦ãããã¨ã確èªã§ãã¾ãã
Ctrl+F2 ãæ¼ã㦠Tomcat ãåæ¢ãã¾ãã
ä¸æ¦ commit ãã¾ãã
次åã¯ããã
ä»åå®è£ ããå¦çã§ã¯ã¢ãããã¼ãããã貸åºå¸ææ¸ç±ãã¼ã¿ã«ã¯ ISBN ãéè¤ãã¦ããªããã¨ãåæã«ãªãã®ã§ã貸åºå¸ææ¸ç± CSV ãã¡ã¤ã«ã¢ãããã¼ãç»é¢ã§ã¢ãããã¼ããã CSV ãã¡ã¤ã«å ã« ISBN ãéè¤ãã¦ãããã¼ã¿ããã£ãå ´åã«ã¯ã¨ã©ã¼ã«ããå¦çã追å ãã¾ãã
ãã®å¾ã§è²¸åºç¶æ³åå¾ã¿ã¹ã¯ã®ã¡ã¼ã«éä¿¡å¦çãä½æãã¾ãã
ã¡ã¢æ¸ã
ã«ã¼ãªã«ã®èµæ¸æ¤ç´¢ WebAPIãå¼ã³åºãå¦çãæ¸ãã¦ãã¦æãã¾ãããJRebel è¶ ä¾¿å©ã§ãï¼ãã¬ã¹ãã³ã¹ãå±éããã¯ã©ã¹ã®ä½æã¯ããªã試è¡é¯èª¤ããã®ã§ãTomcat ãåèµ·åãããã¨ãªãéçºãã§ãã JRebel ãããã¨ãªãã§ã¯éçºå¹çãå ¨ç¶éãã¾ããSpring Boot ã® 1.3 ããå©ç¨ã§ãã spring-boot-devtools ã®èªåãªãã¼ãæ©è½ã JRebel 並ã¿ã§ã¯ãªãã¦ãããç¨åº¦ä½¿ããã¨ãããªããã ( JRebel ã¯è³¼å ¥ããã¨ã¡ãã£ã¨é«ããã§ããã )
@RabbitListener ã¢ããã¼ã·ã§ã³ãä»å ãããã¡ã½ããå ã§ä¾å¤ ( éãã§ãã¯ä¾å¤ã ãï¼ ) ãçºçããå ´åãRabbitMQ ã® Queue ã®ã¡ãã»ã¼ã¸ã¯åé¤ããããä»ã®å®è£ ã ã¨å»¶ã ã¨ãªã¹ãã¼ã®ã¡ã½ãããå¼ã³åºããç¶ãã¾ãããRabbitMQ ã®ãã©ã³ã¶ã¯ã·ã§ã³å¦çã®ãããªãã®ãè¡ããã¦ãããããªæ°ããã¾ãã貸åºç¶æ³åå¾ã¿ã¹ã¯ãä¸éãå®è£ ããå¾ã§ãã®è¾ºã®åä½ãã©ããªã£ã¦ããã®ãã確èªãã¦ã¿ããã¨æãã¾ãã
ã½ã¼ã¹ã³ã¼ã
DomaConfig.java
package ksbysample.webapp.lending.config; import org.apache.commons.lang3.StringUtils; import org.seasar.doma.jdbc.Config; import org.seasar.doma.jdbc.GreedyCacheSqlFileRepository; import org.seasar.doma.jdbc.NoCacheSqlFileRepository; import org.seasar.doma.jdbc.SqlFileRepository; import org.seasar.doma.jdbc.dialect.Dialect; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.jdbc.datasource.TransactionAwareDataSourceProxy; import org.springframework.stereotype.Component; import javax.sql.DataSource; @Component public class DomaConfig implements Config { private DataSource dataSource; private Dialect dialect; private SqlFileRepository sqlFileRepository; public DomaConfig() { } @SuppressWarnings("SpringJavaAutowiringInspection") @Autowired public void setDataSource(DataSource dataSource) { this.dataSource = new TransactionAwareDataSourceProxy(dataSource); } @Autowired public void setDialect(@Value("${doma.dialect}") String domaDialect) throws ClassNotFoundException, IllegalAccessException, InstantiationException { this.dialect = (Dialect) Class.forName(domaDialect).newInstance(); } @Autowired public void setSqlFileRepository(@Value("${spring.profiles.active}") String springProfilesActive) { // develop ã¢ã¼ãã®æ㯠SQL ãã¡ã¤ã«ããã£ãã·ã¥ãããªãããã«ãã if (StringUtils.equals(springProfilesActive, "develop")) { this.sqlFileRepository = new NoCacheSqlFileRepository(); } else { this.sqlFileRepository = new GreedyCacheSqlFileRepository(); } } @Override public DataSource getDataSource() { return this.dataSource; } @Override public Dialect getDialect() { return this.dialect; } @Override public SqlFileRepository getSqlFileRepository() { return this.sqlFileRepository; } }
- setDataSource ã¡ã½ããã« @SuppressWarnings("SpringJavaAutowiringInspection") ã¢ããã¼ã·ã§ã³ã追å ãã¾ããã
- Dialect Bean ãçæããããã®ã¤ã³ãã¼ã¯ã©ã¹ DomaBeanConfig ã¯ã©ã¹ãåé¤ãããã£ã¼ã«ã dialect ãã @Autowired ã¢ããã¼ã·ã§ã³ãåé¤ãã¾ããã代ããã« setDialect ã¡ã½ããã追å ãã¦ããã®ã¡ã½ããã§ãã£ã¼ã«ã dialect ã®ã¤ã³ã¹ã¿ã³ã¹ãçæããããã«ãã¦ãã¾ãã
TestDataResource.java
@Override protected void before() throws Exception { IDatabaseConnection conn = null; try { conn = new DatabaseConnection(dataSource.getConnection()); // ããã¯ã¢ãããåå¾ãã QueryDataSet partialDataSet = new QueryDataSet(conn); for (String backupTable : BACKUP_TABLES) { partialDataSet.addTable(backupTable); } ReplacementDataSet replacementDatasetBackup = new ReplacementDataSet(partialDataSet); replacementDatasetBackup.addReplacementObject("", "[null]"); backupFile = File.createTempFile(BACKUP_FILE_NAME, "xml"); try (FileOutputStream fos = new FileOutputStream(backupFile)) { FlatXmlDataSet.write(replacementDatasetBackup, fos); } // ãã¹ããã¼ã¿ã«å ¥ãæ¿ãã IDataSet dataSet = new CsvDataSet(new File(TESTDATA_DIR)); ReplacementDataSet replacementDataset = new ReplacementDataSet(dataSet); replacementDataset.addReplacementObject("[null]", null); DatabaseOperation.CLEAN_INSERT.execute(conn, replacementDataset); } finally { if (conn != null) conn.close(); } }
- å¦çã®ä¿®æ£æ¹æ³ãæ¤è¨ãã¦ãã¦ã³ã¡ã³ãã¢ã¦ããã¦æ®ãã¦ãã
DatabaseOperation.TRUNCATE_TABLE.execute(...);
ã®ï¼è¡ãåé¤ãã¾ãã
ApplicationConfig.java
package ksbysample.webapp.lending.config; import org.springframework.amqp.core.Queue; import org.springframework.amqp.rabbit.connection.ConnectionFactory; import org.springframework.amqp.rabbit.core.RabbitTemplate; import org.springframework.amqp.support.converter.Jackson2JsonMessageConverter; import org.springframework.amqp.support.converter.MessageConverter; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @Configuration public class ApplicationConfig { @Autowired private ConnectionFactory connectionFactory; @Bean public Queue inquiringStatusOfBookQueue() { return new Queue(Constant.QUEUE_NAME_INQUIRING_STATUSOFBOOK, false); } @Bean public MessageConverter messageConverter() { Jackson2JsonMessageConverter converter = new Jackson2JsonMessageConverter(); return converter; } @Bean public RabbitTemplate rabbitTemplate() { RabbitTemplate rabbitTemplate = new RabbitTemplate(this.connectionFactory); rabbitTemplate.setMessageConverter(this.messageConverter()); return rabbitTemplate; } }
- MessageConverter Bean ã追å ãã¾ãã
- RabbitTemplate Bean å
ã® rabbitTemplate.setMessageConverter(...) ã«æ¸¡ãå¼æ°ã
new Jackson2JsonMessageConverter()
âthis.messageConverter()
ã¸å¤æ´ãã¾ãã
InquiringStatusOfBookQueueService.java
package ksbysample.webapp.lending.service.queue; import ksbysample.webapp.lending.config.Constant; import org.springframework.amqp.core.Message; import org.springframework.amqp.rabbit.core.RabbitTemplate; import org.springframework.amqp.support.converter.MessageConverter; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; @Service public class InquiringStatusOfBookQueueService { @Autowired private MessageConverter converter; @Autowired private RabbitTemplate rabbitTemplate; public void sendMessage(Long lendingAppId) { InquiringStatusOfBookQueueMessage message = new InquiringStatusOfBookQueueMessage(); message.setLendingAppId(lendingAppId); rabbitTemplate.convertAndSend(Constant.QUEUE_NAME_INQUIRING_STATUSOFBOOK, message); } public InquiringStatusOfBookQueueMessage convertMessageToObject(Message message) { return (InquiringStatusOfBookQueueMessage) converter.fromMessage(message); } }
- convertMessageToObject ã¡ã½ããã追å ãã¾ãã
InquiringStatusOfBookQueueListener.java
â ãã®ï¼
package ksbysample.webapp.lending.listener.rabbitmq; import ksbysample.webapp.lending.config.Constant; import ksbysample.webapp.lending.service.queue.InquiringStatusOfBookQueueMessage; import ksbysample.webapp.lending.service.queue.InquiringStatusOfBookQueueService; import org.springframework.amqp.core.Message; import org.springframework.amqp.rabbit.annotation.RabbitListener; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; @Component public class InquiringStatusOfBookQueueListener { @Autowired private InquiringStatusOfBookQueueService inquiringStatusOfBookQueueService; @RabbitListener(queues = {Constant.QUEUE_NAME_INQUIRING_STATUSOFBOOK}) public void receiveMessage(Message message) { // åä¿¡ããã¡ãã»ã¼ã¸ã InquiringStatusOfBookQueueMessage ã¯ã©ã¹ã®ã¤ã³ã¹ã¿ã³ã¹ã«å¤æãã InquiringStatusOfBookQueueMessage convertedMessage = inquiringStatusOfBookQueueService.convertMessageToObject(message); } }
â ãã®ï¼
package ksbysample.webapp.lending.listener.rabbitmq; import ksbysample.webapp.lending.config.Constant; import ksbysample.webapp.lending.service.queue.InquiringStatusOfBookQueueMessage; import ksbysample.webapp.lending.service.queue.InquiringStatusOfBookQueueService; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.amqp.core.Message; import org.springframework.amqp.rabbit.annotation.RabbitListener; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; @Component public class InquiringStatusOfBookQueueListener { private final Logger logger = LoggerFactory.getLogger(this.getClass()); @Autowired private InquiringStatusOfBookQueueService inquiringStatusOfBookQueueService; @Autowired private InquiringStatusOfBookQueueListenerService inquiringStatusOfBookQueueListenerService; @RabbitListener(queues = {Constant.QUEUE_NAME_INQUIRING_STATUSOFBOOK}) public void receiveMessage(Message message) { // åä¿¡ããã¡ãã»ã¼ã¸ã InquiringStatusOfBookQueueMessage ã¯ã©ã¹ã®ã¤ã³ã¹ã¿ã³ã¹ã«å¤æãã InquiringStatusOfBookQueueMessage convertedMessage = inquiringStatusOfBookQueueService.convertMessageToObject(message); // ã«ã¼ãªã«ã®èµæ¸æ¤ç´¢API ãå¼ã³åºãã¦è²¸åºç¶æ³ãåå¾ããlending_app, lending_book ãã¼ãã«ãæ´æ°ãã inquiringStatusOfBookQueueListenerService.callCheckApiAndupdateLendingData(convertedMessage); // TODO ãã¼ã¿ãç»é²ããã¦ã¼ã¶ã¸ã¡ã¼ã«ãéä¿¡ãã } }
private InquiringStatusOfBookQueueListenerService inquiringStatusOfBookQueueListenerService;
ã追å ãã¾ãã- receiveMessage ã¡ã½ããå
ã«
inquiringStatusOfBookQueueListenerService.callCheckApiAndupdateLendingData(convertedMessage);
ã追å ãã¾ãã
CheckApiResponse.java
package ksbysample.webapp.lending.service.calilapi; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import lombok.Data; import lombok.ToString; import javax.xml.bind.annotation.XmlElement; import javax.xml.bind.annotation.XmlRootElement; import java.util.ArrayList; import java.util.List; @XmlRootElement(name = "result") @JsonIgnoreProperties(ignoreUnknown = true) @Data @ToString public class CheckApiResponse { @XmlElement(name = "session") private String session; @XmlElement(name = "continue") private String continueValue; @XmlElement(name = "books") private List<Book> bookList = new ArrayList<>(); }
Book.java
package ksbysample.webapp.lending.service.calilapi; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import lombok.Data; import lombok.ToString; import javax.xml.bind.annotation.XmlAttribute; import javax.xml.bind.annotation.XmlElement; @JsonIgnoreProperties(ignoreUnknown = true) @Data @ToString public class Book { @XmlAttribute(name = "isbn") private String isbn; @XmlAttribute(name = "calilurl") private String calilurl; @XmlElement(name = "system") private SystemData system; }
SystemData.java
package ksbysample.webapp.lending.service.calilapi; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import lombok.Data; import lombok.ToString; import javax.xml.bind.annotation.XmlAttribute; import javax.xml.bind.annotation.XmlElement; import java.util.ArrayList; import java.util.List; @JsonIgnoreProperties(ignoreUnknown = true) @Data @ToString public class SystemData { @XmlAttribute(name = "systemid") private String systemid; @XmlElement(name = "status") private String status; @XmlElement(name = "reserveurl") private String reserveurl; @XmlElement(name = "libkeys") private List<Libkey> libkeyList = new ArrayList<>(); }
Libkey.java
package ksbysample.webapp.lending.service.calilapi; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import lombok.Data; import lombok.ToString; import javax.xml.bind.annotation.XmlAttribute; import javax.xml.bind.annotation.XmlValue; @JsonIgnoreProperties(ignoreUnknown = true) @Data @ToString public class Libkey { @XmlAttribute(name = "name") private String name; @XmlValue private String value; }
- libkey ã¯
<libkey name="æ±äº¬æ¬é¤¨">èµæ¸ãã</libkey>
ã®ããã« Element ç¡ãã§å¤ãåºåããã¦ããã®ã§ã@XmlValue ã使ç¨ãã¾ãã
CalilApiService.java
package ksbysample.webapp.lending.service.calilapi; import com.fasterxml.jackson.dataformat.xml.XmlMapper; import com.google.common.base.Joiner; import org.simpleframework.xml.Serializer; import org.simpleframework.xml.core.Persister; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.PropertySource; import org.springframework.http.MediaType; import org.springframework.http.ResponseEntity; import org.springframework.http.client.ClientHttpRequestFactory; import org.springframework.http.client.SimpleClientHttpRequestFactory; import org.springframework.http.converter.HttpMessageConverter; import org.springframework.http.converter.xml.MappingJackson2XmlHttpMessageConverter; import org.springframework.stereotype.Service; import org.springframework.util.ClassUtils; import org.springframework.web.client.RestTemplate; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; @Service @PropertySource("classpath:calilapi.properties") public class CalilApiService { private final Logger logger = LoggerFactory.getLogger(this.getClass()); private int CONNECT_TIMEOUT = 5000; private int READ_TIMEOUT = 5000; private final int RETRY_MAX_CNT = 5; private final long RETRY_SLEEP_MILLS = 3000; private final String URL_CALILAPI_LIBRALY = "http://api.calil.jp/library?appkey={appkey}&pref={pref}"; private final String URL_CALILAPI_CHECK = "http://api.calil.jp/check?appkey={appkey}&systemid={systemid}&isbn={isbn}&format=xml"; private final String URL_CALILAPI_CHECK_FOR_RETRY = "http://api.calil.jp/check?session={session}&format=xml"; @Value("${calil.apikey}") private String calilApiKey; public Libraries getLibraryList(String pref) throws Exception { // å³æ¸é¤¨ãã¼ã¿ãã¼ã¹APIãå¼ã³åºã㦠XMLã¬ã¹ãã³ã¹ãåä¿¡ãã RestTemplate restTemplate = new RestTemplate(getClientHttpRequestFactory()); ResponseEntity<String> response = restTemplate.getForEntity(URL_CALILAPI_LIBRALY, String.class, this.calilApiKey, pref); // åä¿¡ãã XMLã¬ã¹ãã³ã¹ã Javaãªãã¸ã§ã¯ãã«å¤æãã Serializer serializer = new Persister(); Libraries libraries = serializer.read(Libraries.class, response.getBody()); return libraries; } public LibrariesForJackson2Xml getLibraryListByJackson2Xml(String pref) throws Exception { // å³æ¸é¤¨ãã¼ã¿ãã¼ã¹APIãå¼ã³åºã㦠XMLã¬ã¹ãã³ã¹ãåä¿¡ãã RestTemplate restTemplate = new RestTemplate(getClientHttpRequestFactory()); restTemplate.setMessageConverters(getMessageConvertersforJackson2XML()); ResponseEntity<LibrariesForJackson2Xml> response = restTemplate.getForEntity(URL_CALILAPI_LIBRALY, LibrariesForJackson2Xml.class, this.calilApiKey, pref); return response.getBody(); } public List<Book> check(String systemid, List<String> isbnList) { RestTemplate restTemplate = new RestTemplate(getClientHttpRequestFactory()); restTemplate.setMessageConverters(getMessageConvertersforJackson2XML()); Map<String, String> vars = new HashMap<>(); vars.put("appkey", this.calilApiKey); vars.put("systemid", systemid); vars.put("isbn", Joiner.on(",").join(isbnList)); ResponseEntity<CheckApiResponse> response = null; String url = URL_CALILAPI_CHECK; for (int retry = 0; retry < RETRY_MAX_CNT; retry++) { // èµæ¸æ¤ç´¢APIãå¼ã³åºãã¦èµæ¸ã®æç¡ã¨è²¸åºç¶æ³ãåå¾ãã response = restTemplate.getForEntity(url, CheckApiResponse.class, vars); logger.info("ã«ã¼ãªã«ã®èµæ¸æ¤ç´¢API ãå¼ã³åºããã¬ã¹ãã³ã¹ãåå¾ãã¾ããã{}", response.getBody().toString()); if (response.getBody().getContinueValue() == 0) { break; } // continue ã®å¤ã 0 ã§ãªãå ´åã«ã¯ï¼ç§ä»¥ä¸å¾ æ©ããå¾ãURLãã©ã¡ã¼ã¿ã session ã«å¤æ´ãã¦å度ãªã¯ã¨ã¹ããéä¿¡ãã try { Thread.sleep(RETRY_SLEEP_MILLS); } catch (InterruptedException e) { logger.warn("ã«ã¼ãªã«ã®èµæ¸æ¤ç´¢APIã®sleepä¸ã«InterruptedExceptionãçºçãã¾ããããå¦çã¯ç¶ç¶ãã¾ãã", e); } url = URL_CALILAPI_CHECK_FOR_RETRY; vars.clear(); vars.put("session", response.getBody().getSession()); } return response.getBody().getBookList(); } private ClientHttpRequestFactory getClientHttpRequestFactory() { // æ¥ç¶ã¿ã¤ã ã¢ã¦ããåä¿¡ã¿ã¤ã ã¢ã¦ãã 5ç§ã«è¨å®ãã SimpleClientHttpRequestFactory factory = new SimpleClientHttpRequestFactory(); factory.setConnectTimeout(CONNECT_TIMEOUT); factory.setReadTimeout(READ_TIMEOUT); return factory; } private List<HttpMessageConverter<?>> getMessageConvertersforJackson2XML() { // build.gralde ã« compile("com.fasterxml.jackson.dataformat:jackson-dataformat-xml:...") ãè¨è¿°ã㦠jackson-dataformat-xml // ã使ç¨ã§ããããã«ãªã£ã¦ããªãå ´åã«ã¯ã¨ã©ã¼ã«ãã assert(ClassUtils.isPresent("com.fasterxml.jackson.dataformat.xml.XmlMapper", RestTemplate.class.getClassLoader())); MappingJackson2XmlHttpMessageConverter mappingJackson2XmlHttpMessageConverter = new MappingJackson2XmlHttpMessageConverter(); // findAndRegisterModules ã¡ã½ãããå¼ã³åºã㦠jackson-dataformat-xml ãæ©è½ããããã«ãã mappingJackson2XmlHttpMessageConverter.setObjectMapper(new XmlMapper().findAndRegisterModules()); List<MediaType> mediaTypes = new ArrayList<>(); mediaTypes.add(MediaType.APPLICATION_XML); mediaTypes.add(MediaType.TEXT_XML); mappingJackson2XmlHttpMessageConverter.setSupportedMediaTypes(mediaTypes); List<HttpMessageConverter<?>> messageConverters = new ArrayList<>(); messageConverters.add(mappingJackson2XmlHttpMessageConverter); return messageConverters; } }
private final Logger logger = LoggerFactory.getLogger(this.getClass());
ã追å ãã¾ãã- 以ä¸ã®å®æ°ã追å ãã¾ãã
- RETRY_MAX_CNT
- RETRY_SLEEP_MILLS
- URL_CALILAPI_CHECK
- URL_CALILAPI_CHECK_FOR_RETRY
- check ã¡ã½ããã追å ãã¾ãã
LendingAppDao.java
package ksbysample.webapp.lending.dao; import ksbysample.webapp.lending.entity.LendingApp; import ksbysample.webapp.lending.util.doma.ComponentAndAutowiredDomaConfig; import org.seasar.doma.Dao; import org.seasar.doma.Delete; import org.seasar.doma.Insert; import org.seasar.doma.Select; import org.seasar.doma.Update; import org.seasar.doma.jdbc.SelectOptions; /** */ @Dao @ComponentAndAutowiredDomaConfig public interface LendingAppDao { /** * @param lendingAppId * @return the LendingApp entity */ @Select LendingApp selectById(Long lendingAppId); @Select LendingApp selectById(Long lendingAppId, SelectOptions options); /** * @param entity * @return affected rows */ @Insert int insert(LendingApp entity); /** * @param entity * @return affected rows */ @Update int update(LendingApp entity); /** * @param entity * @return affected rows */ @Delete int delete(LendingApp entity); }
LendingApp selectById(Long lendingAppId, SelectOptions options);
ã追å ãã¾ãã
LendingBookDao.java
package ksbysample.webapp.lending.dao; import ksbysample.webapp.lending.entity.LendingBook; import ksbysample.webapp.lending.util.doma.ComponentAndAutowiredDomaConfig; import org.seasar.doma.Dao; import org.seasar.doma.Delete; import org.seasar.doma.Insert; import org.seasar.doma.Select; import org.seasar.doma.Update; import org.seasar.doma.jdbc.SelectOptions; import java.util.List; /** */ @Dao @ComponentAndAutowiredDomaConfig public interface LendingBookDao { /** * @param lendingBookId * @return the LendingBook entity */ @Select LendingBook selectById(Long lendingBookId); @Select List<LendingBook> selectByLendingAppId(Long lendingAppId); @Select List<LendingBook> selectByLendingAppId(Long lendingAppId, SelectOptions options); /** * @param entity * @return affected rows */ @Insert int insert(LendingBook entity); /** * @param entity * @return affected rows */ @Update int update(LendingBook entity); @Update(include = {"lendingState"}) int updateLendingState(LendingBook entity); /** * @param entity * @return affected rows */ @Delete int delete(LendingBook entity); }
List<LendingBook> selectByLendingAppId(Long lendingAppId, SelectOptions options);
ã追å ãã¾ãã- updateLendingState ã¡ã½ããã追å ãã¾ãã
LendingAppStatusValues.java
package ksbysample.webapp.lending.values; import lombok.Getter; import org.apache.commons.lang3.StringUtils; @Getter public enum LendingAppStatusValues { TENPORARY_SAVE("1", "ä¸æä¿å") , UNAPPLIED("2", "æªç³è«") , PENDING("3", "ç³è«ä¸") , APPLOVED("4", "æ¿èªæ¸");
, UNAPPLIED("2", "æªç³è«")
ã追å ãã¾ãã
InquiringStatusOfBookQueueListenerService.java
package ksbysample.webapp.lending.listener.rabbitmq; import ksbysample.webapp.lending.dao.LendingAppDao; import ksbysample.webapp.lending.dao.LendingBookDao; import ksbysample.webapp.lending.dao.LibraryForsearchDao; import ksbysample.webapp.lending.entity.LendingApp; import ksbysample.webapp.lending.entity.LendingBook; import ksbysample.webapp.lending.entity.LibraryForsearch; import ksbysample.webapp.lending.service.calilapi.Book; import ksbysample.webapp.lending.service.calilapi.CalilApiService; import ksbysample.webapp.lending.service.queue.InquiringStatusOfBookQueueMessage; import ksbysample.webapp.lending.values.LendingAppStatusValues; import org.apache.commons.lang3.StringUtils; import org.seasar.doma.jdbc.SelectOptions; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import java.util.List; import java.util.stream.Collectors; @Service public class InquiringStatusOfBookQueueListenerService { private final Logger logger = LoggerFactory.getLogger(this.getClass()); @Autowired private CalilApiService calilApiService; @Autowired private LibraryForsearchDao libraryForsearchDao; @Autowired private LendingAppDao lendingAppDao; @Autowired private LendingBookDao lendingBookDao; public void callCheckApiAndupdateLendingData(InquiringStatusOfBookQueueMessage convertedMessage) { // é¸æä¸ã®å³æ¸é¤¨ãåå¾ãã LibraryForsearch libraryForsearch = libraryForsearchDao.selectSelectedLibrary(); // æ´æ°å¯¾è±¡ã® lending_app ãã¼ãã«ã®ãã¼ã¿ãåå¾ãã LendingApp lendingApp = lendingAppDao.selectById(convertedMessage.getLendingAppId(), SelectOptions.get().forUpdate()); if (lendingApp == null) { logger.error("lending_app ãã¼ãã«ã«å¯¾è±¡ã®ãã¼ã¿ãããã¾ããã§ãã ( lending_app_id = {} )ã", convertedMessage.getLendingAppId()); return; } // lending_book ãã¼ãã«ãã調æ»å¯¾è±¡ã® ISBN ä¸è¦§ãåå¾ãã List<LendingBook> lendingBookList = lendingBookDao.selectByLendingAppId(convertedMessage.getLendingAppId(), SelectOptions.get().forUpdate()); if (lendingBookList == null) { logger.error("lending_book ãã¼ãã«ã«å¯¾è±¡ã®ãã¼ã¿ãããã¾ããã§ãã ( lending_app_id = {} )ã", convertedMessage.getLendingAppId()); return; } List<String> isbnList = lendingBookList.stream() .map(LendingBook::getIsbn) .collect(Collectors.toList()); // ã«ã¼ãªã«ã®èµæ¸æ¤ç´¢ WebAPI ãå¼ã³åºãã¦è²¸åºç¶æ³ãåå¾ãã List<Book> bookList = calilApiService.check(libraryForsearch.getSystemid(), isbnList); // lending_book ãã¼ãã«ã«åå¾ãã貸åºç¶æ³ãåæ ããlending_app ãã¼ãã«ã® status ã 2(æªç³è«) ã«æ´æ°ãã copyLendingStateFromBookListToEntityList(bookList, lendingBookList); updateLendingData(lendingBookList, lendingApp); } private void copyLendingStateFromBookListToEntityList(List<Book> bookList, List<LendingBook> lendingBookList) { for (LendingBook lendingBook : lendingBookList) { for (Book book : bookList) { if (StringUtils.equals(lendingBook.getIsbn(), book.getIsbn())) { lendingBook.setLendingState(book.getFirstLibkeyValue()); break; } } } } private void updateLendingData(List<LendingBook> lendingBookList, LendingApp lendingApp) { // lending_book ãã¼ãã«ã«åå¾ãã貸åºç¶æ³ãåæ ãã for (LendingBook lendingBook : lendingBookList) { lendingBookDao.updateLendingState(lendingBook); } // lending_app ãã¼ãã«ã® status ã 2(æªç³è«) ã«æ´æ°ãã lendingApp.setStatus(LendingAppStatusValues.UNAPPLIED.getValue()); lendingAppDao.update(lendingApp); } }
å±¥æ´
2015/10/26
åççºè¡ã