/* * 著作権表記 TODO 要否をお客様に確認 */ package com.pgf.mqspring.service.impl; import java.text.MessageFormat; import java.util.Arrays; import javax.jms.BytesMessage; import javax.jms.JMSException; import javax.xml.bind.DatatypeConverter; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.HttpStatus; import org.springframework.jms.core.JmsTemplate; import org.springframework.stereotype.Service; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; import com.pgf.mqspring.component.CharacterCodeConverterComponent; import com.pgf.mqspring.component.MqSpringMessageSourceComponent; import com.pgf.mqspring.constant.MqSpringConst; import com.pgf.mqspring.constant.MqSpringMessageId; import com.pgf.mqspring.exception.MqSpringException; import com.pgf.mqspring.model.ReplyResponseModel; import com.pgf.mqspring.model.SendMapVectorRequestModel; import com.pgf.mqspring.service.MqReceiveService; /** * MQ受信用サービス実装クラス *

* 指定されたキューからメッセージを受信する。 */ @Service public class MqReceiveServiceImpl implements MqReceiveService { /** JMSテンプレート */ private JmsTemplate jmsTemplate = null; /** キュー */ private String queue = MqSpringConst.BLANK; /** 文字コード変換クラス */ @Autowired private CharacterCodeConverterComponent characterCodeConverter; /** MqSpringメッセージソースクラス */ @Autowired private MqSpringMessageSourceComponent messageSource; /** オブジェクトマッパー */ private ObjectMapper mapper = new ObjectMapper(); /** ロガー */ Logger logger = LogManager.getLogger(); /** メッセージセレクターフォーマット */ private static final String MESSAGE_SELECTOR_FORMAT = "JMSCorrelationID = ''{0}''"; /** * MQ受信用サービス実装クラスのコンストラクタ * * @param template Jmsテンプレート */ public MqReceiveServiceImpl(JmsTemplate template) { this.jmsTemplate = template; } /** * メッセージ受信処理 *

* 受信用キューから条件に合致したメッセージを取得する。以下引数
*  ・キュー *  ・JMS相関ID * 取得したメッセージがnullの場合
*  エラーログを出力する。以下引数
*   ・メッセージID:SYS7008E
*  MqSpringExceptionの例外をスローする。以下引数
*   ・メッセージID:SYS7008E
*   ・HttpStatus:REQUEST_TIMEOUT
* バイト配列の受信電文をレスポンス用モデルクラスに格納する。
* 受信メッセージの文字コードをEBCDICからSJISに変換する。
* レスポンス用モデルクラスをJSON形式に変換して返却する。
* メッセージ受信処理でMqSpringExceptionが発生した場合
*  キャッチした内容をそのままスローする。
* メッセージ受信処理でJMS例外が発生した場合
*  エラーログを出力する。以下引数
*   ・メッセージID:SYS7006E
*   ・発生した例外:JMSException
*  MqSpringExceptionの例外をスローする。以下引数
*   ・メッセージID:SYS7006E
*   ・HttpStatus:REQUEST_TIMEOUT
* JSON形式に変換する際に例外が発生した場合
*  エラーログを出力する。以下引数
*   ・メッセージID:SYS7080E
*   ・発生した例外:JsonProcessingException
*  MqSpringExceptionの例外をスローする。以下引数
*   ・メッセージID:SYS7080E
*   ・HttpStatus:INTERNAL_SERVER_ERROR
* メッセージ受信処理で例外が発生した場合
*  エラーログを出力する。以下引数
*   ・メッセージID:SYS7072E
*   ・発生した例外:Exception
*  MqSpringExceptionの例外をスローする。以下引数
*   ・メッセージID:SYS7072E
*   ・HttpStatus:INTERNAL_SERVER_ERROR
* * @param id メッセージID * @return 返信レスポンス用モデルクラスのJSONデータ */ public String receiveMessage(String id) { try { logger.info("Message ID for Receive =" + id); BytesMessage bm = (BytesMessage) jmsTemplate.receiveSelected(queue, MessageFormat.format(MESSAGE_SELECTOR_FORMAT, id)); if (bm == null) { logger.error(messageSource.getMessage(MqSpringMessageId.SYS7008E)); throw new MqSpringException(MqSpringMessageId.SYS7008E, HttpStatus.REQUEST_TIMEOUT); } byte[] bytes = bm.getBody(byte[].class); logger.info("MQGET >>"); logger.info(DatatypeConverter.printHexBinary(bytes)); ReplyResponseModel response = editReplyData(bytes); // MQMD response.getMqmd().setCorrelId(bm.getJMSCorrelationID()); //Json変換 String json = MqSpringConst.BLANK; json = mapper.writeValueAsString(response); return json; } catch (MqSpringException e) { throw e; } catch (JMSException ex) { System.out.println(getStackTrace(ex)); logger.error(messageSource.getMessage(MqSpringMessageId.SYS7006E), ex); throw new MqSpringException(MqSpringMessageId.SYS7006E, HttpStatus.REQUEST_TIMEOUT); } catch (JsonProcessingException e) { System.out.println(getStackTrace(e)); logger.error(messageSource.getMessage(MqSpringMessageId.SYS7080E), e); throw new MqSpringException(MqSpringMessageId.SYS7080E, HttpStatus.INTERNAL_SERVER_ERROR); } catch (Exception ex) { System.out.println(getStackTrace(ex)); logger.error(messageSource.getMessage(MqSpringMessageId.SYS7072E), ex); throw new MqSpringException(MqSpringMessageId.SYS7072E, HttpStatus.INTERNAL_SERVER_ERROR); } } /** * 受信メッセージ編集処理 *

* 下記により各項目ごとにコード変換処理を行い、レスポンス用モデルクラスに設定する。
*  ・16進文字列復号処理{@link characterCodeConverter#decodeHexStringData(byte[])}
*  ・EBCDIC復号処理{@link characterCodeConverter#decodeEbcdic(byte[])}
* 引数のバイト配列が184より大きい場合 *  Vector内の各項目ごとにコード変換処理を行い、レスポンス用モデルクラスに設定する。 * 引数のバイト配列が268より大きい場合 *  Adsデータのコード変換処理を行い、レスポンス用モデルクラスに設定する。 * * @param bytes バイト配列 * @return 返信レスポンス用モデルクラス */ public ReplyResponseModel editReplyData(byte[] bytes) { ReplyResponseModel response = new ReplyResponseModel(); // MQCIH response.getMqcih().setStrucId(characterCodeConverter.decodeEbcdic(Arrays.copyOfRange(bytes, 0, 4)).trim()); response.getMqcih().setVersion(String.valueOf( Long.parseLong(characterCodeConverter.decodeHexStringData(Arrays.copyOfRange(bytes, 4, 8)), 16))); response.getMqcih().setStrucLength(String.valueOf( Long.parseLong(characterCodeConverter.decodeHexStringData(Arrays.copyOfRange(bytes, 8, 12)), 16))); response.getMqcih().setFormat(characterCodeConverter.decodeEbcdic(Arrays.copyOfRange(bytes, 20, 28))); response.getMqcih().setFlags(String.valueOf( Long.parseLong(characterCodeConverter.decodeHexStringData(Arrays.copyOfRange(bytes, 28, 32)), 16))); response.getMqcih().setReturnCode(String.valueOf( Long.parseLong(characterCodeConverter.decodeHexStringData(Arrays.copyOfRange(bytes, 32, 36)), 16))); response.getMqcih().setCompCode(String.valueOf( Long.parseLong(characterCodeConverter.decodeHexStringData(Arrays.copyOfRange(bytes, 36, 40)), 16))); response.getMqcih().setReason(String.valueOf( Long.parseLong(characterCodeConverter.decodeHexStringData(Arrays.copyOfRange(bytes, 40, 44)), 16))); response.getMqcih().setUowControl(String.valueOf( Long.parseLong(characterCodeConverter.decodeHexStringData(Arrays.copyOfRange(bytes, 44, 48)), 16))); response.getMqcih().setGetWaitInterval(String.valueOf( Long.parseLong(characterCodeConverter.decodeHexStringData(Arrays.copyOfRange(bytes, 48, 52)), 16))); response.getMqcih().setLinkType(String.valueOf( Long.parseLong(characterCodeConverter.decodeHexStringData(Arrays.copyOfRange(bytes, 52, 56)), 16))); response.getMqcih().setOutputDataLength(String.valueOf( Long.parseLong(characterCodeConverter.decodeHexStringData(Arrays.copyOfRange(bytes, 56, 60)), 16))); response.getMqcih().setFacilityKeepTime(String.valueOf( Long.parseLong(characterCodeConverter.decodeHexStringData(Arrays.copyOfRange(bytes, 60, 64)), 16))); response.getMqcih().setAdsDescriptor(String.valueOf( Long.parseLong(characterCodeConverter.decodeHexStringData(Arrays.copyOfRange(bytes, 64, 68)), 16))); response.getMqcih().setConversationalTask(String.valueOf( Long.parseLong(characterCodeConverter.decodeHexStringData(Arrays.copyOfRange(bytes, 68, 72)), 16))); response.getMqcih().setTaskEndStatus(String.valueOf( Long.parseLong(characterCodeConverter.decodeHexStringData(Arrays.copyOfRange(bytes, 72, 76)), 16))); response.getMqcih().setFacility(characterCodeConverter.decodeHexStringData(Arrays.copyOfRange(bytes, 76, 84))); response.getMqcih().setFunction(String.valueOf( Long.parseLong(characterCodeConverter.decodeHexStringData(Arrays.copyOfRange(bytes, 84, 88)), 16))); response.getMqcih().setAbendCode(characterCodeConverter.decodeEbcdic(Arrays.copyOfRange(bytes, 88, 92)).trim()); response.getMqcih().setAutherticator(characterCodeConverter.decodeEbcdic(Arrays.copyOfRange(bytes, 92, 100))); response.getMqcih() .setReplyToFormat(characterCodeConverter.decodeEbcdic(Arrays.copyOfRange(bytes, 108, 116)).trim()); String transactionId = characterCodeConverter.decodeEbcdic(Arrays.copyOfRange(bytes, 124, 128)); response.getMqcih().setTransactionId(transactionId); response.getMqcih() .setFacilityLike(characterCodeConverter.decodeEbcdic(Arrays.copyOfRange(bytes, 128, 132)).trim()); response.getMqcih() .setAttentionId(characterCodeConverter.decodeEbcdic(Arrays.copyOfRange(bytes, 132, 136)).trim()); response.getMqcih() .setStartCode(characterCodeConverter.decodeEbcdic(Arrays.copyOfRange(bytes, 136, 140)).trim()); response.getMqcih() .setCancelCode(characterCodeConverter.decodeEbcdic(Arrays.copyOfRange(bytes, 140, 144)).trim()); response.getMqcih() .setNextTransactionCode(characterCodeConverter.decodeEbcdic(Arrays.copyOfRange(bytes, 144, 148))); response.getMqcih().setCursorPositon(String.valueOf( Long.parseLong(characterCodeConverter.decodeHexStringData(Arrays.copyOfRange(bytes, 164, 168)), 16))); response.getMqcih().setErrorOffset(String.valueOf( Long.parseLong(characterCodeConverter.decodeHexStringData(Arrays.copyOfRange(bytes, 168, 172)), 16))); // Vector if (bytes.length > 184) { SendMapVectorRequestModel sendMapVectorModel = new SendMapVectorRequestModel(); sendMapVectorModel .setVectorDescriptor(characterCodeConverter.decodeEbcdic(Arrays.copyOfRange(bytes, 184, 188))); sendMapVectorModel.setVectorType(characterCodeConverter.decodeEbcdic(Arrays.copyOfRange(bytes, 188, 189))); sendMapVectorModel.setVectorVersion(String.valueOf(Long .parseLong(characterCodeConverter.decodeHexStringData(Arrays.copyOfRange(bytes, 189, 196)), 16))); sendMapVectorModel .setScEraseIndic(characterCodeConverter.decodeEbcdic(Arrays.copyOfRange(bytes, 196, 200)).trim()); sendMapVectorModel.setScEraseaupIndic( characterCodeConverter.decodeEbcdic(Arrays.copyOfRange(bytes, 200, 204)).trim()); sendMapVectorModel .setScFreekbIndic(characterCodeConverter.decodeEbcdic(Arrays.copyOfRange(bytes, 204, 208)).trim()); sendMapVectorModel .setScAlarmIndic(characterCodeConverter.decodeEbcdic(Arrays.copyOfRange(bytes, 208, 212)).trim()); sendMapVectorModel .setScFrsetIndic(characterCodeConverter.decodeEbcdic(Arrays.copyOfRange(bytes, 212, 216)).trim()); sendMapVectorModel .setScLastIndic(characterCodeConverter.decodeEbcdic(Arrays.copyOfRange(bytes, 216, 220)).trim()); sendMapVectorModel .setScWaitIndic(characterCodeConverter.decodeEbcdic(Arrays.copyOfRange(bytes, 220, 224)).trim()); sendMapVectorModel.setScCursor(characterCodeConverter .decodeHexStringData(Arrays.copyOfRange(bytes, 224, 228)).replaceAll("FFFFFFFF", "-1")); sendMapVectorModel .setScMsrData(characterCodeConverter.decodeHexStringData(Arrays.copyOfRange(bytes, 228, 232))); sendMapVectorModel .setSmMapset(characterCodeConverter.decodeEbcdic(Arrays.copyOfRange(bytes, 232, 240)).trim()); sendMapVectorModel .setSmMap(characterCodeConverter.decodeEbcdic(Arrays.copyOfRange(bytes, 240, 248)).trim()); sendMapVectorModel .setSmDataIndic(characterCodeConverter.decodeEbcdic(Arrays.copyOfRange(bytes, 248, 252)).trim()); sendMapVectorModel.setSmDataLen(String.valueOf(Long .parseLong(characterCodeConverter.decodeHexStringData(Arrays.copyOfRange(bytes, 252, 256)), 16))); sendMapVectorModel.setSmDataOffset(String.valueOf(Long .parseLong(characterCodeConverter.decodeHexStringData(Arrays.copyOfRange(bytes, 256, 260)), 16))); sendMapVectorModel.setSmAdsdLen(String.valueOf(Long .parseLong(characterCodeConverter.decodeHexStringData(Arrays.copyOfRange(bytes, 260, 264)), 16))); sendMapVectorModel.setSmAdsdOffset(String.valueOf(Long .parseLong(characterCodeConverter.decodeHexStringData(Arrays.copyOfRange(bytes, 264, 268)), 16))); response.getReceiveMessage().setSendMapVector(sendMapVectorModel); } // Ads Data if (bytes.length > 268) { response.getReceiveMessage() .setAds(characterCodeConverter .decodeAdsData(transactionId, Arrays.copyOfRange(bytes, 268, bytes.length)) .replaceAll("\\u0000", "")); } return response; } /** * キュー取得 *

* キューを返却する * * @return キュー */ public String getQueue() { return queue; } /** * キュー設定 *

* キューを設定する * * @param que キュー * @return 無し */ public void setQueue(String que) { queue = que; } private static String getStackTrace(Exception e) { StackTraceElement[] list = e.getStackTrace(); StringBuilder b = new StringBuilder(); b.append(e.getClass()).append(":").append(e.getMessage()).append("\n"); for( StackTraceElement s : list ) { b.append(s.toString()).append("\n"); } return b.toString(); } }