From c2ead22583f0be49222d2da06a8688e5095bbbcf Mon Sep 17 00:00:00 2001 From: jaewohong Date: Wed, 19 Nov 2025 15:59:34 +0900 Subject: [PATCH 001/159] =?UTF-8?q?=EA=B0=9C=EB=B0=9C=EC=84=9C=EB=B2=84?= =?UTF-8?q?=EC=97=90=20push=EC=9C=84=ED=95=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- libs/kjb-safedb.jar | Bin 0 -> 12565 bytes .../impl/HttpClient5AdapterServiceRest.java | 342 +++++++++++++++--- .../http/dynamic/HttpAdapterServiceKey.java | 3 + ...entAccessTokenServiceWithBase64Header.java | 3 +- .../eactive/eai/common/logger/EAILogDAO.java | 128 ++++++- .../eactive/eai/common/util/JMSSender.java | 1 + .../inbound/processor/RequestProcessor.java | 14 +- .../com/eactive/eai/outbound/RESTProcess.java | 1 + 8 files changed, 429 insertions(+), 63 deletions(-) create mode 100644 libs/kjb-safedb.jar diff --git a/libs/kjb-safedb.jar b/libs/kjb-safedb.jar new file mode 100644 index 0000000000000000000000000000000000000000..884cbf47bbb0022553f9f9fc7e05df4db65bbab8 GIT binary patch literal 12565 zcmb7q1yEdTwl(g-8<*hj5)v%9yL)iA;F{p>1b26LcXxMd+=DwmsXH@wZr=R&&D&Mo zd|kEI+RZtAc5PX*65tT%ARsU>Af@)28X#{5_UrAE#G#D)iSB9Jv-ssMEQYBb|vj#mF?sGbjwMb+c@`Gn_D{X-FUJ!xJe(c z)`E|*0Twf=bOJpq@j*`kJR}DL&>Kykp2K!BXuLr-d^|1#IUOy1eAroego^?Q&)h}{ zlwfY71=2{n&-#gT>3B=rC55C9(~Gyi7c3vRYYMdvTwS-{6mmC*YzvDw&~(^Jf@gEq z7WM4+JKHj>d~8~H=4Nv04pQ;$xJ|wD3MGUKA`H4Ggs;IAI-`(&n(<3^R&w_w2gae5 zH}0>FYu!P5QUO(%J?SzT^F&A+I2}l~q~tJd~Xx|_~ftyi0Q(~@4PM(^{x&bquc#u9Or?bZCn5(vB6}B1O(HR5{ z#jLF*ba+_0Sk|oFgxg4rc?33$n*I|^{-r?dSs*$CGjtX#ti~sShYA%10V8|GOEXN# zvxzV5A2QRXyPnq&9YilRgdxHC6yCjaC?ttP3+2Wxmx#1{Aw4eEa)uaA{0J=O1d?P9 z`WiuWq2d_@=WIn1NFeqHv6duJ7b44-)xZbcS4&VupU=Doec6=MYBQm(`#xzEWT`^3 z1lPP?n%uu->w!45%O!h3O;>+=TNKpevYH{h7+!OqkgT9?6k(|$7>gzA0=`gKt2XlP zyA^i=!aKZBA$vq|>U;?a(wV?HBf9z_4m#imNo>@VM}8*GLoGgT zQ{S5K0*=CqdyYkFMJf~U@;P7xj5Ta>9Ka2gYuV}8Vr{m{Z9HaKzICP2+jeEQRZkqb z@9g|5_r;K?YNMfsO(Ysa)rJq|N4X^T#|yi~{qT>^XTJpv7;Ungcrej-8mD*R&qI zG66$Qzb%0P2Tqv547-j?&6|fUMIzk0^-Ew|*%zp@fxA@ib)Xh(^DFec_hu$S$kATv zC98{3xt7P>g<_sYzb$_sA$m&yFZEr_`H4qM_68LfT_%}1L$5KzdP=M9PNzgUSA+ZP z<;LlAY#DTU+fHKZ^~!M=rg6EJtMlmA;do=*^i-Xpu({QZ>^bO5)_Y$xxUQ}?JTCW& zp!@H)N`gl^071y**-P9AGN6$?N6hAsWB0^6nI39%@>*A@nV#?8ugXH(sqQ#mq70kz zzsbTgna=PeZ8k19yST84bv2P)AXm!>vUup{iFOFpDp$FMsxinU8GdvObf+}qzJ(~E z_#Eg`WHp)7Qn7{^BuLSzf;%u6-r`vLQ9;>J&3U$@iB@)oK`VYYrV3d*ShdqEdE9zd zh)=-!ToHGcL8+^{Zi2yyb@D}0K8y@3s=>;{lZ{W0`Vz%XJ(jqY1V=@GA3RrG)?htVZ5W|bgH83At{$FA|bH(Bn0zTD40^8Ej|VDQvt3!R2=dGo=!3|+oQfa zn(R;SdIm0c-ZL*>3b|0TDA4rc}o!eVXse$9Kl*&A#1Y4NZruGrS;z6cgKi5-6Hd}NRhL=4ijHh%RRB_1u9_U`Lh5s2XAUc! z{?z>t1m#~_KxK&XsN6b&>b0nx;ELJY^^OD$umN zh&CSF#*jtb1bbY{vEC#!RHRhn)io zq{etpeTa*b?8|Va3)B|*p%0hbSNi#*fuBF)gg>)?KOW<$Sa+dlcVS1q1qZ;C1K?Yo zUN_uuMC?sICEIWNEMNx>8Xz3 z<&qHVEv<$fB|hHS+iglh43|IJKO&doCF%NBcxNKoF9JF40uCgZHR|uTo%+^AYzsbk zi5wUY&EbTQ7J6qQJ7reF%qry-_j>5n_guGke%Mbf~6x&e%)xeGS- z0p$s8*aHD-N`s*&CQ=e|R2lITO{lWU6mansKZOMkOk69w_l9>`qvck%Ocy$Tt?E$l z&nD18K|p-oYC!tGuS_J&^c3F8o4*t%a>LSKOz7O0QPe{M+qei8$9+A1WsFUe1-2OU zHq!@+%;0q~V=#B-^iLqXLkmGd-~w5dV$*IiW57C(S7#4!8(;cv0)c>z*ti?AQP}*} zVnIpBbQta}J}Z6hPxtW5cvk`7{Lk+6N=f~~#t4tT{vTfSPzYX3b%Y-b11GL+=gHfr zmuTgY=5oqr>swxw4Hich23jR^o`zZ7YZ)yc){GmQp?4R>9Z+P@Gwl+6y_^+|A$##K z)O^!eWi(+E`xSa;x%Pmh+ll%@L^@k&OT5#ozCqDe-+}A1a?aL5Nz}N4z_auM6c_+{ zh!QMrL6hgSL$8`0O!pjIRoDYul>)z`1W#DBjGfw!FqB1SA^z zzrDT&dQ#Q~hJO@)KNR^CmX(oT2%@9t4BnF`@WU$M@LL=UN{KI#B4dhY=3R z3bS{?7z7P4i{+n4BDLN|DloJf<+YMB3W$C>*{JeHr zPxE}ee#r|Ox^aYMpsDneU`>TFV0@i=1&!#$w8PCT>P5ckGsVnLMwN6CCvn+m7; zNJyb&^q%I1vR6`OL^>)-CxL>j(KC@K>ei=9&Ot?FF04g|ei`&5wT}eaeOK&YWTRU& zxOzQpy^#twecluWTr7nci~TnKcv`tquw#V@KucW?VylZvlj7oI@X;3UfdSuo-}UJ<*|C&O_#b5J5N zs>({7JAgbuPI(2PbgD03kV)n|MZ!pc#`D2j( zvjm=MH#UzqIL<|azGy3bgTGzEd?demr?>yOO$h3|4Q`&l5IQUErrkSkX8{2QOb^YL zAW#1zNbBy)GdEXoZKXYfm5KIe?GN_Th}QtO*`mfw)j8`!_cVZerY^P<`pWD%S(~1T z^|pWJr3nQVG1>fW!QFJ>6%jRN@R1`GsdpK{=~|AtQgQYudEw9Z!P7dOibVFBX6`HN z2$M6^*9QG0NAfThP*zY{gA=ueuY8qZ6N(Zp|=w>p2}-Ca&;_ z_x9^0Nu1Z=xcuRzn9aTUvX|}9^^+*ieXLDJh8^!vZ=P)Br~6+?f$<0VKXP>R3|itN z;669impwL+i?M*)-~43SNekSh+yBBLF}Iv^pKIlFlC=Yw({I3}4z1p+9eQeqRq_~- zAyiTX>*9k1)8B^gcse#_8z!D;@*QP&;!D1X$3?IWWOtTt==tE( zQm>ET3lVbSRrd%%th*8BWMiDBBWC5gAa_Epi1&+=*A)PPr%BiqPoUnDh&w^5pxNXR z+c%1Bl+FRY zK(lsIu|U*si=QBGAwWAu&LZQ{imuS}ohIlJq%ed77`IS#?dx9n;sjxnhM5hm=tU@< z?4W6h&NAJg^V9HZc*LkKZ+a(%3(aC>Ll=%R6mQ*ZAR3dvQ0b=Fh@yjU|2CQE8B*)QcuQJ&PqvTLx==F*wcjZ$YW z4*1Toe(^|bA&rqV+8QC%LI$V_!URVZ$=~>JSL%}Ddkw$>M++z$%}b8OZ<^V!YU zCn!!LZZVuCwfmz|r(q{j1U^f6Q%y}*6Y5?yOHD~jRZS26rAlnMhG1huj-?`YkF}qR zm(gJF!AheGNlhpNEvBAU6{Gi&>cr>16wKn^)R$N|sX%FHymJ}MqxS0cCu;l7kma_V z1?B9Xs^zJ*B&#lIq+wiG$LYS9r7V|yhUSjKOMo+n4_iU%AO9kfy-lbQdK|j;%0iEZn ztgHYD>mbT_()P7ErxV-=4vh*JuIVL8ROlq*>3%T(N8{r}hsL9Wom4pK$}+WmxEIol zeNYlQh&jUunT^5{R*XGX4ET|-ZAjSo*J4(+$$$1sQu5?7?TjFI3a3> z2(5-eRLUDeuajv%X+EMU8CB^bf~M#n7#19Yd3{lQu7aJBp)|>JXp2L(hWFnuoGQ^s z$Wv2P+($6CI?#Jn+q>4dk4vDd9@vC+3}|s}l;LM{vWUYFeFk%x7PY_`SS{VP^0L5% zTa*1sZY6ha4EPoWj0|qyq9gYYZqF3!UH^#$c#WNDKd*zsPo?Jh4h7JlIT>6p6HFH@K&z+Q5iKOcS6s&O+JCn?+1dX!ncV5CE1 z@6!wAP$CU7@VbiHNy>9%hY+GHst7@!9vh?w2Wb4vlyg+Rdv-0}Ww>y?w&55XYe9*N zTy$Ikco8@vHENanE$jmuFvDzApt)Dq>ZrM=FhXzL?oFQvc)m^_fw$)0oCY<~<2i@S zt7i|IlJzRl>m)d(GssTmxp89k6qm~h70Cjk@`ABPgqaio2YPYTDSCC(yMc>f@T1Ps z-+x{QX!E+qmM~WV!F051qHZr6V+<@B=X6({sas5xdo>e*KnSII#dJPd2gWb3dfGkV z5k9_E24pye8ax>Bk!ANpa}1h}Wl9RYM2 zN~$FYc55sBoC+hMsj ze>dv+fvTMwwfV=MbWZTR(Zd2X+v*jhI+klL8CDUy?8jRKBVj`2#u#2MVS*3xws0h- zj>2B=(C{qq^51J4)*vOL7P!3}+`!aFj5hgrYI1?PhsBVX(fvf(ji-x`uuig^!~d31 zbEjUc9<)GxWXro-2m8UPfwT6zu;Oa=Sb}-1Yv+~BPlE8XSNE-ORSi6Z2Zu0aYVHda z1u1x)#zl>-=Sq$ofl*h54`}-L+k7EJz5fc?nc2Y8;cg4kGZ$wTw)lGInn zKqp2SKIo^E#RlH)i8WKxZ{g-ac*zfu4+vwn!Tv+}@4oig2Kuk)%Oa7moo(|i6kka1 zrVs3_q2%Cq-1jqOZ*my1;|Vm`Df6c63iBFq?%BlA1T~UAMA;%-O54=O<0w={!g#+* zgiT%<5A@M)e*wK{kpF(UK^}+M(~_Nwku=q8zp&N`2I(aa*;%ivfxl@Se%nb(VifB5KEwCCZz--SOG)2n;xf;%LN?l+ai2cUQasW}OBe`OSoygXJcipp&XIH`$uS$Sg*i(x%jthi$?#5b2 zX9=4$611ft11aXv7)5AK$cJOXG_Qm?D$wP2K$n{%8|a4;r_Vh8D$dYL9?O&#&zuGb ztjKfBMunF3>6euVyT9$_bI+AX*PsR!h}uV%nVOL)ZU4O~9XuFzM>oI31a=XIio2h7+yq zj1$dbnZ~CX4U-7va!h%~#vZ zX@j^+#{i%dm)Y)DY-!)$pX%7P#&-)2rFqoY?r#-fL+6#9D`z6=(Pd&B-4w3q&8H

47%ep(>~T=&u*f zGgv>dOfhSLz|G)@{+;}Ye)_Vtq1n}*SN1+&xM>ft2^MGzTyXAj8(9CKa8Y5EMBplY zwyCArnp}K4k?nS{`TSZR0A!|L>z3)i(D(U4SQJG#=DOPl(6Hk)M3pwi> z+Sr>~Tm55`^W#ir`ZHF4JM?ms!_NE{0Z?7aAx}Of@~rpNFt8|+=-xyBxf~YzVUA#kgE46W-g2~GU?dF^Jc-GHW?M6MHo*v$PMj2*CZ5ZvwCphh! z@S!3IMm-%2Jl}-LBU_0_u|qX>KI212G91w(5B~V_BHGpB+mEnWHD|GpFgUAqBCBAY zq^1-fKJ?&aIWwvTC01YZwUr;+!jFjAIKiKLd?IboirE*VS8~2c_mCm!k!*EoLYxgp ztYmIj-BO_%;pG(3{}?~Jld)C3?5wy+xh_mVYc|5d!MZ+&y{6tZH-~4Pt~6xLT!NEh zg0B6CLEoP3Y8^uLr(rG8N7w93CBI`o2!G8E=JkQTaHVhk@8Fb~ZFbWm?UM1Lhe{wg z@n1Q6h2~F2dIp-`(Tk7-h1BpeQyD}!K$cBqFq^}EN z71dl?*J_3ysyb=d+)c5`8-2Y!H8*t=0^}fD_Z1=qgERM5x`IuQlvd@>(a~x`l&#^V zvXwWdu?+yUU!sO6^6zC<2E?1Lcv@5A&O&e6H>`mk(UXwpbQ4IxLytJ!8KKpI$>Dj9wW<6BvIz~#YY&^I;_t$b z_>vd0o<|H5g7|_EMYrT{?``sZ0tPmBaI-*$@&K0X!1gBU%GXMF1t8yAd=8l@L%=}{ z)elw<>Y;hM#SNPMirjX`d0`xAnaZE10pRtD-p}YTmYx{YX{Joccm!8ULTylPmZ1So zQ#Yx9lv`$ZkmFAyhf9F5!GBrUYC_(3l{YAC|7}BDHZkaz`8JsJczgD^|8LKof`R$( zk6yGE12`YL|N7z_eKBR}+4$P5@-bu(j4hw2U}K>TcQZcQ>?!*)*|Ua~sOBB0XDkPc z7Hh0;D+i0+4flAHb>=1}KivMllI-Ai#O0edX+$A?V!@=0;L!HhgD zb*V|K%cQz%sg8{+s>e#8qMT4O>Y8vHM|4qXmv!1aV4zDLYFKr!gJ0UO1kT03^qaJ| z?j_O>Zo@_%4>?XYl=QZ7N*&E-9wcpXy|U`cTIl6BwZE_ds7`8uyB zSORPUn z*#v+9IT0Fq#QG3>M8{<4W)rsrrfXuhwy`keg8h~B^ntYsh6xjKHnI(Dv+G5%E~q4l zD98%Fj9soB3ot_Z{bTq1kAun9t-5CL()D!LxJ28co_5|(Jwlnl_B^#4HR=&!(L{;* z-3gO}l;Ttj|A{Dp9~FBmJ?LqxlO!ap@PKnz3-l%>uxl2(@-2D^+4i4Ehr?DYe5`uB zi9AVtX8?SJgu@(>{CH^djm`E@rx4y7GOm5>Vh}lBYrRiMZQ%F*9o67%mT?=*JjR!x z1ziYjuybrF%-c??N+T;@?~mU4ote_7>TDcV=u8bQk!>}5NV&l*mxf>hOyqc5Gn8>u z&18CZ7Nz3{!AcuR3vA_-1^tqdmRlRmVyoJ?i}HN+v{m7kCCBWJy56p3D-1D@9o}5e zV$s85OmtkCXGgD;IrzOAvq$r9zx|k4Zbb!tylG6t-qbDs%ZB6EdP9(3z}mvW(#r0i z6L<|3TqX1u|3pnrAnTLK&KZyri4cN?t2@Qw(g}=kJq<9pKxD39;Iu8HGq+Tz}oSR z0P~Q#c~;=`K;TDct74FR40!a&(RwUtEAtI+?E3>EJQ{EXp{qPg7{852DD9p>Pln4p z1y*g~3Ak+ZzrRF!4rF>QL`sK^Jf)|jgBLYoZBCd|8f9|4s(D!uv$ouwHgwR^8P2cX z-Ze6^td_4Cn%^HwJ%0WO`jWfzL!|a74S%*|A1rnxuPHlEYL+^uT6(Yo4*e8YJ9TU& zc^poZn@b9Z0h$gTD~LkcK`yCwK2VZUU-dygH(_3a#%wJIpHM_o8

6cZ}6G2~WIl zPSH+@4jW;qH=edubc|D1)t`mx{TlJGUPw=|{p=!R!OZ75O4T9-Dild4nsD?(hW#-! zsk1WYtRGvRqjh+*6+^F}7oWdpRHnEtqD-VYC|VxXHJvDDV(r{B&=jd@)2cd(r7I2B zxR7{$bx=3HGJ8_}Y}0ChX%5{(GVa1fPVfRdYVU^zESU)Ul;Kh=pThCcPfVUDp_YbB zs@?QF3ujCOyCU?%;xIcc(2gt1C>32(7))mX3zVqEiwGOjMy_wU;aEW1-=7UT-bT$o z+!jc=I>M3qzWaxMkVt-Es$FeZ|bZ{E6clHFHL2m zThYU{mXmO@%hy3XoVgWH@=!l}PFyqXW>)lpr9N8-n&4;fI$(pXWz8bH+`ymm6=a{t3I+6%@)*flha&OhbY!hZhnt#);g6gd660 zb7~@^z%Iyw9NXKAdGr&abZ5|SoA~^dq|)J3%an5P}Y>=FMB_;tLz<$YLc|Xqf8;XZ{yAH;2ntE zlC$j(YWR-z8kT?Kmcur!Dl{uwCR}Z`f`v-IVS$^FwmX4f5bF zmm5dC2jb@9=3~w|KiSYJ5rMWVh2WM_@|Nj{4euk;UptgERo0Bxw<_uWZN*6b_mz^8 zy{W}N5}TjWABl||cEkYdy;!57I$Lh+u3kc%-U%e!&Ybde$h$B&c{fzVg9+WPq{IxR zd!iRGod;Qm(qNDM?6RGRuZ`o0VlbriI%9_Et#1kK?3m^9me+b6G=Wb@1XX1#P*1qG zAE)eQ6HRm4Myvnb3VL^mbbuX>RnTZlIONJ)WguCl`dp>A626m-N-sC0T(h=9B=y{C z(!t^~3#U<~cCqbko;L^n>W)Q7bC+(w3CpyR^eF9p+0M*B=C{IAXCAvJ=4xEc?tC~` zW4iteYZNPT4P|7FB5PYnAEDt*B%EfzX<23Ps9_g%_3%h-4-aeK(_UQumloC1v!oOy z5A*coC(d>EN(CnFy3u;-U9|No?x^Orz4FF6tIxunwUQLw(h_wV*xZlaZD9H#*46&_ ziUQc;JjHDd<2U?{Fnj(2$XkTmOY#Z!m{coqwve_eS~n=QnFT%AQ=P;HvfJRC zVT*3YdSAV2`Fr={8o)~`ywhEx#cNKrCu+qLO^%b#r(-x_wQ!@>+G=CKTlyh0p4;EA zf_7faB~t{?0wH#@jDH@g5hq9{#B0{5iMlx~1{HdxVdDUN?m&A^GuV z!@*FerlV(9hrVPHCAMleCUqO@Ip6|n?q_YV6u69>?9VVSDG9-?>X^8b9eyHSElV6g{G3RaaP^ z<`Bk+F*4)1+V%{%2(kYtpkL0~XB#I>V$<<>_j##+rF$cO8$Z*9`4tnjoj5x9*((i3 zzO{EHeZtN<;{}556>8}y1#5tXda@se5bHC74=Z`#In@xW;I@ciUlhoXo9^$LVZ*3n z5(JYu1Tn1S{5bK0TC$3Eg=+#mI_U*lk{STBK77pB2J^$99Wi9WzVD_g|vme~0}iQSdM4UzX!V_4fWR*uP1He`omR{ZIYzFD39F_A9XC+wqsi z_U{nCbisevFGSMY@!wUse~0{~68^(}A^YBr|Bn2n0scGmFU{~D_6vRUcKjXvOF{g1 z48Ih_f7mYu>bFk!KQa76Py9R4?|R~YQssCV{yov}>f+ytf0qOON&Na&KL5=({14)w z-?@L6!u-jt^S0pr-?{%?81p;#?`!fuxzmyUJMOf6)In zm-s!-??aD2<0KILpW^(_5yEwSZ$tgwasN*Id%yK3@h0)#690$p>v!(o jOPxQtyD0va``-#5SqaFuQSPtYh79uXmT@3ye|`FY2wF4p literal 0 HcmV?d00001 diff --git a/src/main/java/com/eactive/eai/adapter/http/client/impl/HttpClient5AdapterServiceRest.java b/src/main/java/com/eactive/eai/adapter/http/client/impl/HttpClient5AdapterServiceRest.java index 0ddd235..da4f224 100644 --- a/src/main/java/com/eactive/eai/adapter/http/client/impl/HttpClient5AdapterServiceRest.java +++ b/src/main/java/com/eactive/eai/adapter/http/client/impl/HttpClient5AdapterServiceRest.java @@ -86,8 +86,10 @@ import java.nio.charset.StandardCharsets; import java.util.Base64; import com.kjbank.encrypt.exchange.crypto.AES256Cipher; import com.kjbank.encrypt.exchange.crypto.AESCipher; +import com.nimbusds.jwt.SignedJWT; import com.kjbank.encrypt.exchange.crypto.AES256GCMCipher; import com.eactive.eai.authserver.service.OAuth2Manager; +import java.util.Set; /** @@ -114,6 +116,11 @@ public class HttpClient5AdapterServiceRest extends HttpClient5AdapterServiceSupp public static final String HTTP_STATUS = "HTTP_STATUS"; public static final String HEADER_KEYS = "HEADER_KEYS"; public static final String AUTH_TOKEN = "AUTH_TOKEN"; + + public static final String PAYLOAD_PARAM_NAME_CLIENT_ID = "client_id"; // jwhong + + private boolean useAdapterToken; + private boolean encryptResponseApply; /** * 1. 기능 : REST API 통신에 사용
@@ -144,7 +151,7 @@ public class HttpClient5AdapterServiceRest extends HttpClient5AdapterServiceSupp String headerGroupName = prop.getProperty(HEADER_GROUP); String relayResponseHeaderKeys = prop.getProperty(HEADER_KEYS, ""); - boolean useAdapterToken = StringUtils.equalsIgnoreCase(prop.getProperty("ADAPTER_TOKEN_USE_YN", "N"), "Y"); + useAdapterToken = StringUtils.equalsIgnoreCase(prop.getProperty("ADAPTER_TOKEN_USE_YN", "N"), "Y"); boolean useForwardProxy = StringUtils.equalsIgnoreCase(prop.getProperty("FORWARD_PROXY_USE_YN", "N"), "Y"); String forwardProxyUrl = prop.getProperty("FORWARD_PROXY_URL"); @@ -157,6 +164,9 @@ public class HttpClient5AdapterServiceRest extends HttpClient5AdapterServiceSupp // 레이아웃 메시지 타입 REST URL 추출 시 활용. Default JSON String messageType = prop.getProperty("MESSAGE_TYPE", MessageType.JSON); String inboundMethod = tempProp.getProperty(HttpAdapterServiceKey.INBOUND_METHOD, "POST"); + + //Outbound 요청에 대한 응답 메시지의 복호화 여부 결정위해 jwhong + encryptResponseApply = StringUtils.equalsIgnoreCase(prop.getProperty("ENCRYPT_RESPONSE_APPLY", "N"), "Y"); /** * @formatter:off @@ -287,6 +297,51 @@ public class HttpClient5AdapterServiceRest extends HttpClient5AdapterServiceSupp requestConfigBuilder.setProxy(proxy); } + // OAuth2AccessToken check 부분을 뒤에서 여기로 위치를 옮김, 나이스지키미 암호화 KEY를 얻기 위해서. JWHONG + OAuth2AccessTokenVO accessToken = null; + String auth =""; + if (useAdapterToken) { + AccessTokenManagerByDB tokenManager = AccessTokenManagerByDB.getInstance(); + accessToken = (OAuth2AccessTokenVO) tokenManager.getAccessTokenVO(vo.getAdapterGroupName()); + + // 토큰이 없거나 만료 됐으면 재발급 + if (accessToken == null || accessToken.isExpired()) { + String oldToken = accessToken == null ? null : accessToken.getAccessToken(); + accessToken = (OAuth2AccessTokenVO) tokenManager.retryAccessTokenVO(vo.getAdapterGroupName(), prop, + oldToken); + } + + if (logger.isDebug()) { + logger.debug("HttpClientAdapterServiceRest] SEND (" + vo.getAdapterGroupName() + ") TOKEN = [" + + accessToken + "]"); + } + + Properties properties = AdapterPropManager.getInstance().getProperties(vo.getAdapterName()); // jwhong + String encryptAlgorithm = properties.getProperty("ENCRYPT_ALGORITHM"); // jwhong + if (useAdapterToken && "AES256-NICEON".equals(encryptAlgorithm)) { + String niceToken = accessToken.getAccessToken(); + String clientId = JwtClientIdExtractor(niceToken); + long currentTime = System.currentTimeMillis(); + auth = niceToken + ":" + currentTime + ":" + clientId ; + auth = Base64.getEncoder().encodeToString(auth.getBytes("UTF-8")); + + setNiceOnAuthHeaders(method, auth); + } else { + setAuthHeaders(method, accessToken); // 원래 있던 logic + } + + + if (logger.isDebug()) { + logger.debug("HttpClientAdapterServiceRest] SEND (" + vo.getAdapterGroupName() + + ") RequestHeader [Authorization=" + method.getHeader("Authorization") + "]"); + } + } + + if(!StringUtils.isBlank(authToken)) { + setAuthHeaders(method, authToken); + } + // 여기 까지 + configureHttpClient(requestConfigBuilder, vo, method); switch (HttpMethodType.getValue(rmethod)) { @@ -311,7 +366,7 @@ public class HttpClient5AdapterServiceRest extends HttpClient5AdapterServiceSupp case POST: // assignPostBody(dataObject, contentType, vo.getEncode(), method); //assignPostBody(dataContent, contentType, vo.getEncode(), method); // jwhong commnet - assignPostBody(dataContent, contentType, vo.getEncode(), method, vo.getAdapterName()); + assignPostBody(dataContent, contentType, vo.getEncode(), method, vo.getAdapterName(), auth); break; default: break; @@ -322,39 +377,15 @@ public class HttpClient5AdapterServiceRest extends HttpClient5AdapterServiceSupp + method.getEntity() + "] "); } - OAuth2AccessTokenVO accessToken = null; - if (useAdapterToken) { - AccessTokenManagerByDB tokenManager = AccessTokenManagerByDB.getInstance(); - accessToken = (OAuth2AccessTokenVO) tokenManager.getAccessTokenVO(vo.getAdapterGroupName()); - - // 토큰이 없거나 만료 됐으면 재발급 - if (accessToken == null || accessToken.isExpired()) { - String oldToken = accessToken == null ? null : accessToken.getAccessToken(); - accessToken = (OAuth2AccessTokenVO) tokenManager.retryAccessTokenVO(vo.getAdapterGroupName(), prop, - oldToken); - } - - if (logger.isDebug()) { - logger.debug("HttpClientAdapterServiceRest] SEND (" + vo.getAdapterGroupName() + ") TOKEN = [" - + accessToken + "]"); - } - - setAuthHeaders(method, accessToken); - - if (logger.isDebug()) { - logger.debug("HttpClientAdapterServiceRest] SEND (" + vo.getAdapterGroupName() - + ") RequestHeader [Authorization=" + method.getHeader("Authorization") + "]"); - } - } - - if(!StringUtils.isBlank(authToken)) { - setAuthHeaders(method, authToken); - } + // OAuth2AccessToken 원래 있던 위치 JWHONG // 전달 header 셋팅 // Adapter 레벨 header 보다 data로 넘어온 httpHeader를 우선 적용(header명이 같다면 덮어씀) assignRequestHeaders(method, httpHeader); - + + // KJBank API 추적정보를 Header에 제공. jwhong + assignRequestKJHeaders(method, prop, tempProp ); + int status = -1; try { @@ -396,7 +427,6 @@ public class HttpClient5AdapterServiceRest extends HttpClient5AdapterServiceSupp // encrypt algorithm type 추출 from adapter property jwhong Properties properties = AdapterPropManager.getInstance().getProperties(vo.getAdapterName()); // jwhong String encryptAlgorithm = properties.getProperty("ENCRYPT_ALGORITHM"); // jwhong - String encryptBaseKeyType = properties.getProperty("ENCRYPT_BASE_TYPE"); // jwhong try { if (logger.isDebug()) { @@ -414,7 +444,7 @@ public class HttpClient5AdapterServiceRest extends HttpClient5AdapterServiceSupp responseMessageOri = EntityUtils.toByteArray(response.getEntity()); System.out.println("responseMessageOri 바이트 배열 길이: " + responseMessageOri.length); - responseMessage = doOutboundPostFilter(responseMessageOri, encryptAlgorithm, vo.getAdapterName()); // jwhong + responseMessage = doOutboundPostFilter(responseMessageOri, encryptAlgorithm, vo.getAdapterName(), accessToken); // jwhong // 여기까지 responseHeaders = response.getHeaders(); @@ -682,6 +712,37 @@ public class HttpClient5AdapterServiceRest extends HttpClient5AdapterServiceSupp method.setHeader("Authorization", String.format("%s %s", AccessTokenVO.BEARER_TYPE, accessToken.getAccessToken())); } + + /* nice on 나이스 지키미 용으로 생성함 + * jwhong 2015-11-04 + */ + private void setNiceOnAuthHeaders(HttpUriRequestBase method, String auth) throws Exception { + method.setHeader("Authorization", + String.format("%s %s", AccessTokenVO.BEARER_TYPE, auth)); // 나이스지키미 format임 + method.setHeader("ProductID", "2303345072"); + //method.setHeader("Authorization", + // String.format("%s %s", AccessTokenVO.BEARER_TYPE, accessToken.getAccessToken())); + } + + /* nice clientid 추출을 위하여 추가한 내용임. jwhong + * + */ + private String JwtClientIdExtractor(String inboundToken) { + + String tokenClientId =""; + try { + SignedJWT signedJWT = SignedJWT.parse(inboundToken); + tokenClientId = (String) signedJWT.getJWTClaimsSet().getClaim(PAYLOAD_PARAM_NAME_CLIENT_ID); + } catch (Exception e) { + logger.error(e.getMessage()); + tokenClientId = ""; + } + + System.out.println("Token Client ID: " + tokenClientId); + return tokenClientId; + + } + private boolean checkTokenRetry(byte[] responseMessage, String tokenErrorCodeKey, String tokenErrorCodeValues, String encode) { @@ -736,8 +797,41 @@ public class HttpClient5AdapterServiceRest extends HttpClient5AdapterServiceSupp } } + /* + * KJBank Target System으로 요청 보낼때 header에 clientId(업체정보), APIM거래추적자(UUID), 최초 요청시간 을 보낸다. jwhong + */ + private void assignRequestKJHeaders(HttpUriRequestBase method, Properties prop, Properties tempProp) { + + Properties inboundHeaders = (Properties) tempProp.get(HttpAdapterServiceKey.INBOUND_HEADER); + String authorization = inboundHeaders.getProperty("authorization"); + String jwtToken = ""; + + if (authorization != null && authorization.startsWith("Bearer ")) { + jwtToken = authorization.substring(7); // "Bearer " 이후의 JWT만 추출 + //System.out.println("JWT Token: " + jwtToken); + } + + /* 업체정보 */ + String clientId = JwtClientIdExtractor(jwtToken); + method.setHeader("clientId", clientId); + + /* APIM 거래추적자 */ + String uuid = tempProp.getProperty(TransactionContextKeys.TRANSACTION_UUID, ""); + method.setHeader("traceId", uuid); + + /* 최초요청시간 */ + Set keys = tempProp.stringPropertyNames(); + for (String key : keys) { + String value = tempProp.getProperty(key); + System.out.println(key + " = " + value); + } + + String receivedTimestamp = tempProp.getProperty(HttpAdapterServiceKey.INBOUND_REQUESTED_TIME, ""); + method.setHeader("receivedTimestamp", receivedTimestamp); + } + @SuppressWarnings("deprecation") - private void assignPostBody(Object eaiBody, String contentType, String charset, HttpUriRequestBase method, String adapterName) { + private void assignPostBody(Object eaiBody, String contentType, String charset, HttpUriRequestBase method, String adapterName, String niceAuth) { if (eaiBody == null) { return; } @@ -758,7 +852,7 @@ public class HttpClient5AdapterServiceRest extends HttpClient5AdapterServiceSupp } else { ContentType contentTypeObj = ContentType.create(contentType, charset); - String eaiBodyMessage = doOutboundPreFilter(eaiBody,adapterName); // jwhong + String eaiBodyMessage = doOutboundPreFilter(eaiBody, adapterName, niceAuth); // jwhong StringEntity entity = new StringEntity(eaiBodyMessage, contentTypeObj); // 요청 본문을 StringEntity 객체로 생성 //StringEntity entity = new StringEntity(eaiBody.toString(), contentTypeObj); @@ -768,12 +862,15 @@ public class HttpClient5AdapterServiceRest extends HttpClient5AdapterServiceSupp } } - private String doOutboundPreFilter(Object eaiBody, String adapterName) { + // from here by jwhong + private String doOutboundPreFilter(Object eaiBody, String adapterName, String niceAuth) { Properties properties = AdapterPropManager.getInstance().getProperties(adapterName); // jwhong - String encryptAlgorithm = properties.getProperty("ENCRYPT_ALGORITHM"); // jwhong - String encryptBaseKeyType = properties.getProperty("ENCRYPT_BASE_TYPE"); + String encryptAlgorithm = properties.getProperty("ENCRYPT_ALGORITHM",""); // jwhong + //String encryptBaseKeyType = properties.getProperty("ENCRYPT_BASE_TYPE"); String encryptClientId = properties.getProperty("ENCRYPT_CLIENT_ID"); + String encryptAES256Iv = properties.getProperty("ENCRYPT_AES256_IV"); + String encryptAES256Key = properties.getProperty("ENCRYPT_AES256_KEY"); // outbound encrypt 는 SecretKey 또는 NICE-auth 가 암호화 key로 사용된다. // 참고로 inbound encrypt 에는 Token 또는 SecretKey 가 암호화 key로 사용된다. @@ -781,19 +878,30 @@ public class HttpClient5AdapterServiceRest extends HttpClient5AdapterServiceSupp OAuth2Manager manager = OAuth2Manager.getInstance(); ClientDetails clientDetail = manager.getClientDeatilsStore().get(encryptClientId); String clientSecret = ""; - if ( clientDetail != null ) { + if ( clientDetail != null ) { // not null 이라는 것은 APIM Oauth Server에 등록된 client ID 이다. + // 이건 KJBank로 Outbound 나가는 것임 clientSecret = clientDetail.getClientSecret(); + } else { // 그럼 업체로 Outbound 나가는것은, 업체에서 사용하는 secretkey를 사용한다. + clientSecret = encryptClientId; + } + + // Nice-auth , token 값을 substring 해서 사용한다. 나이스 지키미는 adapter token에서 추출된 token을 사용한다. + if (useAdapterToken && "AES256-NICEON".equals(encryptAlgorithm)) { + clientSecret = niceAuth; } // 여기서 SECRETY인지 nice-auth 인지 check 하여 clientSecret 값을 정하는 logic 추가하여 넘겨야한다. - String responseMessage = doOutboundPreEncrypt(eaiBody, encryptAlgorithm, clientSecret); + String responseMessage = doOutboundPreEncrypt(eaiBody, encryptAlgorithm, clientSecret, encryptAES256Iv, encryptAES256Key); return responseMessage; } - private String doOutboundPreEncrypt(Object eaiBody, String encryptAlgorithm, String clientSecretKey) { + private String doOutboundPreEncrypt(Object eaiBody, String encryptAlgorithm, String clientSecretKey, String encryptAES256Iv, String encryptAES256Key ) { String encryptedMessage = ""; + String encryptedJsonKey = ""; + + encryptedJsonKey = getJsonKey(encryptAlgorithm); switch (encryptAlgorithm) { case "AES": @@ -818,12 +926,33 @@ public class HttpClient5AdapterServiceRest extends HttpClient5AdapterServiceSupp } break; case "AES256": - //AES256Cipher aes256Cipher = new AES256Cipher(); try { - //String cleintSecretKey="BxnZ4wpIrTSw8fAkMuF3lYIGZySl1vl47jrErPpGWbAH7uUBeVsJ77njNUrnkAdHJ5fKbNqbiNIE6qCAJ8KfxYJMmbZZrsXCwNMUFooRUcsyRfcDd80h9v490UO4YoQB"; String key = clientSecretKey.substring(10,42); - //String key = "0123456789abcdefghij0123456789ab"; - //encryptedMessage= aes256Cipher.encrypt(eaiBody.toString(), key); + encryptedMessage = AES256Cipher.encrypt(eaiBody.toString(), key); + } catch (Exception e) { + e.printStackTrace(); + logger.error("HttpClientAdapterServiceRest] AES256 Encryption error=" + e.getMessage()); + } + break; + case "AES256-KAKAO": + try { + encryptedMessage = AES256Cipher.encrypt(eaiBody.toString(), encryptAES256Iv, encryptAES256Key); + } catch (Exception e) { + e.printStackTrace(); + logger.error("HttpClientAdapterServiceRest] AES256 Encryption error=" + e.getMessage()); + } + break; + case "AES256-TOSS": + try { + encryptedMessage = AES256Cipher.encrypt(eaiBody.toString(), encryptAES256Iv, encryptAES256Key); + } catch (Exception e) { + e.printStackTrace(); + logger.error("HttpClientAdapterServiceRest] AES256 Encryption error=" + e.getMessage()); + } + break; + case "AES256-NICEON": + try { + String key = clientSecretKey.substring(10,42); encryptedMessage = AES256Cipher.encrypt(eaiBody.toString(), key); } catch (Exception e) { e.printStackTrace(); @@ -844,18 +973,31 @@ public class HttpClient5AdapterServiceRest extends HttpClient5AdapterServiceSupp break; default: encryptedMessage = eaiBody.toString(); - break; + return encryptedMessage; + //break; } - return encryptedMessage; + + Map map = new HashMap<>(); + map.put(encryptedJsonKey, encryptedMessage); + JSONObject json = new JSONObject(); + json.putAll(map); + return json.toJSONString(); + //return encryptedMessage; } - private byte[] doOutboundPostFilter(byte[] eaiBody, String decryptAlgorithm, String adapterName) { + private byte[] doOutboundPostFilter(byte[] eaiBody, String decryptAlgorithm, String adapterName, OAuth2AccessTokenVO niceAccessToken ) { + + if ( !encryptResponseApply) { + return eaiBody; + } Properties properties = AdapterPropManager.getInstance().getProperties(adapterName); // jwhong - String encryptAlgorithm = properties.getProperty("ENCRYPT_ALGORITHM"); // jwhong - String encryptBaseKeyType = properties.getProperty("ENCRYPT_BASE_TYPE"); + //String encryptAlgorithm = properties.getProperty("ENCRYPT_ALGORITHM"); // jwhong + //String encryptBaseKeyType = properties.getProperty("ENCRYPT_BASE_TYPE"); String encryptClientId = properties.getProperty("ENCRYPT_CLIENT_ID"); + String encryptAES256Iv = properties.getProperty("ENCRYPT_AES256_IV"); + String encryptAES256Key = properties.getProperty("ENCRYPT_AES256_KEY"); // outbound encrypt 는 SecretKey 또는 NICE-auth 가 암호화 key로 사용된다. OAuth2Manager manager = OAuth2Manager.getInstance(); @@ -863,18 +1005,31 @@ public class HttpClient5AdapterServiceRest extends HttpClient5AdapterServiceSupp String clientSecret = ""; if ( clientDetail != null ) { clientSecret = clientDetail.getClientSecret(); + } else { + clientSecret = encryptClientId; } - // 여기서 SECRETY인지 nice-auth 인지 check 하여 clientSecret 값을 정하는 logic 추가하여 넘겨야한다. - byte[] resPostMessage = doOutboundPostDecrypt(eaiBody, decryptAlgorithm, clientSecret); + // Nice-auth , token 값을 substring 해서 사용한다. 나이스 지키미는 adapter token에서 추출된 token을 사용한다. + if (useAdapterToken && "AES256-NICEON".equals(decryptAlgorithm)) { + clientSecret = niceAccessToken.getAccessToken(); + } + + byte[] resPostMessage = doOutboundPostDecrypt(eaiBody, decryptAlgorithm, clientSecret, encryptAES256Iv, encryptAES256Key); return resPostMessage; } - private byte[] doOutboundPostDecrypt(byte[] eaiBody, String decryptAlgorithm, String clientSecretKey) { + private byte[] doOutboundPostDecrypt(byte[] eaiBody, String decryptAlgorithm, String clientSecretKey, String encryptAES256Iv, String encryptAES256Key ) { byte[] decryptedMessage = null; String eaiStringBody = new String(eaiBody, StandardCharsets.UTF_8); + try { + eaiStringBody = extractBodyMsg(decryptAlgorithm, eaiStringBody); + } catch (ParseException e) { + System.out.println("JSON 파싱 오류 발생 : " +e.getMessage()); + return eaiBody; + } + //test source System.out.println("eaiBody 바이트 배열 길이: " + eaiBody.length); System.out.println("Base64 문자열: " + eaiStringBody); @@ -897,7 +1052,6 @@ public class HttpClient5AdapterServiceRest extends HttpClient5AdapterServiceSupp case "AES128-TOSS": try { String key128 = clientSecretKey.substring(22,38); - //String decryptedStrMessage = AESCipher.decrypt(eaiStringBody, key128); String decryptedStrMessage = AESCipher.decryptExistException(eaiStringBody, key128); decryptedMessage = decryptedStrMessage.getBytes(StandardCharsets.UTF_8); } catch (Exception e) { @@ -908,7 +1062,6 @@ public class HttpClient5AdapterServiceRest extends HttpClient5AdapterServiceSupp case "AES128-TOGETHER": try { String key128 = clientSecretKey.substring(44,60); - //String decryptedStrMessage = AESCipher.decrypt(eaiStringBody, key128); String decryptedStrMessage = AESCipher.decryptExistException(eaiStringBody, key128); decryptedMessage = decryptedStrMessage.getBytes(StandardCharsets.UTF_8); } catch (Exception e) { @@ -926,6 +1079,34 @@ public class HttpClient5AdapterServiceRest extends HttpClient5AdapterServiceSupp logger.error("HttpClientAdapterServiceRest] AES256 Decryption error=" + e.getMessage()); } break; + case "AES256-KAKAO": + try { + String decryptedStrMessage = AES256Cipher.decrypt(eaiStringBody, encryptAES256Iv, encryptAES256Key); + decryptedMessage = decryptedStrMessage.getBytes(StandardCharsets.UTF_8); + } catch (Exception e) { + e.printStackTrace(); + logger.error("HttpClientAdapterServiceRest] AES256 Encryption error=" + e.getMessage()); + } + break; + case "AES256-TOSS": + try { + String decryptedStrMessage = AES256Cipher.decrypt(eaiStringBody, encryptAES256Iv, encryptAES256Key); + decryptedMessage = decryptedStrMessage.getBytes(StandardCharsets.UTF_8); + } catch (Exception e) { + e.printStackTrace(); + logger.error("HttpClientAdapterServiceRest] AES256 Encryption error=" + e.getMessage()); + } + break; + case "AES256-NICEON": + try { + String key = clientSecretKey.substring(10,42); + String decryptedStrMessage = AES256Cipher.decrypt(eaiStringBody, key); + decryptedMessage = decryptedStrMessage.getBytes(StandardCharsets.UTF_8); + } catch (Exception e) { + e.printStackTrace(); + logger.error("HttpClientAdapterServiceRest] AES256 Decryption error=" + e.getMessage()); + } + break; case "AES256GCM": try { byte[] key = AES256GCMCipher.generateKey(); @@ -952,6 +1133,57 @@ public class HttpClient5AdapterServiceRest extends HttpClient5AdapterServiceSupp } + private String extractBodyMsg(String decryptAlgorithm, String eaiStringBody) throws ParseException { + + String decryptedJsonKey = ""; + String decryptedBodyMessage = ""; + + decryptedJsonKey = getJsonKey(decryptAlgorithm); + + try { + JSONParser parser = new JSONParser(); + JSONObject jsonObject = (JSONObject) parser.parse(eaiStringBody); + decryptedBodyMessage = (String) jsonObject.get(decryptedJsonKey); + } catch (ParseException e) { + e.printStackTrace(); + logger.error("HttpClient5AdapterServiceRest] extractBodyMsg error : " + e.getMessage()); + throw e; + } + + return decryptedBodyMessage; + + } + + private String getJsonKey(String Algorithm) { + + String jsonKey = ""; + + switch (Algorithm) { + case "AES128-TOSS": + jsonKey = "preScreeningRequest"; + break; + case "AES128-TOGETHER": + jsonKey = "obpTxData"; + break; + case "AES256": + jsonKey = "preScreeningRequest"; + break; + case "AES256-KAKAO": + jsonKey = "encrypted_data"; + break; + case "AES256-TOSS": + jsonKey = "encryptedData"; + break; + case "AES256-NICEON": + jsonKey = "preScreeningRequest"; + break; + case "AES256GCM": + break; + default: + break; + } + return jsonKey; + } // by jwhong private String encrypt(String plainText) { try { diff --git a/src/main/java/com/eactive/eai/adapter/http/dynamic/HttpAdapterServiceKey.java b/src/main/java/com/eactive/eai/adapter/http/dynamic/HttpAdapterServiceKey.java index f83d8f3..69bb8cf 100644 --- a/src/main/java/com/eactive/eai/adapter/http/dynamic/HttpAdapterServiceKey.java +++ b/src/main/java/com/eactive/eai/adapter/http/dynamic/HttpAdapterServiceKey.java @@ -75,6 +75,9 @@ public interface HttpAdapterServiceKey { static final String ENCRYPT_ALGORITHM = "ENCRYPT_ALGORITHM"; //jwhong static final String INBOUND_TOKEN = "authorization"; // jwhong static final String ENCRYPT_BASE_TYPE = "ENCRYPT_BASE_TYPE"; // jwhong + static final String ENCRYPT_AES256_IV = "ENCRYPT_AES256_IV"; // jwhong + static final String ENCRYPT_AES256_KEY = "ENCRYPT_AES256_KEY"; // jwhong + static final String INBOUND_REQUESTED_TIME = "INBOUND_REQUESTED_TIME"; // jwhong //응답 처리 용 표준 전문 오브젝트 static final String STANDARD_MESSAGE_OBJECT = "STANDARD_MESSAGE_OBJECT"; diff --git a/src/main/java/com/eactive/eai/authoutbound/client/impl/HttpClientAccessTokenServiceWithBase64Header.java b/src/main/java/com/eactive/eai/authoutbound/client/impl/HttpClientAccessTokenServiceWithBase64Header.java index c1aef65..6316890 100644 --- a/src/main/java/com/eactive/eai/authoutbound/client/impl/HttpClientAccessTokenServiceWithBase64Header.java +++ b/src/main/java/com/eactive/eai/authoutbound/client/impl/HttpClientAccessTokenServiceWithBase64Header.java @@ -96,7 +96,8 @@ public class HttpClientAccessTokenServiceWithBase64Header implements HttpClientA if (!UrlUtils.isAbsoluteUrl(uri)) { uri = appendPath(adapterUrl, uri); } - String contentType = "application/json;"; + //String contentType = "application/json;"; // comment by jwhong + String contentType = "application/x-www-form-urlencoded"; // 광주은행 나이스지키미 Charset charset; if (StringUtils.isNotBlank(encode)) { diff --git a/src/main/java/com/eactive/eai/common/logger/EAILogDAO.java b/src/main/java/com/eactive/eai/common/logger/EAILogDAO.java index ae79af9..4dfc052 100644 --- a/src/main/java/com/eactive/eai/common/logger/EAILogDAO.java +++ b/src/main/java/com/eactive/eai/common/logger/EAILogDAO.java @@ -57,6 +57,10 @@ import com.eactive.eai.transformer.transform.Transform; import com.eactive.eai.transformer.transform.TransformManager; import com.eactive.eai.util.HexaConverter; import com.ext.eai.common.stdmessage.STDMessageKeys; +// safeDB +import com.eactive.ext.kjb.safedb.KjbSafedbWrapper; +import com.eactive.ext.kjb.safedb.Utils; +// until here @Service @@ -452,6 +456,7 @@ public class EAILogDAO { } // 암호화 + /* Charset hexaCharset = Charset.forName("euc-kr"); if ("Y".equalsIgnoreCase(EncryptionManager.getInstance().getEncryptYN())) { try { @@ -471,20 +476,22 @@ public class EAILogDAO { } } else { biz = bizMsgStr; - } + } + */ // jwhong safeDB 암호화 - /* + if ("Y".equalsIgnoreCase(EncryptionManager.getInstance().getEncryptYN())) { try { biz = EncryptSafeDb(bizMsgStr); } catch (Exception e) { logger.error("EAIFileLogger] bizMsgStr encryption Error - " + e.getMessage()); + biz = bizMsgStr; } } else { biz = bizMsgStr; } - */ + // jwhong safeDB end // 임시코드 시작 @@ -855,12 +862,121 @@ public class EAILogDAO { return false; } + + private String EncryptSafeDb(String attribute) { + String originalAttribute = attribute; + if (StringUtils.isNotEmpty(attribute)) { + KjbSafedbWrapper wrapper = KjbSafedbWrapper.getInstance(); + attribute = wrapper.encryptNotRnnoString(attribute); + + if (logger.isInfo()) { + // originalAttribute 홀수 글자 마스킹 + StringBuilder sb = new StringBuilder(); + for (int i = 0; i < originalAttribute.length(); i++) { + if (i % 2 == 0) { + sb.append(originalAttribute.charAt(i)); + } else { + sb.append("*"); + } + } + originalAttribute = sb.toString(); + System.out.println("DB 암호화 #2 : {"+ originalAttribute +"} -> {"+attribute+"}"); + //logger.debug("DB 암호화 #2 : {} -> {}", originalAttribute, attribute); + } + } + return attribute; + + } + + public String DecryptSafeDb(String dbData) { + + String dbDataOriginal = dbData; + if (StringUtils.isNotEmpty(dbData)) { + if (this.isEncrypted(dbData)) { + KjbSafedbWrapper safeDBWrapper = KjbSafedbWrapper.getInstance(); + try { + dbData = safeDBWrapper.decryptNotRnno(dbData); + } catch (Exception e) { + // 복호화 실패시 원본 반환 + String logData = dbData.length() <= 3 ? dbData : dbData.substring(0, 3) + "..."; + logger.warn("DB 복호화 실패: 복호화하지 않고 원본 반환. dbData={} (Length : {})", logData, dbData.length()); + return dbData; + } + } else { + logger.debug("DB 복호화 경고: Base64 형식이 아님. 복호화하지 않고 원본 반환. dbData={}", dbData); + } + } + + //logger.debug("DB 복호화 #2 : {} -> {}", dbDataOriginal, dbData); + + return dbData; + } + + /** + * 암호화 여부 확인(base64 인코딩 여부로 판단, 또는 0-9, - 로 구성된 경우 암호화 되지 않은 걸로 판단(연락처)) + * @param data + * @return + */ + private boolean isEncrypted(String data) { + if (StringUtils.isEmpty(data)) { + return false; + } + + // 숫자, - 로만 구성된 경우 암호화 되지 않은 걸로 판단 (ex: 연락처) + if (data.matches("^[0-9-]+$")) { + return false; + } + + data = data.trim(); + + // Base64 형식 체크 + if (!Utils.isBase64(data)) { + return false; + } + + // Base64 길이 체크 (4의 배수) + if (data.length() % 4 != 0) { + return false; + } + + + return true; + } + + + /* private String EncryptSafeDb(String msg) { PropManager propManager = PropManager.getInstance(); String safeDbPath = propManager.getProperty("SafeDB","safedb.path"); - return "this is a message"; + + SimpleSafeDB safedb = SimpleSafeDB.getInstance(); + boolean loginResult = false; + if(!safedb.login()) { + loginResult = safedb.getSafeDBConfigMgr().isLoginCheck(); + } + + String userName = "SAFEDB"; + String tableName = "SAFEDB.POLICY"; + String columnName1 = "bzwkdatactnt"; + + byte[] byteMsg = msg.getBytes(StandardCharsets.UTF_8); + byte[] encryptedBytes1 = null; + + try { + encryptedBytes1 = safedb.encrypt(userName, tableName, columnName1, byteMsg); + System.out.println("Encrypted Data : [" + new String(encryptedBytes1) + "]"); + + byte[] decryptedBytes1 = safedb.decrypt(userName, tableName, columnName1, encryptedBytes1); + + } catch (SafeDBSDKException e) { + e.printStackTrace(); + + } + + String encryptedMsg = new String(encryptedBytes1, StandardCharsets.UTF_8); + return encryptedMsg; } - - + */ + } diff --git a/src/main/java/com/eactive/eai/common/util/JMSSender.java b/src/main/java/com/eactive/eai/common/util/JMSSender.java index c775498..d6930f8 100644 --- a/src/main/java/com/eactive/eai/common/util/JMSSender.java +++ b/src/main/java/com/eactive/eai/common/util/JMSSender.java @@ -69,6 +69,7 @@ public class JMSSender { throw new Exception("qconFactory not found -" + connectionFactory); queue = locator.getQueue(destination); + logger.info("resolved quene name is:" + "["+ queue + "]"); qsender = qsession.createSender(queue); ObjectMessage msg = qsession.createObjectMessage(); diff --git a/src/main/java/com/eactive/eai/inbound/processor/RequestProcessor.java b/src/main/java/com/eactive/eai/inbound/processor/RequestProcessor.java index eb38a42..0aba908 100644 --- a/src/main/java/com/eactive/eai/inbound/processor/RequestProcessor.java +++ b/src/main/java/com/eactive/eai/inbound/processor/RequestProcessor.java @@ -53,6 +53,10 @@ import com.eactive.eai.message.parser.StandardReader; import com.eactive.eai.message.service.InterfaceMapper; import com.eactive.eai.util.SimHeaderUtil; import com.ext.eai.common.stdmessage.STDMessageKeys; + +import org.json.simple.JSONObject; +import java.util.HashMap; +import java.util.Map; //import org.apache.commons.lang3.StringUtils; //import org.springframework.http.HttpStatus; @@ -1297,7 +1301,15 @@ public class RequestProcessor extends RequestProcessorSupport { } else { // 비동기 거래, S-A의 응답거래시에는 NULL을 리턴 - return null; + //return null; // 원래 null return 인데 광주은행은 GUID를 Return 해 달라고 해서 수정함 jwhong + //map.put("guid", guid); + + Map map = new HashMap<>(); + map.put("uuid", vo.getUuid()); + JSONObject json = new JSONObject(map); + //return json.toJSONString(); + + return vo.getUuid(); } } diff --git a/src/main/java/com/eactive/eai/outbound/RESTProcess.java b/src/main/java/com/eactive/eai/outbound/RESTProcess.java index 1b2eb51..5e9c9a7 100644 --- a/src/main/java/com/eactive/eai/outbound/RESTProcess.java +++ b/src/main/java/com/eactive/eai/outbound/RESTProcess.java @@ -439,6 +439,7 @@ public class RESTProcess extends HTTPProcess { PropertiesUtil.copyPropertyIfPresent(this.callProp, this.tempProp, HttpAdapterServiceKey.INBOUND_PATH_VARIABLES); PropertiesUtil.copyPropertyIfPresent(this.callProp, this.tempProp, HttpAdapterServiceKey.INBOUND_REMOTE_ADDR); PropertiesUtil.copyPropertyIfPresent(this.callProp, this.tempProp, HttpAdapterServiceKey.INBOUND_SCHEME); + PropertiesUtil.copyPropertyIfPresent(this.callProp, this.tempProp, HttpAdapterServiceKey.INBOUND_REQUESTED_TIME); // jwhong String svcName = getServiceId(this.reqEaiMsg); if (svcName == null) { From 29eb510e68fe4ecc519622f578cf8e59c46da7d2 Mon Sep 17 00:00:00 2001 From: jaewohong Date: Wed, 19 Nov 2025 16:51:58 +0900 Subject: [PATCH 002/159] =?UTF-8?q?=EA=B0=9C=EB=B0=9C=EC=84=9C=EB=B2=84?= =?UTF-8?q?=EC=97=90=20push=EC=9C=84=ED=95=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../adapter/http/client/impl/HttpClient5AdapterServiceRest.java | 2 +- .../eactive/eai/adapter/http/dynamic/HttpAdapterServiceKey.java | 2 +- .../impl/HttpClientAccessTokenServiceWithBase64Header.java | 2 +- src/main/java/com/eactive/eai/common/logger/EAILogDAO.java | 2 +- src/main/java/com/eactive/eai/common/util/JMSSender.java | 2 +- .../com/eactive/eai/inbound/processor/RequestProcessor.java | 2 +- src/main/java/com/eactive/eai/outbound/RESTProcess.java | 2 +- 7 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/main/java/com/eactive/eai/adapter/http/client/impl/HttpClient5AdapterServiceRest.java b/src/main/java/com/eactive/eai/adapter/http/client/impl/HttpClient5AdapterServiceRest.java index da4f224..8ff7cf6 100644 --- a/src/main/java/com/eactive/eai/adapter/http/client/impl/HttpClient5AdapterServiceRest.java +++ b/src/main/java/com/eactive/eai/adapter/http/client/impl/HttpClient5AdapterServiceRest.java @@ -862,7 +862,7 @@ public class HttpClient5AdapterServiceRest extends HttpClient5AdapterServiceSupp } } - // from here by jwhong + // from here by jwhong private String doOutboundPreFilter(Object eaiBody, String adapterName, String niceAuth) { Properties properties = AdapterPropManager.getInstance().getProperties(adapterName); // jwhong diff --git a/src/main/java/com/eactive/eai/adapter/http/dynamic/HttpAdapterServiceKey.java b/src/main/java/com/eactive/eai/adapter/http/dynamic/HttpAdapterServiceKey.java index 69bb8cf..257f70f 100644 --- a/src/main/java/com/eactive/eai/adapter/http/dynamic/HttpAdapterServiceKey.java +++ b/src/main/java/com/eactive/eai/adapter/http/dynamic/HttpAdapterServiceKey.java @@ -1,7 +1,7 @@ package com.eactive.eai.adapter.http.dynamic; public interface HttpAdapterServiceKey { - // URL 파리미터 DEFAULT 이름 + // URL 파리미터 DEFAULT 이름 static final String PARAMETER_MESSAGE = "_message_"; // URL 파리미터 이름 diff --git a/src/main/java/com/eactive/eai/authoutbound/client/impl/HttpClientAccessTokenServiceWithBase64Header.java b/src/main/java/com/eactive/eai/authoutbound/client/impl/HttpClientAccessTokenServiceWithBase64Header.java index 6316890..295c2f3 100644 --- a/src/main/java/com/eactive/eai/authoutbound/client/impl/HttpClientAccessTokenServiceWithBase64Header.java +++ b/src/main/java/com/eactive/eai/authoutbound/client/impl/HttpClientAccessTokenServiceWithBase64Header.java @@ -1,6 +1,6 @@ package com.eactive.eai.authoutbound.client.impl; - + import com.eactive.eai.adapter.AdapterGroupVO; import com.eactive.eai.adapter.AdapterManager; import com.eactive.eai.adapter.http.client.HttpClientAdapterServiceKey; diff --git a/src/main/java/com/eactive/eai/common/logger/EAILogDAO.java b/src/main/java/com/eactive/eai/common/logger/EAILogDAO.java index 4dfc052..7d8f0a5 100644 --- a/src/main/java/com/eactive/eai/common/logger/EAILogDAO.java +++ b/src/main/java/com/eactive/eai/common/logger/EAILogDAO.java @@ -60,7 +60,7 @@ import com.ext.eai.common.stdmessage.STDMessageKeys; // safeDB import com.eactive.ext.kjb.safedb.KjbSafedbWrapper; import com.eactive.ext.kjb.safedb.Utils; -// until here +// until here @Service diff --git a/src/main/java/com/eactive/eai/common/util/JMSSender.java b/src/main/java/com/eactive/eai/common/util/JMSSender.java index d6930f8..73b15d6 100644 --- a/src/main/java/com/eactive/eai/common/util/JMSSender.java +++ b/src/main/java/com/eactive/eai/common/util/JMSSender.java @@ -1,5 +1,5 @@ package com.eactive.eai.common.util; - + import java.util.Iterator; import java.util.Properties; diff --git a/src/main/java/com/eactive/eai/inbound/processor/RequestProcessor.java b/src/main/java/com/eactive/eai/inbound/processor/RequestProcessor.java index 0aba908..0e814c3 100644 --- a/src/main/java/com/eactive/eai/inbound/processor/RequestProcessor.java +++ b/src/main/java/com/eactive/eai/inbound/processor/RequestProcessor.java @@ -58,7 +58,7 @@ import org.json.simple.JSONObject; import java.util.HashMap; import java.util.Map; //import org.apache.commons.lang3.StringUtils; -//import org.springframework.http.HttpStatus; +//import org.springframework.http.HttpStatus; //import java.util.Calendar; //import java.util.Properties; diff --git a/src/main/java/com/eactive/eai/outbound/RESTProcess.java b/src/main/java/com/eactive/eai/outbound/RESTProcess.java index 5e9c9a7..9d739f6 100644 --- a/src/main/java/com/eactive/eai/outbound/RESTProcess.java +++ b/src/main/java/com/eactive/eai/outbound/RESTProcess.java @@ -1,5 +1,5 @@ package com.eactive.eai.outbound; - + import java.net.SocketTimeoutException; import java.util.Properties; From 3477613a61ab829d8f4fcd149d0c5407bcf119db Mon Sep 17 00:00:00 2001 From: jaewohong Date: Thu, 20 Nov 2025 17:24:38 +0900 Subject: [PATCH 003/159] =?UTF-8?q?prop=EA=B0=92=20=ED=9A=8D=EB=93=9D?= =?UTF-8?q?=EC=8B=9C=20ClassCastException=EA=B4=80=EB=A0=A8=20=EC=88=98?= =?UTF-8?q?=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../impl/HttpClient5AdapterServiceRest.java | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/src/main/java/com/eactive/eai/adapter/http/client/impl/HttpClient5AdapterServiceRest.java b/src/main/java/com/eactive/eai/adapter/http/client/impl/HttpClient5AdapterServiceRest.java index 8ff7cf6..3e22538 100644 --- a/src/main/java/com/eactive/eai/adapter/http/client/impl/HttpClient5AdapterServiceRest.java +++ b/src/main/java/com/eactive/eai/adapter/http/client/impl/HttpClient5AdapterServiceRest.java @@ -802,7 +802,21 @@ public class HttpClient5AdapterServiceRest extends HttpClient5AdapterServiceSupp */ private void assignRequestKJHeaders(HttpUriRequestBase method, Properties prop, Properties tempProp) { - Properties inboundHeaders = (Properties) tempProp.get(HttpAdapterServiceKey.INBOUND_HEADER); + //weblogic 에서는 tempProp.get 이 property로 return 해어 아래처럼 수정함. ClassCastException 발생함. + //Properties inboundHeaders = (Properties) tempProp.get(HttpAdapterServiceKey.INBOUND_HEADER); + Properties inboundHeaders = null; + try { + Object headerObj = tempProp.get(HttpAdapterServiceKey.INBOUND_HEADER); + if (headerObj instanceof Properties) { //tomcat + inboundHeaders = (Properties) headerObj; + } else if (headerObj instanceof String) { //weblogic + inboundHeaders = new Properties(); + inboundHeaders.load(new StringReader((String) headerObj)); + } + } catch (IOException e) { + e.printStackTrace(); + } + String authorization = inboundHeaders.getProperty("authorization"); String jwtToken = ""; From 3508023ce1019beda4221e30338f62f167eb093a Mon Sep 17 00:00:00 2001 From: jaewohong Date: Tue, 25 Nov 2025 16:22:33 +0900 Subject: [PATCH 004/159] =?UTF-8?q?adapter=EA=B0=9D=EC=B2=B4=20=EB=AA=BB?= =?UTF-8?q?=EC=B0=BE=EC=98=A4=EB=8A=94=20=EB=B6=80=EB=B6=84=20=EC=88=98?= =?UTF-8?q?=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../impl/HttpClient5AdapterServiceRest.java | 56 ++++++++++++++----- .../eai/common/stdmessage/STDMessageDAO.java | 8 +++ 2 files changed, 49 insertions(+), 15 deletions(-) diff --git a/src/main/java/com/eactive/eai/adapter/http/client/impl/HttpClient5AdapterServiceRest.java b/src/main/java/com/eactive/eai/adapter/http/client/impl/HttpClient5AdapterServiceRest.java index 3e22538..2c8043f 100644 --- a/src/main/java/com/eactive/eai/adapter/http/client/impl/HttpClient5AdapterServiceRest.java +++ b/src/main/java/com/eactive/eai/adapter/http/client/impl/HttpClient5AdapterServiceRest.java @@ -88,6 +88,7 @@ import com.kjbank.encrypt.exchange.crypto.AES256Cipher; import com.kjbank.encrypt.exchange.crypto.AESCipher; import com.nimbusds.jwt.SignedJWT; import com.kjbank.encrypt.exchange.crypto.AES256GCMCipher; +import com.kjbank.encrypt.exchange.crypto.ECDHESA256Cipher; import com.eactive.eai.authserver.service.OAuth2Manager; import java.util.Set; @@ -442,7 +443,7 @@ public class HttpClient5AdapterServiceRest extends HttpClient5AdapterServiceSupp // 역기서 responseMessage를 decryption 해야 하나 by jwhong responseMessageOri = EntityUtils.toByteArray(response.getEntity()); - System.out.println("responseMessageOri 바이트 배열 길이: " + responseMessageOri.length); + logger.debug("[responseMessageOri 바이트 배열 길이 ]" + responseMessageOri.length); responseMessage = doOutboundPostFilter(responseMessageOri, encryptAlgorithm, vo.getAdapterName(), accessToken); // jwhong // 여기까지 @@ -738,7 +739,7 @@ public class HttpClient5AdapterServiceRest extends HttpClient5AdapterServiceSupp tokenClientId = ""; } - System.out.println("Token Client ID: " + tokenClientId); + logger.debug("[ NICE Token Client ID ]" + tokenClientId); return tokenClientId; } @@ -822,7 +823,6 @@ public class HttpClient5AdapterServiceRest extends HttpClient5AdapterServiceSupp if (authorization != null && authorization.startsWith("Bearer ")) { jwtToken = authorization.substring(7); // "Bearer " 이후의 JWT만 추출 - //System.out.println("JWT Token: " + jwtToken); } /* 업체정보 */ @@ -832,14 +832,16 @@ public class HttpClient5AdapterServiceRest extends HttpClient5AdapterServiceSupp /* APIM 거래추적자 */ String uuid = tempProp.getProperty(TransactionContextKeys.TRANSACTION_UUID, ""); method.setHeader("traceId", uuid); - - /* 최초요청시간 */ + + /* Set keys = tempProp.stringPropertyNames(); for (String key : keys) { String value = tempProp.getProperty(key); - System.out.println(key + " = " + value); + logger.debug(key + " = " + value); } + */ + /* 최초요청시간 */ String receivedTimestamp = tempProp.getProperty(HttpAdapterServiceKey.INBOUND_REQUESTED_TIME, ""); method.setHeader("receivedTimestamp", receivedTimestamp); } @@ -885,6 +887,7 @@ public class HttpClient5AdapterServiceRest extends HttpClient5AdapterServiceSupp String encryptClientId = properties.getProperty("ENCRYPT_CLIENT_ID"); String encryptAES256Iv = properties.getProperty("ENCRYPT_AES256_IV"); String encryptAES256Key = properties.getProperty("ENCRYPT_AES256_KEY"); + String certPath = properties.getProperty("ENCRYPT_CERT_PATH"); // outbound encrypt 는 SecretKey 또는 NICE-auth 가 암호화 key로 사용된다. // 참고로 inbound encrypt 에는 Token 또는 SecretKey 가 암호화 key로 사용된다. @@ -906,11 +909,11 @@ public class HttpClient5AdapterServiceRest extends HttpClient5AdapterServiceSupp // 여기서 SECRETY인지 nice-auth 인지 check 하여 clientSecret 값을 정하는 logic 추가하여 넘겨야한다. - String responseMessage = doOutboundPreEncrypt(eaiBody, encryptAlgorithm, clientSecret, encryptAES256Iv, encryptAES256Key); + String responseMessage = doOutboundPreEncrypt(eaiBody, encryptAlgorithm, clientSecret, encryptAES256Iv, encryptAES256Key, certPath); return responseMessage; } - private String doOutboundPreEncrypt(Object eaiBody, String encryptAlgorithm, String clientSecretKey, String encryptAES256Iv, String encryptAES256Key ) { + private String doOutboundPreEncrypt(Object eaiBody, String encryptAlgorithm, String clientSecretKey, String encryptAES256Iv, String encryptAES256Key, String certPath ) { String encryptedMessage = ""; String encryptedJsonKey = ""; @@ -985,6 +988,27 @@ public class HttpClient5AdapterServiceRest extends HttpClient5AdapterServiceSupp logger.error("HttpClientAdapterServiceRest] AES256GCM Encryption error=" + e.getMessage()); } break; + case "ECDHESA256": + try { + ECDHESA256Cipher cipher = new ECDHESA256Cipher(); + + encryptedMessage = cipher.encrypt(eaiBody.toString()); + System.out.println("Encrypted JWE: " + encryptedMessage); + + String decrypted = cipher.decrypt(encryptedMessage); + System.out.println("Decrypted Payload: " + decrypted); + + //아래 인증서로 테스트 + ECDHESA256Cipher cipherCert = new ECDHESA256Cipher(certPath); + encryptedMessage = cipherCert.encrypt(eaiBody.toString()); + + decrypted = cipherCert.decrypt(encryptedMessage); + + } catch (Exception e) { + e.printStackTrace(); + logger.error("HttpClientAdapterServiceRest] AES256GCM Encryption error=" + e.getMessage()); + } + break; default: encryptedMessage = eaiBody.toString(); return encryptedMessage; @@ -1040,22 +1064,24 @@ public class HttpClient5AdapterServiceRest extends HttpClient5AdapterServiceSupp try { eaiStringBody = extractBodyMsg(decryptAlgorithm, eaiStringBody); } catch (ParseException e) { - System.out.println("JSON 파싱 오류 발생 : " +e.getMessage()); + logger.debug("[JSON 파싱 오류 발생 : ]" +e.getMessage()); return eaiBody; } //test source - System.out.println("eaiBody 바이트 배열 길이: " + eaiBody.length); - System.out.println("Base64 문자열: " + eaiStringBody); - System.out.println("Base64 문자열 길이: " + eaiStringBody.length()); - System.out.println("Base64 문자열 끝: " + eaiStringBody.substring(eaiStringBody.length() - 10)); + /* + logger.debug("eaiBody 바이트 배열 길이: " + eaiBody.length); + logger.debug("Base64 문자열: " + eaiStringBody); + logger.debug("Base64 문자열 길이: " + eaiStringBody.length()); + logger.debug("Base64 문자열 끝: " + eaiStringBody.substring(eaiStringBody.length() - 10)); + */ // Base64 디코딩 테스트 try { byte[] decoded = Base64.getDecoder().decode(eaiStringBody); - System.out.println("디코딩 성공, 길이: " + decoded.length); + logger.debug("[디코딩 성공, 길이: ]" + decoded.length); } catch (IllegalArgumentException e) { - System.out.println("Base64 디코딩 실패: " + e.getMessage()); + logger.debug("[Base64 디코딩 실패: ]" + e.getMessage()); } // end test source diff --git a/src/main/java/com/eactive/eai/common/stdmessage/STDMessageDAO.java b/src/main/java/com/eactive/eai/common/stdmessage/STDMessageDAO.java index 8b8c320..447fe75 100644 --- a/src/main/java/com/eactive/eai/common/stdmessage/STDMessageDAO.java +++ b/src/main/java/com/eactive/eai/common/stdmessage/STDMessageDAO.java @@ -224,4 +224,12 @@ public class STDMessageDAO extends BaseDAO { throw new DAOException(ExceptionUtil.getErrorCode(e, "RECEAICKE111")); } } + + // jwhong 추가 + public StandardMessageInfo getSTDMsgByPath(String apiFullPath) throws DAOException { + Optional optional = standardMessageInfoLoader.findByApiFullPath(apiFullPath); + return optional.orElseThrow(() -> new DAOException("해당 full path의 TSEAIHS04 에 데이터가 없습니다.")); + } + + } From 5469115dca3323a4b94c3a585d5f23b98d06d76d Mon Sep 17 00:00:00 2001 From: "Yunsam.Eo" Date: Thu, 27 Nov 2025 10:03:57 +0900 Subject: [PATCH 005/159] =?UTF-8?q?uuid=20=EA=B7=9C=EC=B9=99=20=EB=B3=80?= =?UTF-8?q?=EA=B2=BD(instid=20=EC=A0=9C=EC=99=B8,=20-=20=EC=A0=9C=EC=99=B8?= =?UTF-8?q?)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../inbound/processor/RequestProcessor.java | 23 ++++++++++--------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/src/main/java/com/eactive/eai/inbound/processor/RequestProcessor.java b/src/main/java/com/eactive/eai/inbound/processor/RequestProcessor.java index 0e814c3..0dc1a94 100644 --- a/src/main/java/com/eactive/eai/inbound/processor/RequestProcessor.java +++ b/src/main/java/com/eactive/eai/inbound/processor/RequestProcessor.java @@ -121,19 +121,20 @@ public class RequestProcessor extends RequestProcessorSupport { String bidInterface = adptGrpVO.getBidInterface(); String testMasterYn = adptGrpVO.getTestMasterYn(); - // UUID 생성 : UUID = server구분4자리 + UUID + // UUID 생성 : UUID = "-" 없는 32자리 UUID(광주은행 요청) String uuid = ""; + uuid = UUIDGenerator.getUUID().toString().replaceAll("-", ""); - if(instid != null) { - uuid = instid + UUIDGenerator.getUUID(); - if (logger.isDebug()) logger.debug("RequestProcessor] UUID ["+uuid+"]"); - } - else { - String rspErrorCode = "RECEAIIRP030"; - String rspErrorMsg = ErrorCodeHandler.getMessage(rspErrorCode); - if (logger.isError()) logger.error(rspErrorMsg); - throw new RequestProcessorException(rspErrorMsg); - } +// if(instid != null) { +// uuid = instid + UUIDGenerator.getUUID(); +// if (logger.isDebug()) logger.debug("RequestProcessor] UUID ["+uuid+"]"); +// } +// else { +// String rspErrorCode = "RECEAIIRP030"; +// String rspErrorMsg = ErrorCodeHandler.getMessage(rspErrorCode); +// if (logger.isError()) logger.error(rspErrorMsg); +// throw new RequestProcessorException(rspErrorMsg); +// } ProcessVO vo = new ProcessVO(); vo.setAdapterGroupName(adapterGroupName); From bf39193f6546643b56860570f08044d4e93eb0b7 Mon Sep 17 00:00:00 2001 From: 25W0075 <25W0075@P9801Z.kjbank.dom> Date: Thu, 27 Nov 2025 13:47:48 +0900 Subject: [PATCH 006/159] =?UTF-8?q?uuid=20"-"=20=EC=97=86=EC=95=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/eactive/eai/inbound/processor/RequestProcessor.java | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/main/java/com/eactive/eai/inbound/processor/RequestProcessor.java b/src/main/java/com/eactive/eai/inbound/processor/RequestProcessor.java index 0e814c3..505b4cc 100644 --- a/src/main/java/com/eactive/eai/inbound/processor/RequestProcessor.java +++ b/src/main/java/com/eactive/eai/inbound/processor/RequestProcessor.java @@ -121,7 +121,11 @@ public class RequestProcessor extends RequestProcessorSupport { String bidInterface = adptGrpVO.getBidInterface(); String testMasterYn = adptGrpVO.getTestMasterYn(); + // UUID 생성 : UUID에서 - 없는 32자리 + String uuid = ""; + uuid = UUIDGenerator.getUUID().toString().replaceAll("-", ""); // UUID 생성 : UUID = server구분4자리 + UUID + /* String uuid = ""; if(instid != null) { @@ -134,6 +138,7 @@ public class RequestProcessor extends RequestProcessorSupport { if (logger.isError()) logger.error(rspErrorMsg); throw new RequestProcessorException(rspErrorMsg); } + */ ProcessVO vo = new ProcessVO(); vo.setAdapterGroupName(adapterGroupName); From a5a4e93d78c2c096294d959c50cdca589f051e54 Mon Sep 17 00:00:00 2001 From: 25W0075 <25W0075@P9801Z.kjbank.dom> Date: Thu, 27 Nov 2025 14:32:49 +0900 Subject: [PATCH 007/159] company code check --- .../adapter/http/client/impl/HttpClient5AdapterServiceRest.java | 1 + 1 file changed, 1 insertion(+) diff --git a/src/main/java/com/eactive/eai/adapter/http/client/impl/HttpClient5AdapterServiceRest.java b/src/main/java/com/eactive/eai/adapter/http/client/impl/HttpClient5AdapterServiceRest.java index 6c7f633..263b1c0 100644 --- a/src/main/java/com/eactive/eai/adapter/http/client/impl/HttpClient5AdapterServiceRest.java +++ b/src/main/java/com/eactive/eai/adapter/http/client/impl/HttpClient5AdapterServiceRest.java @@ -828,6 +828,7 @@ public class HttpClient5AdapterServiceRest extends HttpClient5AdapterServiceSupp /* 업체정보 */ String clientId = JwtClientIdExtractor(jwtToken); method.setHeader("clientId", clientId); + System.out.println("*** header clientID biz company code:"+clientId); /* APIM 거래추적자 */ String uuid = tempProp.getProperty(TransactionContextKeys.TRANSACTION_UUID, ""); From dd3887eb226deb7e0f889581f19e3a5790b7e050 Mon Sep 17 00:00:00 2001 From: 25W0075 <25W0075@P9801Z.kjbank.dom> Date: Thu, 27 Nov 2025 14:57:39 +0900 Subject: [PATCH 008/159] client test --- .../impl/HttpClient5AdapterServiceRest.java | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/src/main/java/com/eactive/eai/adapter/http/client/impl/HttpClient5AdapterServiceRest.java b/src/main/java/com/eactive/eai/adapter/http/client/impl/HttpClient5AdapterServiceRest.java index 263b1c0..b9b3a68 100644 --- a/src/main/java/com/eactive/eai/adapter/http/client/impl/HttpClient5AdapterServiceRest.java +++ b/src/main/java/com/eactive/eai/adapter/http/client/impl/HttpClient5AdapterServiceRest.java @@ -818,13 +818,27 @@ public class HttpClient5AdapterServiceRest extends HttpClient5AdapterServiceSupp e.printStackTrace(); } - String authorization = inboundHeaders.getProperty("authorization"); + //* jwhong + String key ="authorization"; + String authorization = null; + + for (String k : inboundHeaders.stringPropertyNames()) { + if (k.equalsIgnoreCase(key)) { + authorization = inboundHeaders.getProperty(k); + break; + } + } + +// String authorization = inboundHeaders.getProperty("authorization"); String jwtToken = ""; if (authorization != null && authorization.startsWith("Bearer ")) { jwtToken = authorization.substring(7); // "Bearer " 이후의 JWT만 추출 } + System.out.println("*** authorization is:"+authorization); + System.out.println("*** jwtToken is:"+jwtToken); + /* 업체정보 */ String clientId = JwtClientIdExtractor(jwtToken); method.setHeader("clientId", clientId); From b2ccd48e46cd553c79e1b899b82c6abdb91813ad Mon Sep 17 00:00:00 2001 From: 25W0075 <25W0075@P9801Z.kjbank.dom> Date: Thu, 27 Nov 2025 15:15:11 +0900 Subject: [PATCH 009/159] client check test --- .../http/client/impl/HttpClient5AdapterServiceRest.java | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/main/java/com/eactive/eai/adapter/http/client/impl/HttpClient5AdapterServiceRest.java b/src/main/java/com/eactive/eai/adapter/http/client/impl/HttpClient5AdapterServiceRest.java index b9b3a68..973603e 100644 --- a/src/main/java/com/eactive/eai/adapter/http/client/impl/HttpClient5AdapterServiceRest.java +++ b/src/main/java/com/eactive/eai/adapter/http/client/impl/HttpClient5AdapterServiceRest.java @@ -808,21 +808,27 @@ public class HttpClient5AdapterServiceRest extends HttpClient5AdapterServiceSupp Properties inboundHeaders = null; try { Object headerObj = tempProp.get(HttpAdapterServiceKey.INBOUND_HEADER); + System.out.println("*** inboundheader Ojb:"+headerObj); if (headerObj instanceof Properties) { //tomcat inboundHeaders = (Properties) headerObj; + System.out.println("*** inboundHeaders tomcat:"+inboundHeaders); } else if (headerObj instanceof String) { //weblogic inboundHeaders = new Properties(); inboundHeaders.load(new StringReader((String) headerObj)); + System.out.println("*** inboundHeaders weblogic:"+inboundHeaders); } } catch (IOException e) { e.printStackTrace(); } + System.out.println("*** inboundheader obj is:"+k); + //* jwhong String key ="authorization"; String authorization = null; for (String k : inboundHeaders.stringPropertyNames()) { + System.out.println("*** inboundheader k is:"+k); if (k.equalsIgnoreCase(key)) { authorization = inboundHeaders.getProperty(k); break; From 60e3ba6adc118d46d70a7678005bf426ba17ba7e Mon Sep 17 00:00:00 2001 From: 25W0075 <25W0075@P9801Z.kjbank.dom> Date: Thu, 27 Nov 2025 15:18:29 +0900 Subject: [PATCH 010/159] check --- .../adapter/http/client/impl/HttpClient5AdapterServiceRest.java | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/main/java/com/eactive/eai/adapter/http/client/impl/HttpClient5AdapterServiceRest.java b/src/main/java/com/eactive/eai/adapter/http/client/impl/HttpClient5AdapterServiceRest.java index 973603e..76a1cf0 100644 --- a/src/main/java/com/eactive/eai/adapter/http/client/impl/HttpClient5AdapterServiceRest.java +++ b/src/main/java/com/eactive/eai/adapter/http/client/impl/HttpClient5AdapterServiceRest.java @@ -821,8 +821,6 @@ public class HttpClient5AdapterServiceRest extends HttpClient5AdapterServiceSupp e.printStackTrace(); } - System.out.println("*** inboundheader obj is:"+k); - //* jwhong String key ="authorization"; String authorization = null; From 6c05e29ea5c5dd514f69260beaa38f50cf9a10dc Mon Sep 17 00:00:00 2001 From: 25W0075 <25W0075@P9801Z.kjbank.dom> Date: Thu, 27 Nov 2025 16:51:53 +0900 Subject: [PATCH 011/159] check clientid --- .../impl/HttpClient5AdapterServiceRest.java | 34 ++++++++++--------- 1 file changed, 18 insertions(+), 16 deletions(-) diff --git a/src/main/java/com/eactive/eai/adapter/http/client/impl/HttpClient5AdapterServiceRest.java b/src/main/java/com/eactive/eai/adapter/http/client/impl/HttpClient5AdapterServiceRest.java index 76a1cf0..25f05e9 100644 --- a/src/main/java/com/eactive/eai/adapter/http/client/impl/HttpClient5AdapterServiceRest.java +++ b/src/main/java/com/eactive/eai/adapter/http/client/impl/HttpClient5AdapterServiceRest.java @@ -806,34 +806,36 @@ public class HttpClient5AdapterServiceRest extends HttpClient5AdapterServiceSupp //weblogic 에서는 tempProp.get 이 property로 return 해어 아래처럼 수정함. ClassCastException 발생함. //Properties inboundHeaders = (Properties) tempProp.get(HttpAdapterServiceKey.INBOUND_HEADER); Properties inboundHeaders = null; + String authorization = ""; try { Object headerObj = tempProp.get(HttpAdapterServiceKey.INBOUND_HEADER); System.out.println("*** inboundheader Ojb:"+headerObj); if (headerObj instanceof Properties) { //tomcat inboundHeaders = (Properties) headerObj; System.out.println("*** inboundHeaders tomcat:"+inboundHeaders); + for (String k : inboundHeaders.stringPropertyNames()) { + System.out.println("*** inboundheader k is:"+k); + if (k.equalsIgnoreCase("authorization")) { + authorization = inboundHeaders.getProperty(k); + break; + } + } } else if (headerObj instanceof String) { //weblogic - inboundHeaders = new Properties(); - inboundHeaders.load(new StringReader((String) headerObj)); - System.out.println("*** inboundHeaders weblogic:"+inboundHeaders); + String json = (String) headerObj; + JSONParser parser = new JSONParser(); + JSONObject obj = (JSONObject) parser.parse(json); + for (Object k : obj.keySet()) { + if (((String) k).equalsIgnoreCase("authorization")) { + authorization = (String) obj.get(k); + System.out.println("*** inboundHeaders authorization weblogic:"+authorization); + break; + } + } } } catch (IOException e) { e.printStackTrace(); } - //* jwhong - String key ="authorization"; - String authorization = null; - - for (String k : inboundHeaders.stringPropertyNames()) { - System.out.println("*** inboundheader k is:"+k); - if (k.equalsIgnoreCase(key)) { - authorization = inboundHeaders.getProperty(k); - break; - } - } - -// String authorization = inboundHeaders.getProperty("authorization"); String jwtToken = ""; if (authorization != null && authorization.startsWith("Bearer ")) { From 5eae7b6468bdace07bef006ccbc6e9e6ba6c732d Mon Sep 17 00:00:00 2001 From: 25W0075 <25W0075@P9801Z.kjbank.dom> Date: Thu, 27 Nov 2025 16:58:16 +0900 Subject: [PATCH 012/159] parseException --- .../adapter/http/client/impl/HttpClient5AdapterServiceRest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/com/eactive/eai/adapter/http/client/impl/HttpClient5AdapterServiceRest.java b/src/main/java/com/eactive/eai/adapter/http/client/impl/HttpClient5AdapterServiceRest.java index 25f05e9..0db024e 100644 --- a/src/main/java/com/eactive/eai/adapter/http/client/impl/HttpClient5AdapterServiceRest.java +++ b/src/main/java/com/eactive/eai/adapter/http/client/impl/HttpClient5AdapterServiceRest.java @@ -832,7 +832,7 @@ public class HttpClient5AdapterServiceRest extends HttpClient5AdapterServiceSupp } } } - } catch (IOException e) { + } catch (ParseException e) { e.printStackTrace(); } From 4c9639695178127152440fa4348e5a7b1a19236c Mon Sep 17 00:00:00 2001 From: 25W0075 <25W0075@P9801Z.kjbank.dom> Date: Thu, 27 Nov 2025 17:47:04 +0900 Subject: [PATCH 013/159] clientid --- .../impl/HttpClient5AdapterServiceRest.java | 25 +++++++++++++------ 1 file changed, 17 insertions(+), 8 deletions(-) diff --git a/src/main/java/com/eactive/eai/adapter/http/client/impl/HttpClient5AdapterServiceRest.java b/src/main/java/com/eactive/eai/adapter/http/client/impl/HttpClient5AdapterServiceRest.java index 0db024e..900a82e 100644 --- a/src/main/java/com/eactive/eai/adapter/http/client/impl/HttpClient5AdapterServiceRest.java +++ b/src/main/java/com/eactive/eai/adapter/http/client/impl/HttpClient5AdapterServiceRest.java @@ -821,16 +821,25 @@ public class HttpClient5AdapterServiceRest extends HttpClient5AdapterServiceSupp } } } else if (headerObj instanceof String) { //weblogic - String json = (String) headerObj; - JSONParser parser = new JSONParser(); - JSONObject obj = (JSONObject) parser.parse(json); - for (Object k : obj.keySet()) { - if (((String) k).equalsIgnoreCase("authorization")) { - authorization = (String) obj.get(k); - System.out.println("*** inboundHeaders authorization weblogic:"+authorization); + String str = (String) headerObj; + System.out.println("*** inboundHeaders weblogic str:"+str); + str = str.substring(1, str.length() - 1); + + String[] entries = str.split(","); + + Map map = new HashMap<>(); + for (String entry : entries) { + String[] kv = entry.split("=", 2); + if (kv.length == 2) { + map.put( kv[0].trim(), kv[1].trim()); + } + } + for (String k : map.keySet() ) { + if ( k.equalsIgnoreCase("authorization")) { + authorization = map.get(k); break; } - } + } } } catch (ParseException e) { e.printStackTrace(); From 23eb8ee5cdd451c455ec52fd1e15662902335621 Mon Sep 17 00:00:00 2001 From: 25W0075 <25W0075@P9801Z.kjbank.dom> Date: Thu, 27 Nov 2025 17:48:45 +0900 Subject: [PATCH 014/159] error --- .../adapter/http/client/impl/HttpClient5AdapterServiceRest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/com/eactive/eai/adapter/http/client/impl/HttpClient5AdapterServiceRest.java b/src/main/java/com/eactive/eai/adapter/http/client/impl/HttpClient5AdapterServiceRest.java index 900a82e..c8e23c1 100644 --- a/src/main/java/com/eactive/eai/adapter/http/client/impl/HttpClient5AdapterServiceRest.java +++ b/src/main/java/com/eactive/eai/adapter/http/client/impl/HttpClient5AdapterServiceRest.java @@ -841,7 +841,7 @@ public class HttpClient5AdapterServiceRest extends HttpClient5AdapterServiceSupp } } } - } catch (ParseException e) { + } catch (Exception e) { e.printStackTrace(); } From 2c971ffdd95846c7ff6902da502f30e3cc140c92 Mon Sep 17 00:00:00 2001 From: 25W0075 <25W0075@P9801Z.kjbank.dom> Date: Fri, 28 Nov 2025 14:46:35 +0900 Subject: [PATCH 015/159] debug check --- .../java/com/eactive/eai/inbound/processor/RequestProcessor.java | 1 + 1 file changed, 1 insertion(+) diff --git a/src/main/java/com/eactive/eai/inbound/processor/RequestProcessor.java b/src/main/java/com/eactive/eai/inbound/processor/RequestProcessor.java index 505b4cc..e1ef123 100644 --- a/src/main/java/com/eactive/eai/inbound/processor/RequestProcessor.java +++ b/src/main/java/com/eactive/eai/inbound/processor/RequestProcessor.java @@ -342,6 +342,7 @@ public class RequestProcessor extends RequestProcessorSupport { // 3. EAIMessage Object 생성 String eaiSvcCd = mapper.getEaiSvcCode(standardMessage); + System.out.println("***** eaiSvcCd is"+ eaiSvcCd); String guid = mapper.getGuid(standardMessage); String guidSeq = mapper.getGuidSeq(standardMessage); String returnType = mapper.getSendRecvDivision(standardMessage); // S|R From d6a1fcad25fcd93954225d5eb4880159bd900d48 Mon Sep 17 00:00:00 2001 From: 25W0075 <25W0075@P9801Z.kjbank.dom> Date: Tue, 2 Dec 2025 15:47:29 +0900 Subject: [PATCH 016/159] test --- .../eai/adapter/http/dynamic/HttpDynamicInAdapterManager.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/com/eactive/eai/adapter/http/dynamic/HttpDynamicInAdapterManager.java b/src/main/java/com/eactive/eai/adapter/http/dynamic/HttpDynamicInAdapterManager.java index cba7002..251a9eb 100644 --- a/src/main/java/com/eactive/eai/adapter/http/dynamic/HttpDynamicInAdapterManager.java +++ b/src/main/java/com/eactive/eai/adapter/http/dynamic/HttpDynamicInAdapterManager.java @@ -24,7 +24,7 @@ public class HttpDynamicInAdapterManager implements Lifecycle { private static HttpDynamicInAdapterManager instance = new HttpDynamicInAdapterManager(); - private ConcurrentHashMap adptUriMap = new ConcurrentHashMap(); + public ConcurrentHashMap adptUriMap = new ConcurrentHashMap(); public static HttpDynamicInAdapterManager getInstance() { return instance; From 1811f4a8f511f1f5d86c13d93d4558fe3114e2e4 Mon Sep 17 00:00:00 2001 From: jaewohong Date: Thu, 4 Dec 2025 11:05:06 +0900 Subject: [PATCH 017/159] =?UTF-8?q?EAIMessage=20Object=20=EC=83=9D?= =?UTF-8?q?=EC=84=B1=EB=B6=80=EB=B6=84=EC=97=90=20eaiSvcCd=20=ED=9A=8D?= =?UTF-8?q?=EB=93=9D=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../inbound/processor/RequestProcessor.java | 23 ++++++++++--------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/src/main/java/com/eactive/eai/inbound/processor/RequestProcessor.java b/src/main/java/com/eactive/eai/inbound/processor/RequestProcessor.java index 0e814c3..0dc1a94 100644 --- a/src/main/java/com/eactive/eai/inbound/processor/RequestProcessor.java +++ b/src/main/java/com/eactive/eai/inbound/processor/RequestProcessor.java @@ -121,19 +121,20 @@ public class RequestProcessor extends RequestProcessorSupport { String bidInterface = adptGrpVO.getBidInterface(); String testMasterYn = adptGrpVO.getTestMasterYn(); - // UUID 생성 : UUID = server구분4자리 + UUID + // UUID 생성 : UUID = "-" 없는 32자리 UUID(광주은행 요청) String uuid = ""; + uuid = UUIDGenerator.getUUID().toString().replaceAll("-", ""); - if(instid != null) { - uuid = instid + UUIDGenerator.getUUID(); - if (logger.isDebug()) logger.debug("RequestProcessor] UUID ["+uuid+"]"); - } - else { - String rspErrorCode = "RECEAIIRP030"; - String rspErrorMsg = ErrorCodeHandler.getMessage(rspErrorCode); - if (logger.isError()) logger.error(rspErrorMsg); - throw new RequestProcessorException(rspErrorMsg); - } +// if(instid != null) { +// uuid = instid + UUIDGenerator.getUUID(); +// if (logger.isDebug()) logger.debug("RequestProcessor] UUID ["+uuid+"]"); +// } +// else { +// String rspErrorCode = "RECEAIIRP030"; +// String rspErrorMsg = ErrorCodeHandler.getMessage(rspErrorCode); +// if (logger.isError()) logger.error(rspErrorMsg); +// throw new RequestProcessorException(rspErrorMsg); +// } ProcessVO vo = new ProcessVO(); vo.setAdapterGroupName(adapterGroupName); From 2c9a0a0e952cf8cb639525aa92c0d1b2bbd87af6 Mon Sep 17 00:00:00 2001 From: jaewohong Date: Thu, 4 Dec 2025 11:10:45 +0900 Subject: [PATCH 018/159] =?UTF-8?q?EAIMessage=20Object=20=EC=83=9D?= =?UTF-8?q?=EC=84=B1=20=EB=B6=80=EB=B6=84=EC=97=90=EC=84=9C=20eaiSvcCd=20?= =?UTF-8?q?=ED=9A=8D=EB=93=9D=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/eactive/eai/inbound/processor/RequestProcessor.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/main/java/com/eactive/eai/inbound/processor/RequestProcessor.java b/src/main/java/com/eactive/eai/inbound/processor/RequestProcessor.java index 0dc1a94..750310f 100644 --- a/src/main/java/com/eactive/eai/inbound/processor/RequestProcessor.java +++ b/src/main/java/com/eactive/eai/inbound/processor/RequestProcessor.java @@ -337,7 +337,8 @@ public class RequestProcessor extends RequestProcessorSupport { } // 3. EAIMessage Object 생성 - String eaiSvcCd = mapper.getEaiSvcCode(standardMessage); + //String eaiSvcCd = mapper.getEaiSvcCode(standardMessage); // commnet by jwhong + String eaiSvcCd = prop.getProperty("API_SERVICE_CODE"); String guid = mapper.getGuid(standardMessage); String guidSeq = mapper.getGuidSeq(standardMessage); String returnType = mapper.getSendRecvDivision(standardMessage); // S|R From 65fb26ad810f4f444c508a01164b3191ff4d4430 Mon Sep 17 00:00:00 2001 From: jaewohong Date: Thu, 4 Dec 2025 11:16:02 +0900 Subject: [PATCH 019/159] PUSH --- .../com/eactive/eai/inbound/processor/RequestProcessor.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/main/java/com/eactive/eai/inbound/processor/RequestProcessor.java b/src/main/java/com/eactive/eai/inbound/processor/RequestProcessor.java index 750310f..0dc1a94 100644 --- a/src/main/java/com/eactive/eai/inbound/processor/RequestProcessor.java +++ b/src/main/java/com/eactive/eai/inbound/processor/RequestProcessor.java @@ -337,8 +337,7 @@ public class RequestProcessor extends RequestProcessorSupport { } // 3. EAIMessage Object 생성 - //String eaiSvcCd = mapper.getEaiSvcCode(standardMessage); // commnet by jwhong - String eaiSvcCd = prop.getProperty("API_SERVICE_CODE"); + String eaiSvcCd = mapper.getEaiSvcCode(standardMessage); String guid = mapper.getGuid(standardMessage); String guidSeq = mapper.getGuidSeq(standardMessage); String returnType = mapper.getSendRecvDivision(standardMessage); // S|R From 0eb534fb110c1adff79f2e3c6d308853733fc77f Mon Sep 17 00:00:00 2001 From: jaewohong Date: Thu, 4 Dec 2025 11:28:41 +0900 Subject: [PATCH 020/159] =?UTF-8?q?EAIMessage=20Object=20=EC=83=9D?= =?UTF-8?q?=EC=84=B1=20eaiSvcCd=20=ED=9A=8D=EB=93=9D=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/eactive/eai/inbound/processor/RequestProcessor.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/main/java/com/eactive/eai/inbound/processor/RequestProcessor.java b/src/main/java/com/eactive/eai/inbound/processor/RequestProcessor.java index 0dc1a94..750310f 100644 --- a/src/main/java/com/eactive/eai/inbound/processor/RequestProcessor.java +++ b/src/main/java/com/eactive/eai/inbound/processor/RequestProcessor.java @@ -337,7 +337,8 @@ public class RequestProcessor extends RequestProcessorSupport { } // 3. EAIMessage Object 생성 - String eaiSvcCd = mapper.getEaiSvcCode(standardMessage); + //String eaiSvcCd = mapper.getEaiSvcCode(standardMessage); // commnet by jwhong + String eaiSvcCd = prop.getProperty("API_SERVICE_CODE"); String guid = mapper.getGuid(standardMessage); String guidSeq = mapper.getGuidSeq(standardMessage); String returnType = mapper.getSendRecvDivision(standardMessage); // S|R From d04531886a3d49735843e2d2767183e8e10021c3 Mon Sep 17 00:00:00 2001 From: jaewohong Date: Thu, 4 Dec 2025 11:40:46 +0900 Subject: [PATCH 021/159] =?UTF-8?q?=EC=97=AC=EB=9F=AC=EC=88=98=EC=A0=95=20?= =?UTF-8?q?20251204?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../impl/HttpClient5AdapterServiceRest.java | 91 +++++++++++++------ .../http/dynamic/HttpAdapterServiceKey.java | 2 + .../dynamic/HttpDynamicInAdapterManager.java | 4 +- .../com/eactive/eai/outbound/RESTProcess.java | 1 + 4 files changed, 67 insertions(+), 31 deletions(-) diff --git a/src/main/java/com/eactive/eai/adapter/http/client/impl/HttpClient5AdapterServiceRest.java b/src/main/java/com/eactive/eai/adapter/http/client/impl/HttpClient5AdapterServiceRest.java index 2c8043f..b033323 100644 --- a/src/main/java/com/eactive/eai/adapter/http/client/impl/HttpClient5AdapterServiceRest.java +++ b/src/main/java/com/eactive/eai/adapter/http/client/impl/HttpClient5AdapterServiceRest.java @@ -367,7 +367,9 @@ public class HttpClient5AdapterServiceRest extends HttpClient5AdapterServiceSupp case POST: // assignPostBody(dataObject, contentType, vo.getEncode(), method); //assignPostBody(dataContent, contentType, vo.getEncode(), method); // jwhong commnet - assignPostBody(dataContent, contentType, vo.getEncode(), method, vo.getAdapterName(), auth); + // KJBank API 추적정보를 Header에 제공. jwhong + String inboundToken= assignRequestKJHeaders(method, prop, tempProp ); + assignPostBody(dataContent, contentType, vo.getEncode(), method, vo.getAdapterName(), auth, inboundToken); break; default: break; @@ -385,7 +387,7 @@ public class HttpClient5AdapterServiceRest extends HttpClient5AdapterServiceSupp assignRequestHeaders(method, httpHeader); // KJBank API 추적정보를 Header에 제공. jwhong - assignRequestKJHeaders(method, prop, tempProp ); + //assignRequestKJHeaders(method, prop, tempProp ); int status = -1; @@ -799,26 +801,48 @@ public class HttpClient5AdapterServiceRest extends HttpClient5AdapterServiceSupp } /* - * KJBank Target System으로 요청 보낼때 header에 clientId(업체정보), APIM거래추적자(UUID), 최초 요청시간 을 보낸다. jwhong + * KJBank Target System으로 요청 보낼때 header에 clientId(업체정보), APIM거래추적자(UUID), 최초 요청시간, guid 추가해서 보낸다. jwhong */ - private void assignRequestKJHeaders(HttpUriRequestBase method, Properties prop, Properties tempProp) { + private String assignRequestKJHeaders(HttpUriRequestBase method, Properties prop, Properties tempProp){ //weblogic 에서는 tempProp.get 이 property로 return 해어 아래처럼 수정함. ClassCastException 발생함. //Properties inboundHeaders = (Properties) tempProp.get(HttpAdapterServiceKey.INBOUND_HEADER); Properties inboundHeaders = null; + String authorization =""; try { Object headerObj = tempProp.get(HttpAdapterServiceKey.INBOUND_HEADER); if (headerObj instanceof Properties) { //tomcat inboundHeaders = (Properties) headerObj; + for ( String k : inboundHeaders.stringPropertyNames()) { + if(k.equalsIgnoreCase("authorization")) { + authorization = inboundHeaders.getProperty(k); + break; + } + } } else if (headerObj instanceof String) { //weblogic - inboundHeaders = new Properties(); - inboundHeaders.load(new StringReader((String) headerObj)); + String str = (String) headerObj; + str = str.substring(1, str.length() - 1); + // 2. key=value 쌍 분리 + String[] entries = str.split(","); + // map에 담기 + Map map = new HashMap<>(); + for (String entry : entries) { + String[] kv = entry.split("=", 2); + if (kv.length == 2) { + map.put(kv[0].trim(), kv[1].trim()); + } + } + for (String k : map.keySet()) { + if (k.equalsIgnoreCase("authorization")) { + authorization = map.get(k); + break; + } + } } - } catch (IOException e) { + } catch (Exception e) { e.printStackTrace(); } - String authorization = inboundHeaders.getProperty("authorization"); String jwtToken = ""; if (authorization != null && authorization.startsWith("Bearer ")) { @@ -832,22 +856,20 @@ public class HttpClient5AdapterServiceRest extends HttpClient5AdapterServiceSupp /* APIM 거래추적자 */ String uuid = tempProp.getProperty(TransactionContextKeys.TRANSACTION_UUID, ""); method.setHeader("traceId", uuid); - - /* - Set keys = tempProp.stringPropertyNames(); - for (String key : keys) { - String value = tempProp.getProperty(key); - logger.debug(key + " = " + value); - } - */ - + + /* GUID */ + String guid = tempProp.getProperty(TransactionContextKeys.GUID, ""); + method.setHeader("guid", guid); + /* 최초요청시간 */ String receivedTimestamp = tempProp.getProperty(HttpAdapterServiceKey.INBOUND_REQUESTED_TIME, ""); method.setHeader("receivedTimestamp", receivedTimestamp); + + return jwtToken; } @SuppressWarnings("deprecation") - private void assignPostBody(Object eaiBody, String contentType, String charset, HttpUriRequestBase method, String adapterName, String niceAuth) { + private void assignPostBody(Object eaiBody, String contentType, String charset, HttpUriRequestBase method, String adapterName, String niceAuth, String inboundToken) { if (eaiBody == null) { return; } @@ -868,7 +890,7 @@ public class HttpClient5AdapterServiceRest extends HttpClient5AdapterServiceSupp } else { ContentType contentTypeObj = ContentType.create(contentType, charset); - String eaiBodyMessage = doOutboundPreFilter(eaiBody, adapterName, niceAuth); // jwhong + String eaiBodyMessage = doOutboundPreFilter(eaiBody, adapterName, niceAuth, inboundToken); // jwhong StringEntity entity = new StringEntity(eaiBodyMessage, contentTypeObj); // 요청 본문을 StringEntity 객체로 생성 //StringEntity entity = new StringEntity(eaiBody.toString(), contentTypeObj); @@ -879,27 +901,32 @@ public class HttpClient5AdapterServiceRest extends HttpClient5AdapterServiceSupp } // from here by jwhong - private String doOutboundPreFilter(Object eaiBody, String adapterName, String niceAuth) { + private String doOutboundPreFilter(Object eaiBody, String adapterName, String niceAuth, String inboundToken) { Properties properties = AdapterPropManager.getInstance().getProperties(adapterName); // jwhong String encryptAlgorithm = properties.getProperty("ENCRYPT_ALGORITHM",""); // jwhong - //String encryptBaseKeyType = properties.getProperty("ENCRYPT_BASE_TYPE"); + String encryptBaseKeyType = properties.getProperty("ENCRYPT_BASE_TYPE"); String encryptClientId = properties.getProperty("ENCRYPT_CLIENT_ID"); String encryptAES256Iv = properties.getProperty("ENCRYPT_AES256_IV"); String encryptAES256Key = properties.getProperty("ENCRYPT_AES256_KEY"); String certPath = properties.getProperty("ENCRYPT_CERT_PATH"); // outbound encrypt 는 SecretKey 또는 NICE-auth 가 암호화 key로 사용된다. + // outbound 알림결과는 SecretKey, NICE-auth, Token을 사용한다. // 참고로 inbound encrypt 에는 Token 또는 SecretKey 가 암호화 key로 사용된다. - // 여기에 NICE-auth 뭔지 파악하여 logic 추가해야 한다. - OAuth2Manager manager = OAuth2Manager.getInstance(); - ClientDetails clientDetail = manager.getClientDeatilsStore().get(encryptClientId); - String clientSecret = ""; - if ( clientDetail != null ) { // not null 이라는 것은 APIM Oauth Server에 등록된 client ID 이다. - // 이건 KJBank로 Outbound 나가는 것임 - clientSecret = clientDetail.getClientSecret(); - } else { // 그럼 업체로 Outbound 나가는것은, 업체에서 사용하는 secretkey를 사용한다. - clientSecret = encryptClientId; + // 여기에 NICE-auth logic 추가함 . + String clientSecret = ""; + if ("TOKEN".equalsIgnoreCase(encryptBaseKeyType)) { + clientSecret = inboundToken; + } else if ( "SECRETKEY".equalsIgnoreCase(encryptBaseKeyType)) { + OAuth2Manager manager = OAuth2Manager.getInstance(); + ClientDetails clientDetail = manager.getClientDeatilsStore().get(encryptClientId); + if ( clientDetail != null ) { // not null 이라는 것은 APIM Oauth Server에 등록된 client ID 이다. + // 업체가 우리 OAuth 를 사용하는 경우임 + clientSecret = clientDetail.getClientSecret(); + } else { // 이경우는 우리 OAuth를 사용안하는 경우임, 업체에서 사용하는 secretkey를 사용한다. + clientSecret = encryptClientId; + } } // Nice-auth , token 값을 substring 해서 사용한다. 나이스 지키미는 adapter token에서 추출된 token을 사용한다. @@ -910,6 +937,7 @@ public class HttpClient5AdapterServiceRest extends HttpClient5AdapterServiceSupp // 여기서 SECRETY인지 nice-auth 인지 check 하여 clientSecret 값을 정하는 logic 추가하여 넘겨야한다. String responseMessage = doOutboundPreEncrypt(eaiBody, encryptAlgorithm, clientSecret, encryptAES256Iv, encryptAES256Key, certPath); + logger.debug("outbound pre encrypte value is :"+responseMessage); return responseMessage; } @@ -924,6 +952,7 @@ public class HttpClient5AdapterServiceRest extends HttpClient5AdapterServiceSupp case "AES": encryptedMessage = encrypt(eaiBody.toString()); // encrypt by jwhong break; + case "AES128": case "AES128-TOSS": try { String key = clientSecretKey.substring(22,38); @@ -1089,6 +1118,7 @@ public class HttpClient5AdapterServiceRest extends HttpClient5AdapterServiceSupp case "AES": decryptedMessage = decrypt(eaiBody); // encrypt by jwhong break; + case "AES128": case "AES128-TOSS": try { String key128 = clientSecretKey.substring(22,38); @@ -1199,6 +1229,7 @@ public class HttpClient5AdapterServiceRest extends HttpClient5AdapterServiceSupp String jsonKey = ""; switch (Algorithm) { + case "AES128": case "AES128-TOSS": jsonKey = "preScreeningRequest"; break; diff --git a/src/main/java/com/eactive/eai/adapter/http/dynamic/HttpAdapterServiceKey.java b/src/main/java/com/eactive/eai/adapter/http/dynamic/HttpAdapterServiceKey.java index 257f70f..44d664b 100644 --- a/src/main/java/com/eactive/eai/adapter/http/dynamic/HttpAdapterServiceKey.java +++ b/src/main/java/com/eactive/eai/adapter/http/dynamic/HttpAdapterServiceKey.java @@ -78,6 +78,8 @@ public interface HttpAdapterServiceKey { static final String ENCRYPT_AES256_IV = "ENCRYPT_AES256_IV"; // jwhong static final String ENCRYPT_AES256_KEY = "ENCRYPT_AES256_KEY"; // jwhong static final String INBOUND_REQUESTED_TIME = "INBOUND_REQUESTED_TIME"; // jwhong + static final String GUID = "GUID"; // jwhong + static final String API_SERVICE_CODE = "API_SERVICE_CODE"; // jwhong //응답 처리 용 표준 전문 오브젝트 static final String STANDARD_MESSAGE_OBJECT = "STANDARD_MESSAGE_OBJECT"; diff --git a/src/main/java/com/eactive/eai/adapter/http/dynamic/HttpDynamicInAdapterManager.java b/src/main/java/com/eactive/eai/adapter/http/dynamic/HttpDynamicInAdapterManager.java index cba7002..979052a 100644 --- a/src/main/java/com/eactive/eai/adapter/http/dynamic/HttpDynamicInAdapterManager.java +++ b/src/main/java/com/eactive/eai/adapter/http/dynamic/HttpDynamicInAdapterManager.java @@ -24,8 +24,10 @@ public class HttpDynamicInAdapterManager implements Lifecycle { private static HttpDynamicInAdapterManager instance = new HttpDynamicInAdapterManager(); - private ConcurrentHashMap adptUriMap = new ConcurrentHashMap(); + //private ConcurrentHashMap adptUriMap = new ConcurrentHashMap(); + public ConcurrentHashMap adptUriMap = new ConcurrentHashMap(); + public static HttpDynamicInAdapterManager getInstance() { return instance; } diff --git a/src/main/java/com/eactive/eai/outbound/RESTProcess.java b/src/main/java/com/eactive/eai/outbound/RESTProcess.java index 9d739f6..77e1d9d 100644 --- a/src/main/java/com/eactive/eai/outbound/RESTProcess.java +++ b/src/main/java/com/eactive/eai/outbound/RESTProcess.java @@ -440,6 +440,7 @@ public class RESTProcess extends HTTPProcess { PropertiesUtil.copyPropertyIfPresent(this.callProp, this.tempProp, HttpAdapterServiceKey.INBOUND_REMOTE_ADDR); PropertiesUtil.copyPropertyIfPresent(this.callProp, this.tempProp, HttpAdapterServiceKey.INBOUND_SCHEME); PropertiesUtil.copyPropertyIfPresent(this.callProp, this.tempProp, HttpAdapterServiceKey.INBOUND_REQUESTED_TIME); // jwhong + PropertiesUtil.copyPropertyIfPresent(this.callProp, this.tempProp, HttpAdapterServiceKey.GUID); // jwhong String svcName = getServiceId(this.reqEaiMsg); if (svcName == null) { From 25acf1873f515080a8e5dbd869bcc99cc7c4612d Mon Sep 17 00:00:00 2001 From: "Yunsam.Eo" Date: Fri, 5 Dec 2025 09:24:42 +0900 Subject: [PATCH 022/159] =?UTF-8?q?Http=20Adapter=20Extra=20Log=20-=20Head?= =?UTF-8?q?er=EC=B2=98=EB=A6=AC=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../logger/HttpAdapterExtraHeaderVo.java | 6 +- .../common/logger/HttpAdapterExtraLogVo.java | 1 + .../async/HttpAdapterExtraLogH2Factory.java | 4 +- .../mapper/HttpAdapterExtraHeaderMapper.java | 44 +++++----- .../mapper/HttpAdapterExtraLogMapper.java | 80 ++++++++++++++----- .../common/util/HttpAdapterExtraLogUtil.java | 2 +- 6 files changed, 90 insertions(+), 47 deletions(-) diff --git a/src/main/java/com/eactive/eai/common/logger/HttpAdapterExtraHeaderVo.java b/src/main/java/com/eactive/eai/common/logger/HttpAdapterExtraHeaderVo.java index 975f134..cce3a62 100644 --- a/src/main/java/com/eactive/eai/common/logger/HttpAdapterExtraHeaderVo.java +++ b/src/main/java/com/eactive/eai/common/logger/HttpAdapterExtraHeaderVo.java @@ -2,11 +2,15 @@ package com.eactive.eai.common.logger; import lombok.AllArgsConstructor; import lombok.Data; +import lombok.NoArgsConstructor; @Data @AllArgsConstructor public class HttpAdapterExtraHeaderVo { private String name; - private String value; + + public HttpAdapterExtraHeaderVo() { + + } } diff --git a/src/main/java/com/eactive/eai/common/logger/HttpAdapterExtraLogVo.java b/src/main/java/com/eactive/eai/common/logger/HttpAdapterExtraLogVo.java index 4dcb0ac..318c57c 100644 --- a/src/main/java/com/eactive/eai/common/logger/HttpAdapterExtraLogVo.java +++ b/src/main/java/com/eactive/eai/common/logger/HttpAdapterExtraLogVo.java @@ -8,6 +8,7 @@ import java.util.List; public class HttpAdapterExtraLogVo { private String guid; private int serviceProcessNumber; + private String prcsDate; private String adapterGroupName; private String adapterName; private String url; diff --git a/src/main/java/com/eactive/eai/common/logger/async/HttpAdapterExtraLogH2Factory.java b/src/main/java/com/eactive/eai/common/logger/async/HttpAdapterExtraLogH2Factory.java index 7eb5292..93d9150 100644 --- a/src/main/java/com/eactive/eai/common/logger/async/HttpAdapterExtraLogH2Factory.java +++ b/src/main/java/com/eactive/eai/common/logger/async/HttpAdapterExtraLogH2Factory.java @@ -3,7 +3,7 @@ package com.eactive.eai.common.logger.async; import com.eactive.eai.common.property.PropManager; import com.eactive.eai.common.server.EAIServerManager; import com.eactive.eai.common.util.LogKeys; -import com.eactive.eai.data.entity.onl.logger.HttpAdapterExtraHeader; +//import com.eactive.eai.data.entity.onl.logger.HttpAdapterExtraHeader; import com.eactive.eai.data.entity.onl.logger.HttpAdapterExtraLog; import com.zaxxer.hikari.HikariConfig; import com.zaxxer.hikari.HikariDataSource; @@ -66,7 +66,7 @@ public class HttpAdapterExtraLogH2Factory { // 엔티티 클래스 추가 configuration.addAnnotatedClass(HttpAdapterExtraLog.class); - configuration.addAnnotatedClass(HttpAdapterExtraHeader.class); +// configuration.addAnnotatedClass(HttpAdapterExtraHeader.class); return configuration.buildSessionFactory(); } catch (Throwable ex) { diff --git a/src/main/java/com/eactive/eai/common/logger/mapper/HttpAdapterExtraHeaderMapper.java b/src/main/java/com/eactive/eai/common/logger/mapper/HttpAdapterExtraHeaderMapper.java index e6eabe0..b609dee 100644 --- a/src/main/java/com/eactive/eai/common/logger/mapper/HttpAdapterExtraHeaderMapper.java +++ b/src/main/java/com/eactive/eai/common/logger/mapper/HttpAdapterExtraHeaderMapper.java @@ -1,22 +1,22 @@ -package com.eactive.eai.common.logger.mapper; - -import com.eactive.eai.common.logger.HttpAdapterExtraHeaderVo; -import com.eactive.eai.data.entity.onl.logger.HttpAdapterExtraHeader; -import com.eactive.eai.data.mapper.BaseMapperConfig; -import com.eactive.eai.data.mapper.GenericMapper; - -import org.mapstruct.InheritInverseConfiguration; -import org.mapstruct.Mapper; -import org.mapstruct.Mapping; - -@Mapper(config = BaseMapperConfig.class) -public interface HttpAdapterExtraHeaderMapper extends GenericMapper { - - @Override - @Mapping(source = "id.name", target = "name") - HttpAdapterExtraHeaderVo toVo(HttpAdapterExtraHeader entity); - - @Override - @InheritInverseConfiguration - HttpAdapterExtraHeader toEntity(HttpAdapterExtraHeaderVo vo); -} +//package com.eactive.eai.common.logger.mapper; +// +//import com.eactive.eai.common.logger.HttpAdapterExtraHeaderVo; +//import com.eactive.eai.data.entity.onl.logger.HttpAdapterExtraHeader; +//import com.eactive.eai.data.mapper.BaseMapperConfig; +//import com.eactive.eai.data.mapper.GenericMapper; +// +//import org.mapstruct.InheritInverseConfiguration; +//import org.mapstruct.Mapper; +//import org.mapstruct.Mapping; +// +//@Mapper(config = BaseMapperConfig.class) +//public interface HttpAdapterExtraHeaderMapper extends GenericMapper { +// +// @Override +// @Mapping(source = "id.name", target = "name") +// HttpAdapterExtraHeaderVo toVo(HttpAdapterExtraHeader entity); +// +// @Override +// @InheritInverseConfiguration +// HttpAdapterExtraHeader toEntity(HttpAdapterExtraHeaderVo vo); +//} diff --git a/src/main/java/com/eactive/eai/common/logger/mapper/HttpAdapterExtraLogMapper.java b/src/main/java/com/eactive/eai/common/logger/mapper/HttpAdapterExtraLogMapper.java index 73ba243..002e401 100644 --- a/src/main/java/com/eactive/eai/common/logger/mapper/HttpAdapterExtraLogMapper.java +++ b/src/main/java/com/eactive/eai/common/logger/mapper/HttpAdapterExtraLogMapper.java @@ -1,42 +1,80 @@ package com.eactive.eai.common.logger.mapper; +import com.eactive.eai.common.logger.HttpAdapterExtraHeaderVo; import com.eactive.eai.common.logger.HttpAdapterExtraLogVo; -import com.eactive.eai.data.entity.onl.logger.HttpAdapterExtraHeaderId; import com.eactive.eai.data.entity.onl.logger.HttpAdapterExtraLog; import com.eactive.eai.data.mapper.BaseMapperConfig; import com.eactive.eai.data.mapper.GenericMapper; - +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.core.type.TypeReference; +import com.fasterxml.jackson.databind.ObjectMapper; +import lombok.extern.slf4j.Slf4j; import org.mapstruct.*; -import java.time.DayOfWeek; import java.time.LocalDate; -import java.util.Optional; +import java.time.format.DateTimeFormatter; +import java.util.Collections; +import java.util.List; -@Mapper(config = BaseMapperConfig.class, uses = HttpAdapterExtraHeaderMapper.class) -public interface HttpAdapterExtraLogMapper extends GenericMapper { +@Slf4j +@Mapper(config = BaseMapperConfig.class) +public abstract class HttpAdapterExtraLogMapper implements GenericMapper { + + private final static ObjectMapper objectMapper = new ObjectMapper(); + private static final DateTimeFormatter SDF_YYYYMMDD = DateTimeFormatter.ofPattern( "yyyyMMdd"); @Override @Mapping(source = "id.guid", target = "guid") @Mapping(source = "id.serviceProcessNumber", target = "serviceProcessNumber") - HttpAdapterExtraLogVo toVo(HttpAdapterExtraLog entity); + abstract public HttpAdapterExtraLogVo toVo(HttpAdapterExtraLog entity); @Override @InheritInverseConfiguration - HttpAdapterExtraLog toEntity(HttpAdapterExtraLogVo vo); + abstract public HttpAdapterExtraLog toEntity(HttpAdapterExtraLogVo vo); @AfterMapping - default void setHeaderIdAndWeekday(@MappingTarget HttpAdapterExtraLog entity, HttpAdapterExtraLogVo vo) { - DayOfWeek dayOfWeek = LocalDate.now().getDayOfWeek(); // 현재 요일 - int dayOfWeekNumber = dayOfWeek.getValue() % 7 + 1; // 1 (일요일)부터 7 (토요일)까지 - entity.getId().setWeekday(dayOfWeekNumber); - Optional.ofNullable(entity.getHeaderList()) - .ifPresent(headers -> headers.forEach(header -> { - if (header.getId() == null) { - header.setId(new HttpAdapterExtraHeaderId()); - } - header.getId().setWeekday(dayOfWeekNumber); - header.getId().setGuid(vo.getGuid()); - header.getId().setServiceProcessNumber(vo.getServiceProcessNumber()); - })); + public void voToEntity(@MappingTarget HttpAdapterExtraLog entity, HttpAdapterExtraLogVo vo) { + + // 1. Set weekday for partition table +// DayOfWeek dayOfWeek = LocalDate.now().getDayOfWeek(); // 현재 요일 +// int dayOfWeekNumber = dayOfWeek.getValue() % 7 + 1; // 1 (일요일)부터 7 (토요일)까지 +// entity.getId().setWeekday(dayOfWeekNumber); + +// String prcs_date = SDF_YYYYMMDD.format(ZonedDateTime.now()); + String prcs_date = LocalDate.now().format(SDF_YYYYMMDD); + entity.getId().setPrcsDate(prcs_date); + + // 2. Set Content + try { + String headerContent = objectMapper.writeValueAsString(vo.getHeaderList()); + entity.setHeaderContent(headerContent); + } catch (JsonProcessingException e) { + log.warn("Http Header Json Parse 실패", e); + entity.setHeaderContent("[{ \"error\": \"parse error\"}]"); + } + + } + + /** + * Entity → VO 변환 후 추가 처리 + */ + @AfterMapping + protected void entityToVo(@MappingTarget HttpAdapterExtraLogVo vo, HttpAdapterExtraLog entity) { + String headerContent = entity.getHeaderContent(); + if (headerContent == null || headerContent.isEmpty()) { + vo.setHeaderList(Collections.emptyList()); + return; + } + + try { + List headerList = objectMapper.readValue( + headerContent, + new TypeReference>() {} + ); + vo.setHeaderList(headerList); + } catch (JsonProcessingException e) { + log.warn("Http Header 역직렬화 실패", e); + vo.setHeaderList(Collections.emptyList()); + } } } diff --git a/src/main/java/com/eactive/eai/common/util/HttpAdapterExtraLogUtil.java b/src/main/java/com/eactive/eai/common/util/HttpAdapterExtraLogUtil.java index 8251e53..75f405c 100644 --- a/src/main/java/com/eactive/eai/common/util/HttpAdapterExtraLogUtil.java +++ b/src/main/java/com/eactive/eai/common/util/HttpAdapterExtraLogUtil.java @@ -101,7 +101,7 @@ public class HttpAdapterExtraLogUtil { public static List convertHeaderToListOfHttpAdapterExtraHeaderVo(Header[] headers) { Set seenNames = new HashSet<>(); return Arrays.stream(headers) - .filter(header -> seenNames.add(header.getName())) // 중복된 이름을 스킵 +// .filter(header -> seenNames.add(header.getName())) // 중복된 이름을 스킵 .map(header -> new HttpAdapterExtraHeaderVo(header.getName(), header.getValue())) .collect(Collectors.toList()); } From 3329291b178469f7c5b108fa440b88ee6c9f6442 Mon Sep 17 00:00:00 2001 From: jaewohong Date: Fri, 5 Dec 2025 14:18:56 +0900 Subject: [PATCH 023/159] =?UTF-8?q?=EC=9B=90=EA=B2=A9=20=EB=B8=8C=EB=9E=9C?= =?UTF-8?q?=EC=B9=98=EC=97=90=EC=84=9C=20online-common=20=EA=B4=80?= =?UTF-8?q?=EB=A0=A8=20=ED=8C=8C=EC=9D=BC=20=EA=B0=80=EC=A0=B8=EC=98=A4?= =?UTF-8?q?=EA=B8=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...HttpClientAccessTokenServiceWithParam.java | 11 ++- .../logger/HttpAdapterExtraHeaderVo.java | 6 +- .../common/logger/HttpAdapterExtraLogVo.java | 1 + .../async/HttpAdapterExtraLogH2Factory.java | 4 +- .../mapper/HttpAdapterExtraHeaderMapper.java | 44 +++++----- .../mapper/HttpAdapterExtraLogMapper.java | 80 ++++++++++++++----- .../common/util/HttpAdapterExtraLogUtil.java | 2 +- 7 files changed, 99 insertions(+), 49 deletions(-) diff --git a/src/main/java/com/eactive/eai/authoutbound/client/impl/HttpClientAccessTokenServiceWithParam.java b/src/main/java/com/eactive/eai/authoutbound/client/impl/HttpClientAccessTokenServiceWithParam.java index 3772406..45e7c60 100644 --- a/src/main/java/com/eactive/eai/authoutbound/client/impl/HttpClientAccessTokenServiceWithParam.java +++ b/src/main/java/com/eactive/eai/authoutbound/client/impl/HttpClientAccessTokenServiceWithParam.java @@ -51,7 +51,7 @@ import com.openbanking.eai.common.token.AccessTokenVO; import com.openbanking.eai.common.token.OAuth2AccessTokenVO; import org.springframework.security.web.util.UrlUtils; -/** +/** * 1. 기능 : HTTP 웹 컴포넌트를 POST 방식으로 호출할 수 있는 기능을 제공한다. 2. 처리 개요 : * - 2009.11.24 * retry 로직 제거 : 요청 3. 주의사항 * @@ -224,17 +224,20 @@ public class HttpClientAccessTokenServiceWithParam implements HttpClientAccessTo logger.debug("contentType = [" + contentType + "]"); logger.debug("encode = [" + encode + "]"); + OAuth2AccessTokenVO accessToken = new OAuth2AccessTokenVO(); try (CloseableHttpResponse response = httpClient.execute(httpPost)) { if (response.getCode() != 200) { + System.out.println("OAuth token receive status fail value= "+ response.getCode()); throw new Exception("OAuth token receive status fail value= " + response.getCode()); } + System.out.println("OAuth token receive status SUCCESS value= "+ response.getCode()); HttpEntity entity = response.getEntity(); String responseString = EntityUtils.toString(entity, encode); logger.debug("oauthToken RECV = [" + responseString + "]"); if (StringUtils.isNotBlank(responseString)) { - OAuth2AccessTokenVO accessToken = new OAuth2AccessTokenVO(); + //OAuth2AccessTokenVO accessToken = new OAuth2AccessTokenVO(); ObjectMapper objectMapper = new ObjectMapper(); JsonNode responseJSON = objectMapper.readTree(responseString); @@ -259,6 +262,10 @@ public class HttpClientAccessTokenServiceWithParam implements HttpClientAccessTo } else { throw new Exception("oauth token return null"); } + } catch (Exception e) { + e.printStackTrace(); + logger.error("[HttpClientAccessTokenServiceWithParam] retrieve accessToken exception :" + e.getMessage()); + return accessToken; } } } diff --git a/src/main/java/com/eactive/eai/common/logger/HttpAdapterExtraHeaderVo.java b/src/main/java/com/eactive/eai/common/logger/HttpAdapterExtraHeaderVo.java index 975f134..cce3a62 100644 --- a/src/main/java/com/eactive/eai/common/logger/HttpAdapterExtraHeaderVo.java +++ b/src/main/java/com/eactive/eai/common/logger/HttpAdapterExtraHeaderVo.java @@ -2,11 +2,15 @@ package com.eactive.eai.common.logger; import lombok.AllArgsConstructor; import lombok.Data; +import lombok.NoArgsConstructor; @Data @AllArgsConstructor public class HttpAdapterExtraHeaderVo { private String name; - private String value; + + public HttpAdapterExtraHeaderVo() { + + } } diff --git a/src/main/java/com/eactive/eai/common/logger/HttpAdapterExtraLogVo.java b/src/main/java/com/eactive/eai/common/logger/HttpAdapterExtraLogVo.java index 4dcb0ac..318c57c 100644 --- a/src/main/java/com/eactive/eai/common/logger/HttpAdapterExtraLogVo.java +++ b/src/main/java/com/eactive/eai/common/logger/HttpAdapterExtraLogVo.java @@ -8,6 +8,7 @@ import java.util.List; public class HttpAdapterExtraLogVo { private String guid; private int serviceProcessNumber; + private String prcsDate; private String adapterGroupName; private String adapterName; private String url; diff --git a/src/main/java/com/eactive/eai/common/logger/async/HttpAdapterExtraLogH2Factory.java b/src/main/java/com/eactive/eai/common/logger/async/HttpAdapterExtraLogH2Factory.java index 7eb5292..93d9150 100644 --- a/src/main/java/com/eactive/eai/common/logger/async/HttpAdapterExtraLogH2Factory.java +++ b/src/main/java/com/eactive/eai/common/logger/async/HttpAdapterExtraLogH2Factory.java @@ -3,7 +3,7 @@ package com.eactive.eai.common.logger.async; import com.eactive.eai.common.property.PropManager; import com.eactive.eai.common.server.EAIServerManager; import com.eactive.eai.common.util.LogKeys; -import com.eactive.eai.data.entity.onl.logger.HttpAdapterExtraHeader; +//import com.eactive.eai.data.entity.onl.logger.HttpAdapterExtraHeader; import com.eactive.eai.data.entity.onl.logger.HttpAdapterExtraLog; import com.zaxxer.hikari.HikariConfig; import com.zaxxer.hikari.HikariDataSource; @@ -66,7 +66,7 @@ public class HttpAdapterExtraLogH2Factory { // 엔티티 클래스 추가 configuration.addAnnotatedClass(HttpAdapterExtraLog.class); - configuration.addAnnotatedClass(HttpAdapterExtraHeader.class); +// configuration.addAnnotatedClass(HttpAdapterExtraHeader.class); return configuration.buildSessionFactory(); } catch (Throwable ex) { diff --git a/src/main/java/com/eactive/eai/common/logger/mapper/HttpAdapterExtraHeaderMapper.java b/src/main/java/com/eactive/eai/common/logger/mapper/HttpAdapterExtraHeaderMapper.java index e6eabe0..b609dee 100644 --- a/src/main/java/com/eactive/eai/common/logger/mapper/HttpAdapterExtraHeaderMapper.java +++ b/src/main/java/com/eactive/eai/common/logger/mapper/HttpAdapterExtraHeaderMapper.java @@ -1,22 +1,22 @@ -package com.eactive.eai.common.logger.mapper; - -import com.eactive.eai.common.logger.HttpAdapterExtraHeaderVo; -import com.eactive.eai.data.entity.onl.logger.HttpAdapterExtraHeader; -import com.eactive.eai.data.mapper.BaseMapperConfig; -import com.eactive.eai.data.mapper.GenericMapper; - -import org.mapstruct.InheritInverseConfiguration; -import org.mapstruct.Mapper; -import org.mapstruct.Mapping; - -@Mapper(config = BaseMapperConfig.class) -public interface HttpAdapterExtraHeaderMapper extends GenericMapper { - - @Override - @Mapping(source = "id.name", target = "name") - HttpAdapterExtraHeaderVo toVo(HttpAdapterExtraHeader entity); - - @Override - @InheritInverseConfiguration - HttpAdapterExtraHeader toEntity(HttpAdapterExtraHeaderVo vo); -} +//package com.eactive.eai.common.logger.mapper; +// +//import com.eactive.eai.common.logger.HttpAdapterExtraHeaderVo; +//import com.eactive.eai.data.entity.onl.logger.HttpAdapterExtraHeader; +//import com.eactive.eai.data.mapper.BaseMapperConfig; +//import com.eactive.eai.data.mapper.GenericMapper; +// +//import org.mapstruct.InheritInverseConfiguration; +//import org.mapstruct.Mapper; +//import org.mapstruct.Mapping; +// +//@Mapper(config = BaseMapperConfig.class) +//public interface HttpAdapterExtraHeaderMapper extends GenericMapper { +// +// @Override +// @Mapping(source = "id.name", target = "name") +// HttpAdapterExtraHeaderVo toVo(HttpAdapterExtraHeader entity); +// +// @Override +// @InheritInverseConfiguration +// HttpAdapterExtraHeader toEntity(HttpAdapterExtraHeaderVo vo); +//} diff --git a/src/main/java/com/eactive/eai/common/logger/mapper/HttpAdapterExtraLogMapper.java b/src/main/java/com/eactive/eai/common/logger/mapper/HttpAdapterExtraLogMapper.java index 73ba243..002e401 100644 --- a/src/main/java/com/eactive/eai/common/logger/mapper/HttpAdapterExtraLogMapper.java +++ b/src/main/java/com/eactive/eai/common/logger/mapper/HttpAdapterExtraLogMapper.java @@ -1,42 +1,80 @@ package com.eactive.eai.common.logger.mapper; +import com.eactive.eai.common.logger.HttpAdapterExtraHeaderVo; import com.eactive.eai.common.logger.HttpAdapterExtraLogVo; -import com.eactive.eai.data.entity.onl.logger.HttpAdapterExtraHeaderId; import com.eactive.eai.data.entity.onl.logger.HttpAdapterExtraLog; import com.eactive.eai.data.mapper.BaseMapperConfig; import com.eactive.eai.data.mapper.GenericMapper; - +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.core.type.TypeReference; +import com.fasterxml.jackson.databind.ObjectMapper; +import lombok.extern.slf4j.Slf4j; import org.mapstruct.*; -import java.time.DayOfWeek; import java.time.LocalDate; -import java.util.Optional; +import java.time.format.DateTimeFormatter; +import java.util.Collections; +import java.util.List; -@Mapper(config = BaseMapperConfig.class, uses = HttpAdapterExtraHeaderMapper.class) -public interface HttpAdapterExtraLogMapper extends GenericMapper { +@Slf4j +@Mapper(config = BaseMapperConfig.class) +public abstract class HttpAdapterExtraLogMapper implements GenericMapper { + + private final static ObjectMapper objectMapper = new ObjectMapper(); + private static final DateTimeFormatter SDF_YYYYMMDD = DateTimeFormatter.ofPattern( "yyyyMMdd"); @Override @Mapping(source = "id.guid", target = "guid") @Mapping(source = "id.serviceProcessNumber", target = "serviceProcessNumber") - HttpAdapterExtraLogVo toVo(HttpAdapterExtraLog entity); + abstract public HttpAdapterExtraLogVo toVo(HttpAdapterExtraLog entity); @Override @InheritInverseConfiguration - HttpAdapterExtraLog toEntity(HttpAdapterExtraLogVo vo); + abstract public HttpAdapterExtraLog toEntity(HttpAdapterExtraLogVo vo); @AfterMapping - default void setHeaderIdAndWeekday(@MappingTarget HttpAdapterExtraLog entity, HttpAdapterExtraLogVo vo) { - DayOfWeek dayOfWeek = LocalDate.now().getDayOfWeek(); // 현재 요일 - int dayOfWeekNumber = dayOfWeek.getValue() % 7 + 1; // 1 (일요일)부터 7 (토요일)까지 - entity.getId().setWeekday(dayOfWeekNumber); - Optional.ofNullable(entity.getHeaderList()) - .ifPresent(headers -> headers.forEach(header -> { - if (header.getId() == null) { - header.setId(new HttpAdapterExtraHeaderId()); - } - header.getId().setWeekday(dayOfWeekNumber); - header.getId().setGuid(vo.getGuid()); - header.getId().setServiceProcessNumber(vo.getServiceProcessNumber()); - })); + public void voToEntity(@MappingTarget HttpAdapterExtraLog entity, HttpAdapterExtraLogVo vo) { + + // 1. Set weekday for partition table +// DayOfWeek dayOfWeek = LocalDate.now().getDayOfWeek(); // 현재 요일 +// int dayOfWeekNumber = dayOfWeek.getValue() % 7 + 1; // 1 (일요일)부터 7 (토요일)까지 +// entity.getId().setWeekday(dayOfWeekNumber); + +// String prcs_date = SDF_YYYYMMDD.format(ZonedDateTime.now()); + String prcs_date = LocalDate.now().format(SDF_YYYYMMDD); + entity.getId().setPrcsDate(prcs_date); + + // 2. Set Content + try { + String headerContent = objectMapper.writeValueAsString(vo.getHeaderList()); + entity.setHeaderContent(headerContent); + } catch (JsonProcessingException e) { + log.warn("Http Header Json Parse 실패", e); + entity.setHeaderContent("[{ \"error\": \"parse error\"}]"); + } + + } + + /** + * Entity → VO 변환 후 추가 처리 + */ + @AfterMapping + protected void entityToVo(@MappingTarget HttpAdapterExtraLogVo vo, HttpAdapterExtraLog entity) { + String headerContent = entity.getHeaderContent(); + if (headerContent == null || headerContent.isEmpty()) { + vo.setHeaderList(Collections.emptyList()); + return; + } + + try { + List headerList = objectMapper.readValue( + headerContent, + new TypeReference>() {} + ); + vo.setHeaderList(headerList); + } catch (JsonProcessingException e) { + log.warn("Http Header 역직렬화 실패", e); + vo.setHeaderList(Collections.emptyList()); + } } } diff --git a/src/main/java/com/eactive/eai/common/util/HttpAdapterExtraLogUtil.java b/src/main/java/com/eactive/eai/common/util/HttpAdapterExtraLogUtil.java index 8251e53..75f405c 100644 --- a/src/main/java/com/eactive/eai/common/util/HttpAdapterExtraLogUtil.java +++ b/src/main/java/com/eactive/eai/common/util/HttpAdapterExtraLogUtil.java @@ -101,7 +101,7 @@ public class HttpAdapterExtraLogUtil { public static List convertHeaderToListOfHttpAdapterExtraHeaderVo(Header[] headers) { Set seenNames = new HashSet<>(); return Arrays.stream(headers) - .filter(header -> seenNames.add(header.getName())) // 중복된 이름을 스킵 +// .filter(header -> seenNames.add(header.getName())) // 중복된 이름을 스킵 .map(header -> new HttpAdapterExtraHeaderVo(header.getName(), header.getValue())) .collect(Collectors.toList()); } From e4d59f3d3681ccd0b143a3ab1538a1c984d1a75f Mon Sep 17 00:00:00 2001 From: jaewohong Date: Fri, 5 Dec 2025 14:52:41 +0900 Subject: [PATCH 024/159] push for source sync --- .../adapter/http/client/impl/HttpClient5AdapterServiceRest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/com/eactive/eai/adapter/http/client/impl/HttpClient5AdapterServiceRest.java b/src/main/java/com/eactive/eai/adapter/http/client/impl/HttpClient5AdapterServiceRest.java index b033323..fd923cd 100644 --- a/src/main/java/com/eactive/eai/adapter/http/client/impl/HttpClient5AdapterServiceRest.java +++ b/src/main/java/com/eactive/eai/adapter/http/client/impl/HttpClient5AdapterServiceRest.java @@ -934,7 +934,7 @@ public class HttpClient5AdapterServiceRest extends HttpClient5AdapterServiceSupp clientSecret = niceAuth; } - // 여기서 SECRETY인지 nice-auth 인지 check 하여 clientSecret 값을 정하는 logic 추가하여 넘겨야한다. + // 여기서 SECRETY인지 nice-auth 인지 check 하여 clientSecret 값을 정하는 logic 추가하여 넘겨야한다. String responseMessage = doOutboundPreEncrypt(eaiBody, encryptAlgorithm, clientSecret, encryptAES256Iv, encryptAES256Key, certPath); logger.debug("outbound pre encrypte value is :"+responseMessage); From 0b60ac48fd6be9312feefb45b0284e6795650df9 Mon Sep 17 00:00:00 2001 From: jaewohong Date: Fri, 5 Dec 2025 17:38:36 +0900 Subject: [PATCH 025/159] sync2 --- .../http/client/impl/HttpClient5AdapterServiceRest.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/eactive/eai/adapter/http/client/impl/HttpClient5AdapterServiceRest.java b/src/main/java/com/eactive/eai/adapter/http/client/impl/HttpClient5AdapterServiceRest.java index fd923cd..6a91999 100644 --- a/src/main/java/com/eactive/eai/adapter/http/client/impl/HttpClient5AdapterServiceRest.java +++ b/src/main/java/com/eactive/eai/adapter/http/client/impl/HttpClient5AdapterServiceRest.java @@ -1,4 +1,4 @@ -package com.eactive.eai.adapter.http.client.impl; +package com.eactive.eai.adapter.http.client.impl; import java.io.IOException; import java.io.StringReader; @@ -380,7 +380,7 @@ public class HttpClient5AdapterServiceRest extends HttpClient5AdapterServiceSupp + method.getEntity() + "] "); } - // OAuth2AccessToken 원래 있던 위치 JWHONG + // OAuth2AccessToken 원래 있던 위치 JWHONG // 전달 header 셋팅 // Adapter 레벨 header 보다 data로 넘어온 httpHeader를 우선 적용(header명이 같다면 덮어씀) From 1a6bf8135d918e31b7c0bc29d943e0eae07f2266 Mon Sep 17 00:00:00 2001 From: jaewohong Date: Fri, 5 Dec 2025 17:43:21 +0900 Subject: [PATCH 026/159] push2 --- .../adapter/http/client/impl/HttpClient5AdapterServiceRest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/com/eactive/eai/adapter/http/client/impl/HttpClient5AdapterServiceRest.java b/src/main/java/com/eactive/eai/adapter/http/client/impl/HttpClient5AdapterServiceRest.java index 6a91999..dff222c 100644 --- a/src/main/java/com/eactive/eai/adapter/http/client/impl/HttpClient5AdapterServiceRest.java +++ b/src/main/java/com/eactive/eai/adapter/http/client/impl/HttpClient5AdapterServiceRest.java @@ -814,7 +814,7 @@ public class HttpClient5AdapterServiceRest extends HttpClient5AdapterServiceSupp if (headerObj instanceof Properties) { //tomcat inboundHeaders = (Properties) headerObj; for ( String k : inboundHeaders.stringPropertyNames()) { - if(k.equalsIgnoreCase("authorization")) { + if(k.equalsIgnoreCase("authorization")) { authorization = inboundHeaders.getProperty(k); break; } From 642af96cf32ad290f723d978a38e3965e1422e08 Mon Sep 17 00:00:00 2001 From: Rinjae Date: Fri, 5 Dec 2025 18:16:03 +0900 Subject: [PATCH 027/159] push --- .../impl/HttpClient5AdapterServiceRest.java | 904 ++++++++---------- 1 file changed, 402 insertions(+), 502 deletions(-) diff --git a/src/main/java/com/eactive/eai/adapter/http/client/impl/HttpClient5AdapterServiceRest.java b/src/main/java/com/eactive/eai/adapter/http/client/impl/HttpClient5AdapterServiceRest.java index a2b6a46..86a47aa 100644 --- a/src/main/java/com/eactive/eai/adapter/http/client/impl/HttpClient5AdapterServiceRest.java +++ b/src/main/java/com/eactive/eai/adapter/http/client/impl/HttpClient5AdapterServiceRest.java @@ -1,4 +1,4 @@ -package com.eactive.eai.adapter.http.client.impl; +package com.eactive.eai.adapter.http.client.impl; import java.io.IOException; import java.io.StringReader; @@ -87,7 +87,6 @@ import java.util.Base64; import com.kjbank.encrypt.exchange.crypto.AES256Cipher; import com.kjbank.encrypt.exchange.crypto.AESCipher; import com.nimbusds.jwt.SignedJWT; -import com.nimbusds.jwt.SignedJWT; import com.kjbank.encrypt.exchange.crypto.AES256GCMCipher; import com.kjbank.encrypt.exchange.crypto.ECDHESA256Cipher; import com.eactive.eai.authserver.service.OAuth2Manager; @@ -106,7 +105,7 @@ import java.util.Set; * @see : HttpClientAdapterServiceFactory.java, * HttpClientAdapterServiceSupport.java * @since : - * + * */ public class HttpClient5AdapterServiceRest extends HttpClient5AdapterServiceSupport implements HttpClientAdapterServiceKey { @@ -118,9 +117,9 @@ public class HttpClient5AdapterServiceRest extends HttpClient5AdapterServiceSupp public static final String HTTP_STATUS = "HTTP_STATUS"; public static final String HEADER_KEYS = "HEADER_KEYS"; public static final String AUTH_TOKEN = "AUTH_TOKEN"; - + public static final String PAYLOAD_PARAM_NAME_CLIENT_ID = "client_id"; // jwhong - + private boolean useAdapterToken; private boolean encryptResponseApply; @@ -166,8 +165,8 @@ public class HttpClient5AdapterServiceRest extends HttpClient5AdapterServiceSupp // 레이아웃 메시지 타입 REST URL 추출 시 활용. Default JSON String messageType = prop.getProperty("MESSAGE_TYPE", MessageType.JSON); String inboundMethod = tempProp.getProperty(HttpAdapterServiceKey.INBOUND_METHOD, "POST"); - - //Outbound 요청에 대한 응답 메시지의 복호화 여부 결정위해 + + //Outbound 요청에 대한 응답 메시지의 복호화 여부 결정위해 jwhong encryptResponseApply = StringUtils.equalsIgnoreCase(prop.getProperty("ENCRYPT_RESPONSE_APPLY", "N"), "Y"); /** @@ -320,17 +319,17 @@ public class HttpClient5AdapterServiceRest extends HttpClient5AdapterServiceSupp Properties properties = AdapterPropManager.getInstance().getProperties(vo.getAdapterName()); // jwhong String encryptAlgorithm = properties.getProperty("ENCRYPT_ALGORITHM"); // jwhong - if (useAdapterToken && "AES256-NICEON".equals(encryptAlgorithm)) { - String niceToken = accessToken.getAccessToken(); - String clientId = JwtClientIdExtractor(niceToken); - long currentTime = System.currentTimeMillis(); - auth = niceToken + ":" + currentTime + ":" + clientId ; - auth = Base64.getEncoder().encodeToString(auth.getBytes("UTF-8")); - - setNiceOnAuthHeaders(method, auth); - } else { + if (useAdapterToken && "AES256-NICEON".equals(encryptAlgorithm)) { + String niceToken = accessToken.getAccessToken(); + String clientId = JwtClientIdExtractor(niceToken); + long currentTime = System.currentTimeMillis(); + auth = niceToken + ":" + currentTime + ":" + clientId ; + auth = Base64.getEncoder().encodeToString(auth.getBytes("UTF-8")); + + setNiceOnAuthHeaders(method, auth); + } else { setAuthHeaders(method, accessToken); // 원래 있던 logic - } + } if (logger.isDebug()) { @@ -342,8 +341,8 @@ public class HttpClient5AdapterServiceRest extends HttpClient5AdapterServiceSupp if(!StringUtils.isBlank(authToken)) { setAuthHeaders(method, authToken); } - // 여기 까지 - + // 여기 까지 + configureHttpClient(requestConfigBuilder, vo, method); switch (HttpMethodType.getValue(rmethod)) { @@ -370,7 +369,7 @@ public class HttpClient5AdapterServiceRest extends HttpClient5AdapterServiceSupp //assignPostBody(dataContent, contentType, vo.getEncode(), method); // jwhong commnet // KJBank API 추적정보를 Header에 제공. jwhong String inboundToken= assignRequestKJHeaders(method, prop, tempProp ); - assignPostBody(dataContent, contentType, vo.getEncode(), method, vo.getAdapterName(), auth, inboundToken); + assignPostBody(dataContent, contentType, vo.getEncode(), method, vo.getAdapterName(), auth, inboundToken); break; default: break; @@ -381,15 +380,15 @@ public class HttpClient5AdapterServiceRest extends HttpClient5AdapterServiceSupp + method.getEntity() + "] "); } - // OAuth2AccessToken 원래 있던 위치 JWHONG + // OAuth2AccessToken 원래 있던 위치 JWHONG // 전달 header 셋팅 // Adapter 레벨 header 보다 data로 넘어온 httpHeader를 우선 적용(header명이 같다면 덮어씀) assignRequestHeaders(method, httpHeader); - + // KJBank API 추적정보를 Header에 제공. jwhong //assignRequestKJHeaders(method, prop, tempProp ); - + int status = -1; try { @@ -431,7 +430,7 @@ public class HttpClient5AdapterServiceRest extends HttpClient5AdapterServiceSupp // encrypt algorithm type 추출 from adapter property jwhong Properties properties = AdapterPropManager.getInstance().getProperties(vo.getAdapterName()); // jwhong String encryptAlgorithm = properties.getProperty("ENCRYPT_ALGORITHM"); // jwhong - + try { if (logger.isDebug()) { logger.debug("[method getName]" + method.getMethod()); @@ -444,14 +443,14 @@ public class HttpClient5AdapterServiceRest extends HttpClient5AdapterServiceSupp //responseMessage = EntityUtils.toByteArray(response.getEntity()); // 역기서 responseMessage를 decryption 해야 하나 by jwhong - + responseMessageOri = EntityUtils.toByteArray(response.getEntity()); logger.debug("[responseMessageOri 바이트 배열 길이 ]" + responseMessageOri.length); - - responseMessage = doOutboundPostFilter(responseMessageOri, encryptAlgorithm, vo.getAdapterName(), accessToken); // jwhong + + responseMessage = doOutboundPostFilter(responseMessageOri, encryptAlgorithm, vo.getAdapterName(), accessToken); // jwhong // 여기까지 - - responseHeaders = response.getHeaders(); + + responseHeaders = response.getHeaders(); if (logger.isDebug()) { logger.debug("[received status]" + status); @@ -472,7 +471,7 @@ public class HttpClient5AdapterServiceRest extends HttpClient5AdapterServiceSupp * OAuth 토큰 응답 체크(Adapter properties로 설정) * 응답코드에 따라 유효한 토큰 확인(토큰 재발급 여부 확인) * API 서비스 마다 정책이 다름(보통 400대에서 체크하나 200에서도 체크할 수 있음) - * + * * TOKEN_ERROR_CODE_KEY: 응답 json error code key * __ex) $.dataHeader.resultCode * TOKEN_ERROR_CODE_VALUES: 토큰 재발급이 필요한 응답 error codes(ex: O0001,O0002,O0003) @@ -481,10 +480,10 @@ public class HttpClient5AdapterServiceRest extends HttpClient5AdapterServiceSupp * @formatter:on */ boolean needReissue = false; - + Properties responseHeaderProp = assignRelayDataToInbound(tempProp, responseHeaders); String responseString = new String(responseMessage, vo.getEncode()); - + Map map = new HashMap(); tempProp.put(HttpAdapterServiceKey.OUTBOUND_PROPERTY_MAP, map); map.put(HttpAdapterServiceKey.OUTBOUND_RESPONSE_HEADERS, responseHeaderProp); @@ -505,7 +504,7 @@ public class HttpClient5AdapterServiceRest extends HttpClient5AdapterServiceSupp "http receive status fail value=%d adapterName=%s.%s uri=%s method=%s response Data=%s", status, vo.getAdapterGroupName(), vo.getAdapterName(), uri, rmethod, responseString); // logger.error(errMsg); - + if (status >= 400 && status < 500) { if (useAdapterToken) { needReissue = checkTokenRetry(responseMessage, tokenErrorCodeKey, tokenErrorCodeValues, @@ -516,7 +515,7 @@ public class HttpClient5AdapterServiceRest extends HttpClient5AdapterServiceSupp throw new Exception(errMsg); } } else { - + throw new Exception(errMsg); } } @@ -648,7 +647,7 @@ public class HttpClient5AdapterServiceRest extends HttpClient5AdapterServiceSupp if (responseHeaders == null || responseHeaders.length == 0) { return headerProp; } - + for (Header header : responseHeaders) { headerProp.put(header.getName(), header.getValue()); } @@ -658,7 +657,7 @@ public class HttpClient5AdapterServiceRest extends HttpClient5AdapterServiceSupp /** * 현재 1단계 레이아웃에만 적용되도록 구현됨. - * + * * @param method * @param responseMessage * @param headerGroupName @@ -670,7 +669,7 @@ public class HttpClient5AdapterServiceRest extends HttpClient5AdapterServiceSupp */ @SuppressWarnings("unchecked") private String assignResponseHeaders(HttpUriRequestBase method, byte[] responseMessage, String headerGroupName, - String encode, String messageType, String relayHeaderKeys, int status, Properties responseHeaderProp) throws Exception { + String encode, String messageType, String relayHeaderKeys, int status, Properties responseHeaderProp) throws Exception { if (!MessageType.JSON.equals(messageType) || StringUtils.isBlank(headerGroupName) || StringUtils.isBlank(relayHeaderKeys)) { return new String(responseMessage, encode); @@ -716,40 +715,40 @@ public class HttpClient5AdapterServiceRest extends HttpClient5AdapterServiceSupp method.setHeader("Authorization", String.format("%s %s", AccessTokenVO.BEARER_TYPE, accessToken.getAccessToken())); } - - /* nice on 나이스 지키미 용으로 생성함 + + /* nice on 나이스 지키미 용으로 생성함 * jwhong 2015-11-04 */ private void setNiceOnAuthHeaders(HttpUriRequestBase method, String auth) throws Exception { - method.setHeader("Authorization", - String.format("%s %s", AccessTokenVO.BEARER_TYPE, auth)); // 나이스지키미 format임 - method.setHeader("ProductID", "2303345072"); + method.setHeader("Authorization", + String.format("%s %s", AccessTokenVO.BEARER_TYPE, auth)); // 나이스지키미 format임 + method.setHeader("ProductID", "2303345072"); //method.setHeader("Authorization", // String.format("%s %s", AccessTokenVO.BEARER_TYPE, accessToken.getAccessToken())); } - /* nice clientid 추출을 위하여 추가한 내용임. jwhong - * - */ - private String JwtClientIdExtractor(String inboundToken) { + /* nice clientid 추출을 위하여 추가한 내용임. jwhong + * + */ + private String JwtClientIdExtractor(String inboundToken) { - String tokenClientId =""; - try { - SignedJWT signedJWT = SignedJWT.parse(inboundToken); - tokenClientId = (String) signedJWT.getJWTClaimsSet().getClaim(PAYLOAD_PARAM_NAME_CLIENT_ID); + String tokenClientId =""; + try { + SignedJWT signedJWT = SignedJWT.parse(inboundToken); + tokenClientId = (String) signedJWT.getJWTClaimsSet().getClaim(PAYLOAD_PARAM_NAME_CLIENT_ID); } catch (Exception e) { logger.error(e.getMessage()); tokenClientId = ""; } - - logger.debug("[ NICE Token Client ID ]" + tokenClientId); - return tokenClientId; - } - + logger.debug("[ NICE Token Client ID ]" + tokenClientId); + return tokenClientId; + + } + private boolean checkTokenRetry(byte[] responseMessage, String tokenErrorCodeKey, String tokenErrorCodeValues, - String encode) { + String encode) { if (responseMessage == null) { return false; } @@ -809,83 +808,68 @@ public class HttpClient5AdapterServiceRest extends HttpClient5AdapterServiceSupp //weblogic 에서는 tempProp.get 이 property로 return 해어 아래처럼 수정함. ClassCastException 발생함. //Properties inboundHeaders = (Properties) tempProp.get(HttpAdapterServiceKey.INBOUND_HEADER); Properties inboundHeaders = null; - String authorization = ""; String authorization =""; try { Object headerObj = tempProp.get(HttpAdapterServiceKey.INBOUND_HEADER); - System.out.println("*** inboundheader Ojb:"+headerObj); if (headerObj instanceof Properties) { //tomcat inboundHeaders = (Properties) headerObj; - System.out.println("*** inboundHeaders tomcat:"+inboundHeaders); - for (String k : inboundHeaders.stringPropertyNames()) { - System.out.println("*** inboundheader k is:"+k); - if (k.equalsIgnoreCase("authorization")) { - authorization = inboundHeaders.getProperty(k); - break; - } - } for ( String k : inboundHeaders.stringPropertyNames()) { - if(k.equalsIgnoreCase("authorization")) { + if(k.equalsIgnoreCase("authorization")) { authorization = inboundHeaders.getProperty(k); break; } } } else if (headerObj instanceof String) { //weblogic String str = (String) headerObj; - System.out.println("*** inboundHeaders weblogic str:"+str); str = str.substring(1, str.length() - 1); - + // 2. key=value 쌍 분리 String[] entries = str.split(","); - + // map에 담기 Map map = new HashMap<>(); for (String entry : entries) { String[] kv = entry.split("=", 2); if (kv.length == 2) { - map.put( kv[0].trim(), kv[1].trim()); + map.put(kv[0].trim(), kv[1].trim()); } } - for (String k : map.keySet() ) { - if ( k.equalsIgnoreCase("authorization")) { + for (String k : map.keySet()) { + if (k.equalsIgnoreCase("authorization")) { authorization = map.get(k); break; } - } - } - } catch (Exception e) { - e.printStackTrace(); + } + } + } catch (Exception e) { + e.printStackTrace(); } - + String jwtToken = ""; - + if (authorization != null && authorization.startsWith("Bearer ")) { - jwtToken = authorization.substring(7); // "Bearer " 이후의 JWT만 추출 + jwtToken = authorization.substring(7); // "Bearer " 이후의 JWT만 추출 } - - System.out.println("*** authorization is:"+authorization); - System.out.println("*** jwtToken is:"+jwtToken); - + /* 업체정보 */ - String clientId = JwtClientIdExtractor(jwtToken); - method.setHeader("clientId", clientId); - System.out.println("*** header clientID biz company code:"+clientId); - - /* APIM 거래추적자 */ - String uuid = tempProp.getProperty(TransactionContextKeys.TRANSACTION_UUID, ""); - method.setHeader("traceId", uuid); - - /* GUID */ - String guid = tempProp.getProperty(TransactionContextKeys.GUID, ""); - method.setHeader("guid", guid); - - /* 최초요청시간 */ - String receivedTimestamp = tempProp.getProperty(HttpAdapterServiceKey.INBOUND_REQUESTED_TIME, ""); - method.setHeader("receivedTimestamp", receivedTimestamp); - - return jwtToken; + String clientId = JwtClientIdExtractor(jwtToken); + method.setHeader("clientId", clientId); + + /* APIM 거래추적자 */ + String uuid = tempProp.getProperty(TransactionContextKeys.TRANSACTION_UUID, ""); + method.setHeader("traceId", uuid); + + /* GUID */ + String guid = tempProp.getProperty(TransactionContextKeys.GUID, ""); + method.setHeader("guid", guid); + + /* 최초요청시간 */ + String receivedTimestamp = tempProp.getProperty(HttpAdapterServiceKey.INBOUND_REQUESTED_TIME, ""); + method.setHeader("receivedTimestamp", receivedTimestamp); + + return jwtToken; } @SuppressWarnings("deprecation") - private void assignPostBody(Object eaiBody, String contentType, String charset, HttpUriRequestBase method, String adapterName, String niceAuth, String inboundToken) { + private void assignPostBody(Object eaiBody, String contentType, String charset, HttpUriRequestBase method, String adapterName, String niceAuth, String inboundToken) { if (eaiBody == null) { return; } @@ -896,7 +880,7 @@ public class HttpClient5AdapterServiceRest extends HttpClient5AdapterServiceSupp JSONObject jsonObject = (JSONObject) eaiBody; for (Object key : jsonObject.keySet()) { //String encryptedValue = encrypt((String) jsonObject.get(key)); // encrypt by jwhong - //params.add(new BasicNameValuePair((String) key, encryptedValue )); + //params.add(new BasicNameValuePair((String) key, encryptedValue )); params.add(new BasicNameValuePair((String) key, (String) jsonObject.get(key))); } @@ -907,7 +891,7 @@ public class HttpClient5AdapterServiceRest extends HttpClient5AdapterServiceSupp ContentType contentTypeObj = ContentType.create(contentType, charset); String eaiBodyMessage = doOutboundPreFilter(eaiBody, adapterName, niceAuth, inboundToken); // jwhong - StringEntity entity = new StringEntity(eaiBodyMessage, contentTypeObj); + StringEntity entity = new StringEntity(eaiBodyMessage, contentTypeObj); // 요청 본문을 StringEntity 객체로 생성 //StringEntity entity = new StringEntity(eaiBody.toString(), contentTypeObj); @@ -915,153 +899,151 @@ public class HttpClient5AdapterServiceRest extends HttpClient5AdapterServiceSupp method.setEntity(entity); } } - - // from here by jwhong + + // from here by jwhong private String doOutboundPreFilter(Object eaiBody, String adapterName, String niceAuth, String inboundToken) { - + Properties properties = AdapterPropManager.getInstance().getProperties(adapterName); // jwhong String encryptAlgorithm = properties.getProperty("ENCRYPT_ALGORITHM",""); // jwhong - //String encryptBaseKeyType = properties.getProperty("ENCRYPT_BASE_TYPE"); - String encryptClientId = properties.getProperty("ENCRYPT_CLIENT_ID"); - String encryptAES256Iv = properties.getProperty("ENCRYPT_AES256_IV"); - String encryptAES256Key = properties.getProperty("ENCRYPT_AES256_KEY"); - String certPath = properties.getProperty("ENCRYPT_CERT_PATH"); - String encryptAES256Iv = properties.getProperty("ENCRYPT_AES256_IV"); - String encryptAES256Key = properties.getProperty("ENCRYPT_AES256_KEY"); - + String encryptBaseKeyType = properties.getProperty("ENCRYPT_BASE_TYPE"); + String encryptClientId = properties.getProperty("ENCRYPT_CLIENT_ID"); + String encryptAES256Iv = properties.getProperty("ENCRYPT_AES256_IV"); + String encryptAES256Key = properties.getProperty("ENCRYPT_AES256_KEY"); + String certPath = properties.getProperty("ENCRYPT_CERT_PATH"); + // outbound encrypt 는 SecretKey 또는 NICE-auth 가 암호화 key로 사용된다. // outbound 알림결과는 SecretKey, NICE-auth, Token을 사용한다. // 참고로 inbound encrypt 에는 Token 또는 SecretKey 가 암호화 key로 사용된다. // 여기에 NICE-auth logic 추가함 . String clientSecret = ""; - if ("TOKEN".equalsIgnoreCase(encryptBaseKeyType)) { - clientSecret = inboundToken; - } else if ( "SECRETKEY".equalsIgnoreCase(encryptBaseKeyType)) { - OAuth2Manager manager = OAuth2Manager.getInstance(); - ClientDetails clientDetail = manager.getClientDeatilsStore().get(encryptClientId); - if ( clientDetail != null ) { // not null 이라는 것은 APIM Oauth Server에 등록된 client ID 이다. - // 업체가 우리 OAuth 를 사용하는 경우임 - clientSecret = clientDetail.getClientSecret(); - } else { // 이경우는 우리 OAuth를 사용안하는 경우임, 업체에서 사용하는 secretkey를 사용한다. - clientSecret = encryptClientId; - } - } - - // Nice-auth , token 값을 substring 해서 사용한다. 나이스 지키미는 adapter token에서 추출된 token을 사용한다. - if (useAdapterToken && "AES256-NICEON".equals(encryptAlgorithm)) { - clientSecret = niceAuth; - } - - // 여기서 SECRETY인지 nice-auth 인지 check 하여 clientSecret 값을 정하는 logic 추가하여 넘겨야한다. - + if ("TOKEN".equalsIgnoreCase(encryptBaseKeyType)) { + clientSecret = inboundToken; + } else if ( "SECRETKEY".equalsIgnoreCase(encryptBaseKeyType)) { + OAuth2Manager manager = OAuth2Manager.getInstance(); + ClientDetails clientDetail = manager.getClientDeatilsStore().get(encryptClientId); + if ( clientDetail != null ) { // not null 이라는 것은 APIM Oauth Server에 등록된 client ID 이다. + // 업체가 우리 OAuth 를 사용하는 경우임 + clientSecret = clientDetail.getClientSecret(); + } else { // 이경우는 우리 OAuth를 사용안하는 경우임, 업체에서 사용하는 secretkey를 사용한다. + clientSecret = encryptClientId; + } + } + + // Nice-auth , token 값을 substring 해서 사용한다. 나이스 지키미는 adapter token에서 추출된 token을 사용한다. + if (useAdapterToken && "AES256-NICEON".equals(encryptAlgorithm)) { + clientSecret = niceAuth; + } + + // 여기서 SECRETY인지 nice-auth 인지 check 하여 clientSecret 값을 정하는 logic 추가하여 넘겨야한다. + String responseMessage = doOutboundPreEncrypt(eaiBody, encryptAlgorithm, clientSecret, encryptAES256Iv, encryptAES256Key, certPath); logger.debug("outbound pre encrypte value is :"+responseMessage); return responseMessage; - + } private String doOutboundPreEncrypt(Object eaiBody, String encryptAlgorithm, String clientSecretKey, String encryptAES256Iv, String encryptAES256Key, String certPath ) { - + String encryptedMessage = ""; String encryptedJsonKey = ""; - + encryptedJsonKey = getJsonKey(encryptAlgorithm); - + switch (encryptAlgorithm) { - case "AES": - encryptedMessage = encrypt(eaiBody.toString()); // encrypt by jwhong - break; - case "AES128": - case "AES128-TOSS": - try { - String key = clientSecretKey.substring(22,38); - encryptedMessage = AESCipher.encrypt(eaiBody.toString(), key); - } catch (Exception e) { - e.printStackTrace(); - logger.error("HttpClientAdapterServiceRest] AES128 Encryption error=" + e.getMessage()); - } - break; - case "AES128-TOGETHER": - try { - String key = clientSecretKey.substring(44,60); - encryptedMessage = AESCipher.encrypt(eaiBody.toString(), key); - } catch (Exception e) { - e.printStackTrace(); - logger.error("HttpClientAdapterServiceRest] AES128 Encryption error=" + e.getMessage()); - } - break; - case "AES256": - try { - String key = clientSecretKey.substring(10,42); - encryptedMessage = AES256Cipher.encrypt(eaiBody.toString(), key); - } catch (Exception e) { - e.printStackTrace(); - logger.error("HttpClientAdapterServiceRest] AES256 Encryption error=" + e.getMessage()); - } - break; - case "AES256-KAKAO": - try { - encryptedMessage = AES256Cipher.encrypt(eaiBody.toString(), encryptAES256Iv, encryptAES256Key); - } catch (Exception e) { - e.printStackTrace(); - logger.error("HttpClientAdapterServiceRest] AES256 Encryption error=" + e.getMessage()); - } - break; - case "AES256-TOSS": - try { - encryptedMessage = AES256Cipher.encrypt(eaiBody.toString(), encryptAES256Iv, encryptAES256Key); - } catch (Exception e) { - e.printStackTrace(); - logger.error("HttpClientAdapterServiceRest] AES256 Encryption error=" + e.getMessage()); - } - break; - case "AES256-NICEON": - try { - String key = clientSecretKey.substring(10,42); - encryptedMessage = AES256Cipher.encrypt(eaiBody.toString(), key); - } catch (Exception e) { - e.printStackTrace(); - logger.error("HttpClientAdapterServiceRest] AES256 Encryption error=" + e.getMessage()); - } - break; - case "AES256GCM": - try { - byte[] key = AES256GCMCipher.generateKey(); - AES256GCMCipher cipher = new AES256GCMCipher(key); - byte[] aad = "metadata".getBytes(); - - encryptedMessage = cipher.encrypt(eaiBody.toString(), aad); - } catch (Exception e) { - e.printStackTrace(); - logger.error("HttpClientAdapterServiceRest] AES256GCM Encryption error=" + e.getMessage()); - } - break; - case "ECDHESA256": - try { - ECDHESA256Cipher cipher = new ECDHESA256Cipher(); + case "AES": + encryptedMessage = encrypt(eaiBody.toString()); // encrypt by jwhong + break; + case "AES128": + case "AES128-TOSS": + try { + String key = clientSecretKey.substring(22,38); + encryptedMessage = AESCipher.encrypt(eaiBody.toString(), key); + } catch (Exception e) { + e.printStackTrace(); + logger.error("HttpClientAdapterServiceRest] AES128 Encryption error=" + e.getMessage()); + } + break; + case "AES128-TOGETHER": + try { + String key = clientSecretKey.substring(44,60); + encryptedMessage = AESCipher.encrypt(eaiBody.toString(), key); + } catch (Exception e) { + e.printStackTrace(); + logger.error("HttpClientAdapterServiceRest] AES128 Encryption error=" + e.getMessage()); + } + break; + case "AES256": + try { + String key = clientSecretKey.substring(10,42); + encryptedMessage = AES256Cipher.encrypt(eaiBody.toString(), key); + } catch (Exception e) { + e.printStackTrace(); + logger.error("HttpClientAdapterServiceRest] AES256 Encryption error=" + e.getMessage()); + } + break; + case "AES256-KAKAO": + try { + encryptedMessage = AES256Cipher.encrypt(eaiBody.toString(), encryptAES256Iv, encryptAES256Key); + } catch (Exception e) { + e.printStackTrace(); + logger.error("HttpClientAdapterServiceRest] AES256 Encryption error=" + e.getMessage()); + } + break; + case "AES256-TOSS": + try { + encryptedMessage = AES256Cipher.encrypt(eaiBody.toString(), encryptAES256Iv, encryptAES256Key); + } catch (Exception e) { + e.printStackTrace(); + logger.error("HttpClientAdapterServiceRest] AES256 Encryption error=" + e.getMessage()); + } + break; + case "AES256-NICEON": + try { + String key = clientSecretKey.substring(10,42); + encryptedMessage = AES256Cipher.encrypt(eaiBody.toString(), key); + } catch (Exception e) { + e.printStackTrace(); + logger.error("HttpClientAdapterServiceRest] AES256 Encryption error=" + e.getMessage()); + } + break; + case "AES256GCM": + try { + byte[] key = AES256GCMCipher.generateKey(); + AES256GCMCipher cipher = new AES256GCMCipher(key); + byte[] aad = "metadata".getBytes(); - encryptedMessage = cipher.encrypt(eaiBody.toString()); - System.out.println("Encrypted JWE: " + encryptedMessage); + encryptedMessage = cipher.encrypt(eaiBody.toString(), aad); + } catch (Exception e) { + e.printStackTrace(); + logger.error("HttpClientAdapterServiceRest] AES256GCM Encryption error=" + e.getMessage()); + } + break; + case "ECDHESA256": + try { + ECDHESA256Cipher cipher = new ECDHESA256Cipher(); - String decrypted = cipher.decrypt(encryptedMessage); - System.out.println("Decrypted Payload: " + decrypted); - - //아래 인증서로 테스트 - ECDHESA256Cipher cipherCert = new ECDHESA256Cipher(certPath); - encryptedMessage = cipherCert.encrypt(eaiBody.toString()); - - decrypted = cipherCert.decrypt(encryptedMessage); - - } catch (Exception e) { - e.printStackTrace(); - logger.error("HttpClientAdapterServiceRest] AES256GCM Encryption error=" + e.getMessage()); - } - break; - default: - encryptedMessage = eaiBody.toString(); - return encryptedMessage; + encryptedMessage = cipher.encrypt(eaiBody.toString()); + System.out.println("Encrypted JWE: " + encryptedMessage); + + String decrypted = cipher.decrypt(encryptedMessage); + System.out.println("Decrypted Payload: " + decrypted); + + //아래 인증서로 테스트 + ECDHESA256Cipher cipherCert = new ECDHESA256Cipher(certPath); + encryptedMessage = cipherCert.encrypt(eaiBody.toString()); + + decrypted = cipherCert.decrypt(encryptedMessage); + + } catch (Exception e) { + e.printStackTrace(); + logger.error("HttpClientAdapterServiceRest] AES256GCM Encryption error=" + e.getMessage()); + } + break; + default: + encryptedMessage = eaiBody.toString(); + return encryptedMessage; //break; } - + Map map = new HashMap<>(); map.put(encryptedJsonKey, encryptedMessage); JSONObject json = new JSONObject(); @@ -1069,84 +1051,52 @@ public class HttpClient5AdapterServiceRest extends HttpClient5AdapterServiceSupp return json.toJSONString(); //return encryptedMessage; } - - + + private byte[] doOutboundPostFilter(byte[] eaiBody, String decryptAlgorithm, String adapterName, OAuth2AccessTokenVO niceAccessToken ) { - + if ( !encryptResponseApply) { return eaiBody; } - return encryptedMessage; - //break; - } - - Map map = new HashMap<>(); - map.put(encryptedJsonKey, encryptedMessage); - JSONObject json = new JSONObject(); - json.putAll(map); - return json.toJSONString(); - //return encryptedMessage; - } - - - private byte[] doOutboundPostFilter(byte[] eaiBody, String decryptAlgorithm, String adapterName, OAuth2AccessTokenVO niceAccessToken ) { - - if ( !encryptResponseApply) { - return eaiBody; - } - + Properties properties = AdapterPropManager.getInstance().getProperties(adapterName); // jwhong - ////String encryptAlgorithm = properties.getProperty("ENCRYPT_ALGORITHM"); // jwhong - ////String encryptBaseKeyType = properties.getProperty("ENCRYPT_BASE_TYPE"); - String encryptClientId = properties.getProperty("ENCRYPT_CLIENT_ID"); - String encryptAES256Iv = properties.getProperty("ENCRYPT_AES256_IV"); - String encryptAES256Key = properties.getProperty("ENCRYPT_AES256_KEY"); - String encryptAES256Iv = properties.getProperty("ENCRYPT_AES256_IV"); - String encryptAES256Key = properties.getProperty("ENCRYPT_AES256_KEY"); - + //String encryptAlgorithm = properties.getProperty("ENCRYPT_ALGORITHM"); // jwhong + //String encryptBaseKeyType = properties.getProperty("ENCRYPT_BASE_TYPE"); + String encryptClientId = properties.getProperty("ENCRYPT_CLIENT_ID"); + String encryptAES256Iv = properties.getProperty("ENCRYPT_AES256_IV"); + String encryptAES256Key = properties.getProperty("ENCRYPT_AES256_KEY"); + // outbound encrypt 는 SecretKey 또는 NICE-auth 가 암호화 key로 사용된다. - OAuth2Manager manager = OAuth2Manager.getInstance(); - ClientDetails clientDetail = manager.getClientDeatilsStore().get(encryptClientId); - String clientSecret = ""; - if ( clientDetail != null ) { - clientSecret = clientDetail.getClientSecret(); - } else { - clientSecret = encryptClientId; - } - - // Nice-auth , token 값을 substring 해서 사용한다. 나이스 지키미는 adapter token에서 추출된 token을 사용한다. - if (useAdapterToken && "AES256-NICEON".equals(decryptAlgorithm)) { - clientSecret = niceAccessToken.getAccessToken(); - } - - byte[] resPostMessage = doOutboundPostDecrypt(eaiBody, decryptAlgorithm, clientSecret, encryptAES256Iv, encryptAES256Key); - } else { - clientSecret = encryptClientId; - } - - // Nice-auth , token 값을 substring 해서 사용한다. 나이스 지키미는 adapter token에서 추출된 token을 사용한다. - if (useAdapterToken && "AES256-NICEON".equals(decryptAlgorithm)) { - clientSecret = niceAccessToken.getAccessToken(); - } - + OAuth2Manager manager = OAuth2Manager.getInstance(); + ClientDetails clientDetail = manager.getClientDeatilsStore().get(encryptClientId); + String clientSecret = ""; + if ( clientDetail != null ) { + clientSecret = clientDetail.getClientSecret(); + } else { + clientSecret = encryptClientId; + } + + // Nice-auth , token 값을 substring 해서 사용한다. 나이스 지키미는 adapter token에서 추출된 token을 사용한다. + if (useAdapterToken && "AES256-NICEON".equals(decryptAlgorithm)) { + clientSecret = niceAccessToken.getAccessToken(); + } + byte[] resPostMessage = doOutboundPostDecrypt(eaiBody, decryptAlgorithm, clientSecret, encryptAES256Iv, encryptAES256Key); return resPostMessage; } - - private byte[] doOutboundPostDecrypt(byte[] eaiBody, String decryptAlgorithm, String clientSecretKey, String encryptAES256Iv, String encryptAES256Key , String encryptAES256Iv, String encryptAES256Key ) { - + + private byte[] doOutboundPostDecrypt(byte[] eaiBody, String decryptAlgorithm, String clientSecretKey, String encryptAES256Iv, String encryptAES256Key ) { + byte[] decryptedMessage = null; String eaiStringBody = new String(eaiBody, StandardCharsets.UTF_8); - + try { eaiStringBody = extractBodyMsg(decryptAlgorithm, eaiStringBody); } catch (ParseException e) { logger.debug("[JSON 파싱 오류 발생 : ]" +e.getMessage()); return eaiBody; - } - - eaiStringBody = extractBodyMsg(decryptAlgorithm, eaiStringBody); - + } + //test source /* logger.debug("eaiBody 바이트 배열 길이: " + eaiBody.length); @@ -1157,246 +1107,196 @@ public class HttpClient5AdapterServiceRest extends HttpClient5AdapterServiceSupp // Base64 디코딩 테스트 try { - byte[] decoded = Base64.getDecoder().decode(eaiStringBody); - logger.debug("[디코딩 성공, 길이: ]" + decoded.length); + byte[] decoded = Base64.getDecoder().decode(eaiStringBody); + logger.debug("[디코딩 성공, 길이: ]" + decoded.length); } catch (IllegalArgumentException e) { logger.debug("[Base64 디코딩 실패: ]" + e.getMessage()); } - // end test source - + // end test source + switch (decryptAlgorithm) { - case "AES": - decryptedMessage = decrypt(eaiBody); // encrypt by jwhong - break; - case "AES128": - case "AES128-TOSS": - try { - String key128 = clientSecretKey.substring(22,38); - String decryptedStrMessage = AESCipher.decryptExistException(eaiStringBody, key128); - decryptedMessage = decryptedStrMessage.getBytes(StandardCharsets.UTF_8); - } catch (Exception e) { - e.printStackTrace(); - logger.error("HttpClientAdapterServiceRest] AES128 Decryption error=" + e.getMessage()); - } - break; - case "AES128-TOGETHER": - try { - String key128 = clientSecretKey.substring(44,60); - String decryptedStrMessage = AESCipher.decryptExistException(eaiStringBody, key128); - decryptedMessage = decryptedStrMessage.getBytes(StandardCharsets.UTF_8); - } catch (Exception e) { - e.printStackTrace(); - logger.error("HttpClientAdapterServiceRest] AES128 Decryption error=" + e.getMessage()); - } - break; - case "AES256": - try { - String key = clientSecretKey.substring(10,42); - String decryptedStrMessage = AES256Cipher.decrypt(eaiStringBody, key); - decryptedMessage = decryptedStrMessage.getBytes(StandardCharsets.UTF_8); - } catch (Exception e) { - e.printStackTrace(); - logger.error("HttpClientAdapterServiceRest] AES256 Decryption error=" + e.getMessage()); - } - break; - case "AES256-KAKAO": - try { - String decryptedStrMessage = AES256Cipher.decrypt(eaiStringBody, encryptAES256Iv, encryptAES256Key); - decryptedMessage = decryptedStrMessage.getBytes(StandardCharsets.UTF_8); - } catch (Exception e) { - e.printStackTrace(); - logger.error("HttpClientAdapterServiceRest] AES256 Encryption error=" + e.getMessage()); - } - break; - case "AES256-TOSS": - try { - String decryptedStrMessage = AES256Cipher.decrypt(eaiStringBody, encryptAES256Iv, encryptAES256Key); - decryptedMessage = decryptedStrMessage.getBytes(StandardCharsets.UTF_8); - } catch (Exception e) { - e.printStackTrace(); - logger.error("HttpClientAdapterServiceRest] AES256 Encryption error=" + e.getMessage()); - } - break; - case "AES256-NICEON": - try { - String key = clientSecretKey.substring(10,42); - String decryptedStrMessage = AES256Cipher.decrypt(eaiStringBody, key); - decryptedMessage = decryptedStrMessage.getBytes(StandardCharsets.UTF_8); - } catch (Exception e) { - e.printStackTrace(); - logger.error("HttpClientAdapterServiceRest] AES256 Decryption error=" + e.getMessage()); - } - break; - case "AES256GCM": - try { - byte[] key = AES256GCMCipher.generateKey(); - AES256GCMCipher cipher = new AES256GCMCipher(key); - byte[] aad = "metadata".getBytes(); - String decryptedStrMessage = cipher.decrypt(eaiStringBody, aad); - decryptedMessage = decryptedStrMessage.getBytes(StandardCharsets.UTF_8); - } catch (Exception e) { - e.printStackTrace(); - logger.error("HttpClientAdapterServiceRest] AES256 Decryption error=" + e.getMessage()); - } - break; - default: - try { - decryptedMessage = Arrays.copyOf(eaiBody, eaiBody.length); - } catch (Exception e) { - e.printStackTrace(); - logger.error("HttpClientAdapterServiceRest] doOutboundPostFilter Array copy error=" + e.getMessage()); - } - break; + case "AES": + decryptedMessage = decrypt(eaiBody); // encrypt by jwhong + break; + case "AES128": + case "AES128-TOSS": + try { + String key128 = clientSecretKey.substring(22,38); + String decryptedStrMessage = AESCipher.decryptExistException(eaiStringBody, key128); + decryptedMessage = decryptedStrMessage.getBytes(StandardCharsets.UTF_8); + } catch (Exception e) { + e.printStackTrace(); + logger.error("HttpClientAdapterServiceRest] AES128 Decryption error=" + e.getMessage()); + } + break; + case "AES128-TOGETHER": + try { + String key128 = clientSecretKey.substring(44,60); + String decryptedStrMessage = AESCipher.decryptExistException(eaiStringBody, key128); + decryptedMessage = decryptedStrMessage.getBytes(StandardCharsets.UTF_8); + } catch (Exception e) { + e.printStackTrace(); + logger.error("HttpClientAdapterServiceRest] AES128 Decryption error=" + e.getMessage()); + } + break; + case "AES256": + try { + String key = clientSecretKey.substring(10,42); + String decryptedStrMessage = AES256Cipher.decrypt(eaiStringBody, key); + decryptedMessage = decryptedStrMessage.getBytes(StandardCharsets.UTF_8); + } catch (Exception e) { + e.printStackTrace(); + logger.error("HttpClientAdapterServiceRest] AES256 Decryption error=" + e.getMessage()); + } + break; + case "AES256-KAKAO": + try { + String decryptedStrMessage = AES256Cipher.decrypt(eaiStringBody, encryptAES256Iv, encryptAES256Key); + decryptedMessage = decryptedStrMessage.getBytes(StandardCharsets.UTF_8); + } catch (Exception e) { + e.printStackTrace(); + logger.error("HttpClientAdapterServiceRest] AES256 Encryption error=" + e.getMessage()); + } + break; + case "AES256-TOSS": + try { + String decryptedStrMessage = AES256Cipher.decrypt(eaiStringBody, encryptAES256Iv, encryptAES256Key); + decryptedMessage = decryptedStrMessage.getBytes(StandardCharsets.UTF_8); + } catch (Exception e) { + e.printStackTrace(); + logger.error("HttpClientAdapterServiceRest] AES256 Encryption error=" + e.getMessage()); + } + break; + case "AES256-NICEON": + try { + String key = clientSecretKey.substring(10,42); + String decryptedStrMessage = AES256Cipher.decrypt(eaiStringBody, key); + decryptedMessage = decryptedStrMessage.getBytes(StandardCharsets.UTF_8); + } catch (Exception e) { + e.printStackTrace(); + logger.error("HttpClientAdapterServiceRest] AES256 Decryption error=" + e.getMessage()); + } + break; + case "AES256GCM": + try { + byte[] key = AES256GCMCipher.generateKey(); + AES256GCMCipher cipher = new AES256GCMCipher(key); + byte[] aad = "metadata".getBytes(); + String decryptedStrMessage = cipher.decrypt(eaiStringBody, aad); + decryptedMessage = decryptedStrMessage.getBytes(StandardCharsets.UTF_8); + } catch (Exception e) { + e.printStackTrace(); + logger.error("HttpClientAdapterServiceRest] AES256 Decryption error=" + e.getMessage()); + } + break; + default: + try { + decryptedMessage = Arrays.copyOf(eaiBody, eaiBody.length); + } catch (Exception e) { + e.printStackTrace(); + logger.error("HttpClientAdapterServiceRest] doOutboundPostFilter Array copy error=" + e.getMessage()); + } + break; } - - return decryptedMessage; + + return decryptedMessage; } - - + + private String extractBodyMsg(String decryptAlgorithm, String eaiStringBody) throws ParseException { String decryptedJsonKey = ""; String decryptedBodyMessage = ""; - + decryptedJsonKey = getJsonKey(decryptAlgorithm); - + try { JSONParser parser = new JSONParser(); JSONObject jsonObject = (JSONObject) parser.parse(eaiStringBody); - decryptedBodyMessage = (String) jsonObject.get(decryptedJsonKey); + decryptedBodyMessage = (String) jsonObject.get(decryptedJsonKey); } catch (ParseException e) { - e.printStackTrace(); - logger.error("HttpClient5AdapterServiceRest] extractBodyMsg error : " + e.getMessage()); - throw e; - } - - return decryptedBodyMessage; - - } - - private String getJsonKey(String Algorithm) { - - String jsonKey = ""; - - switch (Algorithm) { - case "AES128": - case "AES128-TOSS": - jsonKey = "preScreeningRequest"; - break; - case "AES128-TOGETHER": - jsonKey = "obpTxData"; - break; - case "AES256": - jsonKey = "preScreeningRequest"; - break; - case "AES256-KAKAO": - jsonKey = "encrypted_data"; - break; - case "AES256-TOSS": - jsonKey = "encryptedData"; - break; - case "AES256-NICEON": - jsonKey = "preScreeningRequest"; - break; - case "AES256GCM": - break; - default: - break; - } - return jsonKey; - } - private String extractBodyMsg(String decryptAlgorithm, String eaiStringBody) { - - String decryptedJsonKey = ""; - String decryptedBodyMessage = ""; - - decryptedJsonKey = getJsonKey(decryptAlgorithm); - - try { - JSONParser parser = new JSONParser(); - JSONObject jsonObject = (JSONObject) parser.parse(eaiStringBody); - decryptedBodyMessage = (String) jsonObject.get(decryptedJsonKey); - } catch (Exception e) { - e.printStackTrace(); - logger.error("HttpClient5AdapterServiceRest] extractBodyMsg error : " + e.getMessage()); + e.printStackTrace(); + logger.error("HttpClient5AdapterServiceRest] extractBodyMsg error : " + e.getMessage()); + throw e; } return decryptedBodyMessage; - + } - + private String getJsonKey(String Algorithm) { - + String jsonKey = ""; - + switch (Algorithm) { - case "AES128-TOSS": - jsonKey = "preScreeningRequest"; - break; - case "AES128-TOGETHER": - jsonKey = "obpTxData"; - break; - case "AES256": - jsonKey = "preScreeningRequest"; - break; - case "AES256-KAKAO": - jsonKey = "encrypted_data"; - break; - case "AES256-TOSS": - jsonKey = "encryptedData"; - break; - case "AES256-NICEON": - jsonKey = "preScreeningRequest"; - break; - case "AES256GCM": - break; - default: - break; + case "AES128": + case "AES128-TOSS": + jsonKey = "preScreeningRequest"; + break; + case "AES128-TOGETHER": + jsonKey = "obpTxData"; + break; + case "AES256": + jsonKey = "preScreeningRequest"; + break; + case "AES256-KAKAO": + jsonKey = "encrypted_data"; + break; + case "AES256-TOSS": + jsonKey = "encryptedData"; + break; + case "AES256-NICEON": + jsonKey = "preScreeningRequest"; + break; + case "AES256GCM": + break; + default: + break; } return jsonKey; } // by jwhong private String encrypt(String plainText) { - try { - SecretKeySpec key = new SecretKeySpec("1234567890123456".getBytes(), "AES"); - Cipher cipher = Cipher.getInstance("AES"); - cipher.init(Cipher.ENCRYPT_MODE, key); - byte[] encrypted = cipher.doFinal(plainText.getBytes(StandardCharsets.UTF_8)); - return Base64.getEncoder().encodeToString(encrypted); - } catch (Exception e) { - // 예외 로그 출력 또는 사용자 정의 처리 - e.printStackTrace(); - return null; // 또는 에러 메시지 반환 - } + try { + SecretKeySpec key = new SecretKeySpec("1234567890123456".getBytes(), "AES"); + Cipher cipher = Cipher.getInstance("AES"); + cipher.init(Cipher.ENCRYPT_MODE, key); + byte[] encrypted = cipher.doFinal(plainText.getBytes(StandardCharsets.UTF_8)); + return Base64.getEncoder().encodeToString(encrypted); + } catch (Exception e) { + // 예외 로그 출력 또는 사용자 정의 처리 + e.printStackTrace(); + return null; // 또는 에러 메시지 반환 + } } - - - public static byte[] decrypt(byte[] encryptedBytes) { - try { - // byte[] --> Base64 문자열로 변환 - String encryptedText = new String(encryptedBytes, StandardCharsets.UTF_8).trim(); - // 암호화에 사용한 키와 동일한 키 사용 - SecretKeySpec key = new SecretKeySpec("1234567890123456".getBytes(), "AES"); - // 암호화와 동일한 알고리즘 설정 - Cipher cipher = Cipher.getInstance("AES"); - cipher.init(Cipher.DECRYPT_MODE, key); - // Base64로 인코딩된 문자열을 디코딩 - byte[] decodedBytes = Base64.getDecoder().decode(encryptedText); + public static byte[] decrypt(byte[] encryptedBytes) { + try { + // byte[] --> Base64 문자열로 변환 + String encryptedText = new String(encryptedBytes, StandardCharsets.UTF_8).trim(); + // 암호화에 사용한 키와 동일한 키 사용 + SecretKeySpec key = new SecretKeySpec("1234567890123456".getBytes(), "AES"); - // 복호화 수행 - byte[] decryptedBytes = cipher.doFinal(decodedBytes); + // 암호화와 동일한 알고리즘 설정 + Cipher cipher = Cipher.getInstance("AES"); + cipher.init(Cipher.DECRYPT_MODE, key); - // UTF-8 문자열로 변환하여 반환 - //return new String(decryptedBytes, StandardCharsets.UTF_8); - //복호화된 바이트 배열 반환 - return decryptedBytes; - } catch (Exception e) { - e.printStackTrace(); - return null; - } - } + // Base64로 인코딩된 문자열을 디코딩 + byte[] decodedBytes = Base64.getDecoder().decode(encryptedText); + + // 복호화 수행 + byte[] decryptedBytes = cipher.doFinal(decodedBytes); + + // UTF-8 문자열로 변환하여 반환 + //return new String(decryptedBytes, StandardCharsets.UTF_8); + //복호화된 바이트 배열 반환 + return decryptedBytes; + } catch (Exception e) { + e.printStackTrace(); + return null; + } + } private HashMap getParameters(Object message) throws Exception { @@ -1428,7 +1328,7 @@ public class HttpClient5AdapterServiceRest extends HttpClient5AdapterServiceSupp return result; } - + public String getStringValue(Object obj) { if (obj == null) { return null; @@ -1566,4 +1466,4 @@ public class HttpClient5AdapterServiceRest extends HttpClient5AdapterServiceSupp logger.debug("HttpClientAdapterServiceRest] after concatenate url=[" + targetUrl + "] "); return targetUrl; } -} \ No newline at end of file +} From 9f03f3dabea0afe931db503d2901f67feb4e7da1 Mon Sep 17 00:00:00 2001 From: Rinjae Date: Fri, 5 Dec 2025 18:17:20 +0900 Subject: [PATCH 028/159] =?UTF-8?q?push=202=ED=8A=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/com/eactive/eai/common/logger/EAILogDAO.java | 5 ----- 1 file changed, 5 deletions(-) diff --git a/src/main/java/com/eactive/eai/common/logger/EAILogDAO.java b/src/main/java/com/eactive/eai/common/logger/EAILogDAO.java index 3a48e5d..08cc9b3 100644 --- a/src/main/java/com/eactive/eai/common/logger/EAILogDAO.java +++ b/src/main/java/com/eactive/eai/common/logger/EAILogDAO.java @@ -60,11 +60,6 @@ import com.ext.eai.common.stdmessage.STDMessageKeys; // safeDB import com.eactive.ext.kjb.safedb.KjbSafedbWrapper; import com.eactive.ext.kjb.safedb.Utils; -<<<<<<<<< Temporary merge branch 1 -// until here -========= -// until here ->>>>>>>>> Temporary merge branch 2 @Service From b4a2150bc0fb5bd68ecefd14b1116d758d549dec Mon Sep 17 00:00:00 2001 From: Rinjae Date: Fri, 5 Dec 2025 18:19:00 +0900 Subject: [PATCH 029/159] push --- .../eai/adapter/http/dynamic/HttpAdapterServiceKey.java | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/main/java/com/eactive/eai/adapter/http/dynamic/HttpAdapterServiceKey.java b/src/main/java/com/eactive/eai/adapter/http/dynamic/HttpAdapterServiceKey.java index 5061ee1..9fdc548 100644 --- a/src/main/java/com/eactive/eai/adapter/http/dynamic/HttpAdapterServiceKey.java +++ b/src/main/java/com/eactive/eai/adapter/http/dynamic/HttpAdapterServiceKey.java @@ -79,9 +79,7 @@ public interface HttpAdapterServiceKey { static final String ENCRYPT_AES256_KEY = "ENCRYPT_AES256_KEY"; // jwhong static final String INBOUND_REQUESTED_TIME = "INBOUND_REQUESTED_TIME"; // jwhong static final String GUID = "GUID"; // jwhong - static final String API_SERVICE_CODE = "API_SERVICE_CODE"; // jwhong - static final String ENCRYPT_AES256_IV = "ENCRYPT_AES256_IV"; // jwhong - static final String ENCRYPT_AES256_KEY = "ENCRYPT_AES256_KEY"; // jwhong + static final String API_SERVICE_CODE = "API_SERVICE_CODE"; // jwhong //응답 처리 용 표준 전문 오브젝트 static final String STANDARD_MESSAGE_OBJECT = "STANDARD_MESSAGE_OBJECT"; From 24958ac00e22a6f8d3032f50511e24c44a728cb5 Mon Sep 17 00:00:00 2001 From: yunjy-hp Date: Tue, 9 Dec 2025 13:46:56 +0900 Subject: [PATCH 030/159] =?UTF-8?q?=EA=B4=91=EC=A3=BC=EC=9D=80=ED=96=89=20?= =?UTF-8?q?=ED=91=9C=EC=A4=80=EC=A0=84=EB=AC=B8=20=EA=B4=80=EB=A0=A8=20?= =?UTF-8?q?=EC=9E=91=EC=97=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../impl/HttpClient5AdapterServiceBody.java | 19 ++++++---- .../eactive/eai/common/routing/Process.java | 4 +- .../inbound/processor/RequestProcessor.java | 3 ++ .../eai/message/parser/FlatReader.java | 38 ++++++++++++++++--- .../DefaultStandardMessageCoordinator.java | 9 ++++- .../service/StandardMessageCoordinator.java | 20 +++++++++- 6 files changed, 76 insertions(+), 17 deletions(-) diff --git a/src/main/java/com/eactive/eai/adapter/http/client/impl/HttpClient5AdapterServiceBody.java b/src/main/java/com/eactive/eai/adapter/http/client/impl/HttpClient5AdapterServiceBody.java index 5bfc866..2468b2f 100644 --- a/src/main/java/com/eactive/eai/adapter/http/client/impl/HttpClient5AdapterServiceBody.java +++ b/src/main/java/com/eactive/eai/adapter/http/client/impl/HttpClient5AdapterServiceBody.java @@ -5,6 +5,7 @@ import com.eactive.eai.adapter.http.client.HttpClient5AdapterServiceSupport; import com.eactive.eai.adapter.http.client.HttpClientAdapterServiceKey; import com.eactive.eai.adapter.http.client.HttpClientAdapterVO; import com.eactive.eai.common.TransactionContextKeys; +import com.eactive.eai.common.message.MessageType; import com.eactive.eai.common.util.CommonLib; import org.apache.commons.httpclient.HttpStatus; import org.apache.commons.lang3.StringUtils; @@ -57,14 +58,16 @@ public class HttpClient5AdapterServiceBody extends HttpClient5AdapterServiceSupp } else if (data instanceof byte[]) { sendData = new String((byte[]) data, vo.getEncode()); } - - ObjectMapper mapper = new ObjectMapper(); - ObjectNode jsonNode = (ObjectNode) mapper.readTree(sendData); - ObjectNode headerPart = (ObjectNode) jsonNode.get("header_part"); - - if( headerPart.get("mciIntfId") != null && headerPart.get("mciIntfId").asText().trim().length() > 0 ) { - headerPart.put("eaiIntfId", ""); - sendData = mapper.writerWithDefaultPrettyPrinter().writeValueAsString(jsonNode); + + if(MessageType.JSON.equals(prop.getProperty("messageType"))) { + ObjectMapper mapper = new ObjectMapper(); + ObjectNode jsonNode = (ObjectNode) mapper.readTree(sendData); + ObjectNode headerPart = (ObjectNode) jsonNode.get("header_part"); + + if( headerPart.get("mciIntfId") != null && headerPart.get("mciIntfId").asText().trim().length() > 0 ) { + headerPart.put("eaiIntfId", ""); + sendData = mapper.writerWithDefaultPrettyPrinter().writeValueAsString(jsonNode); + } } if ("Y".equals(vo.getUrlEncodeYn())) { diff --git a/src/main/java/com/eactive/eai/common/routing/Process.java b/src/main/java/com/eactive/eai/common/routing/Process.java index 9720241..0731da5 100644 --- a/src/main/java/com/eactive/eai/common/routing/Process.java +++ b/src/main/java/com/eactive/eai/common/routing/Process.java @@ -33,7 +33,9 @@ public abstract class Process { String outboundAdapterGroupName = eaiMessage.getCurrentSvcMsg().getPsvSysItfTp(); AdapterGroupVO outboundAdapterGvo = AdapterManager.getInstance().getAdapterGroupVO(outboundAdapterGroupName); standardMessage.setBizData(bizObject, outboundAdapterGvo.getMessageEncode()); - + + StandardMessageManager.getInstance().getMessageCoordinator().coordinateBeforeStandardMessageSend(standardMessage, msgType, charset); + if(MessageType.JSON.equals(msgType)) { return standardMessage.toJson(); } diff --git a/src/main/java/com/eactive/eai/inbound/processor/RequestProcessor.java b/src/main/java/com/eactive/eai/inbound/processor/RequestProcessor.java index 0dc1a94..531d7fa 100644 --- a/src/main/java/com/eactive/eai/inbound/processor/RequestProcessor.java +++ b/src/main/java/com/eactive/eai/inbound/processor/RequestProcessor.java @@ -1222,6 +1222,9 @@ public class RequestProcessor extends RequestProcessorSupport { logger.error("convertToSub failed.", e); } } + + //응답 전 표준 전문의 로직 처리 필요 한 경우를 위해 호출 + standardManager.getMessageCoordinator().coordinateBeforeResponse(standardMessage, vo, prop, inboundCharset); // 10. 응답 거래로그 Logging if(EAIMessageKeys.SYNC_SVC.equals(svcTsmtUsgTp) && diff --git a/src/main/java/com/eactive/eai/message/parser/FlatReader.java b/src/main/java/com/eactive/eai/message/parser/FlatReader.java index 76e29bc..ef2d2a6 100644 --- a/src/main/java/com/eactive/eai/message/parser/FlatReader.java +++ b/src/main/java/com/eactive/eai/message/parser/FlatReader.java @@ -107,16 +107,22 @@ public class FlatReader implements StandardReader { case StandardType.GROUP: logger.debug("@GROUP name={}, getLength={}, getRefPath={}, getRefValue=[{}]" , currentItem.getName(), currentItem.getLength(), currentItem.getRefPath(), currentItem.getRefValue()); - if( currentItem.getSize() == 0 - && StringUtils.isNotBlank(currentItem.getRefPath()) + if( currentItem.getSize() == 0 + && StringUtils.isNotBlank(currentItem.getRefPath()) && StringUtils.isNotBlank(currentItem.getRefValue()) ) { - String refItemValue = itemMap.get(currentItem.getRefPath()); - + //2024.08.07 아래추가로직은 Group 하위의 field 값에 따라서 + //파싱을 해야 될경우 추가 + String refItemValue =""; + if (currentItem.getRefPath().startsWith(fieldName)){ + refItemValue = getRefItemValue(currentItem.getRefPath(), fieldName, srcbytes, currentItem, start); + }else{ + refItemValue = itemMap.get(currentItem.getRefPath()); + } logger.debug("@GROUP name={}, getRefPath={}, refItemValue=[{}], getRefValue=[{}]" , currentItem.getName(), currentItem.getRefPath(), refItemValue, currentItem.getRefValue()); - + if(refItemValue != null) refItemValue = refItemValue.trim(); - + /* * 값의 경우의수 NR,ER,""(blank) * ER이 아닐경우 표현하고 싶어서 ! 를 추가했음 @@ -284,6 +290,26 @@ public class FlatReader implements StandardReader { } return result; } + + private String getRefItemValue(String orgRef, String fieldName, byte[] srcbytes , StandardItem currentItem ,int start ){ + String currentFieldName = orgRef.replace(fieldName+".",""); + ArrayList childList = currentItem.getChildsList(); + String refItemValue =""; + for(StandardItem item : childList) { + if (currentFieldName.indexOf(".") < 0) { + byte[] tempValue = null; + if (orgRef.equals(fieldName + "." + item.getName())) { + tempValue = cut(fieldName, srcbytes, start, item.getLength()); + return new String(tempValue); + }else{ + start = start + item.getLength(); + } + } else { + return getRefItemValue(orgRef, fieldName+"."+item.getName(), srcbytes, item, start); + } + } + return refItemValue; + } // public static void main(String[] args) { // } } \ No newline at end of file diff --git a/src/main/java/com/eactive/eai/message/service/DefaultStandardMessageCoordinator.java b/src/main/java/com/eactive/eai/message/service/DefaultStandardMessageCoordinator.java index 01a5cc4..81f34b5 100644 --- a/src/main/java/com/eactive/eai/message/service/DefaultStandardMessageCoordinator.java +++ b/src/main/java/com/eactive/eai/message/service/DefaultStandardMessageCoordinator.java @@ -25,6 +25,11 @@ public class DefaultStandardMessageCoordinator implements StandardMessageCoordin mapper.setGuid(standardMessage, UUIDGenerator.getGUID(eaiServerManager.getSystemType())); } + @Override + public void coordinateBeforeStandardMessageSend(StandardMessage standardMessage, String msgType, String charset) { + + } + @Override public void coordinateInReturnObject(StandardMessage standardMessage) { } @@ -72,5 +77,7 @@ public class DefaultStandardMessageCoordinator implements StandardMessageCoordin } - + @Override + public void coordinateBeforeResponse(StandardMessage standardMessage, ProcessVO processVO, Properties prop, String charset) { + } } diff --git a/src/main/java/com/eactive/eai/message/service/StandardMessageCoordinator.java b/src/main/java/com/eactive/eai/message/service/StandardMessageCoordinator.java index 11df794..a9a0e49 100644 --- a/src/main/java/com/eactive/eai/message/service/StandardMessageCoordinator.java +++ b/src/main/java/com/eactive/eai/message/service/StandardMessageCoordinator.java @@ -26,7 +26,14 @@ public interface StandardMessageCoordinator { * @param prop */ public void coordinateAfterCreateMessageByRule(StandardMessage standardMessage, Object paramObject, Properties prop); - + + /** + * 표준전문 송신 전 메시지 조립 전 처리 + * + * @param standardMessage + */ + public void coordinateBeforeStandardMessageSend(StandardMessage standardMessage, String msgType, String charset); + /** * 표준 메시지일경우 ReturnObject 에서 처리 * @@ -97,4 +104,15 @@ public interface StandardMessageCoordinator { * @param responseMessage */ public void coordinateAfterRecvNonStdSyncResponse(StandardMessage responseMessage); + + + /** + * RequestProcess 400 응답 로그 전 표준 메시지 조작 처리 + * + * @param standardMessage + * @param processVO + * @param prop + * @param charset + */ + public void coordinateBeforeResponse(StandardMessage standardMessage, ProcessVO processVO, Properties prop, String charset); } From b6ba433fc92fc6fa8296129e2db68c970e6de152 Mon Sep 17 00:00:00 2001 From: "Yunsam.Eo" Date: Wed, 10 Dec 2025 23:07:09 +0900 Subject: [PATCH 031/159] =?UTF-8?q?API=20SvcCD=20Setting=EB=B3=80=EA=B2=BD?= =?UTF-8?q?,=20=EA=B3=A0=EC=A0=95=ED=86=A0=ED=81=B0=20=EC=B2=98=EB=A6=AC?= =?UTF-8?q?=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../http/dynamic/filter/ApiAuthFilter.java | 46 +++++++++++++++++-- .../http/dynamic/filter/JwtAuthFilter.java | 7 ++- 2 files changed, 48 insertions(+), 5 deletions(-) diff --git a/src/main/java/com/eactive/eai/adapter/http/dynamic/filter/ApiAuthFilter.java b/src/main/java/com/eactive/eai/adapter/http/dynamic/filter/ApiAuthFilter.java index c3458e6..569b64b 100644 --- a/src/main/java/com/eactive/eai/adapter/http/dynamic/filter/ApiAuthFilter.java +++ b/src/main/java/com/eactive/eai/adapter/http/dynamic/filter/ApiAuthFilter.java @@ -1,6 +1,8 @@ package com.eactive.eai.adapter.http.dynamic.filter; import com.eactive.eai.adapter.http.dynamic.HttpAdapterServiceSupport; +//import com.eactive.eai.authserver.vo.BearerTokenInfo; +//import com.eactive.eai.authserver.custom.BearerTokenService; import com.eactive.eai.authserver.service.OAuth2Manager; import com.eactive.eai.authserver.vo.ClientVO; import com.eactive.eai.common.message.EAIMessage; @@ -9,6 +11,7 @@ import com.eactive.eai.common.property.PropGroupVO; import com.eactive.eai.common.property.PropManager; import com.eactive.eai.common.stdmessage.STDMessageManager; import com.eactive.eai.common.util.Logger; +import com.eactive.eai.common.util.StringUtil; import com.eactive.eai.inbound.action.ActionFactory; import com.eactive.eai.inbound.action.RequestAction; import com.eactive.eai.inbound.processor.Processor; @@ -35,7 +38,9 @@ import java.text.ParseException; import java.util.Base64; import java.util.Date; import java.util.HashSet; +import java.util.Map; import java.util.Properties; +import java.util.concurrent.ConcurrentHashMap; public class ApiAuthFilter implements HttpAdapterFilter { static Logger logger = Logger.getLogger(Logger.LOGGER_ADAPTER); @@ -52,7 +57,10 @@ public class ApiAuthFilter implements HttpAdapterFilter { private JWSVerifier jwsVerifier; - public ApiAuthFilter() { +// // CA 토큰 저장소 +// private final Map CATokenStore = new ConcurrentHashMap<>(); + + public ApiAuthFilter() { super(); PropGroupVO vo = PropManager.getInstance().getPropGroupVO(PROP_GROUP_AUTH_SERVER); @@ -94,6 +102,7 @@ public class ApiAuthFilter implements HttpAdapterFilter { */ StandardMessage standardMessage = STDMessageManager.getInstance().getSTDMessage(apiId); String eaiSvcCd = StandardMessageManager.getInstance().getMapper().getEaiSvcCode(standardMessage); + if(!StringUtils.equals(eaiSvcCd, prop.getProperty("API_SERVICE_CODE"))) eaiSvcCd = prop.getProperty("API_SERVICE_CODE"); EAIMessage eaiMessage = EAIMessageManager.getInstance().getEAIMessage(eaiSvcCd); if(StringUtils.isBlank(eaiMessage.getAuthType())){ @@ -106,7 +115,9 @@ public class ApiAuthFilter implements HttpAdapterFilter { String token = ApiAuthFilter.extractJWTToken(request); SignedJWT signedJWT = SignedJWT.parse(token); - if (new Date().after(signedJWT.getJWTClaimsSet().getExpirationTime())) { + if (signedJWT.getJWTClaimsSet().getExpirationTime() == null) { + logger.debug("Static Token"); + } else if (new Date().after(signedJWT.getJWTClaimsSet().getExpirationTime())) { throw new JwtAuthException(ERROR_TOKEN_EXPIRED, "Access token expired"); } @@ -133,6 +144,26 @@ public class ApiAuthFilter implements HttpAdapterFilter { throw new JwtAuthException(ERROR_AUTHENTICATION_FAIL, "Token invalid"); } break; +// case "bearer": +// try { +// String token = ApiAuthFilter.extractJWTToken(request); +// BearerTokenInfo CATokenInfo = CATokenStore.get(token); +// +// if (CATokenInfo == null) { +// throw new JwtAuthException(ERROR_AUTHENTICATION_FAIL, "Token invalid"); +// } +// +// if (CATokenInfo.isExpired()) { +// throw new JwtAuthException(ERROR_TOKEN_EXPIRED, "Access token expired"); +// } +// } catch (JwtAuthException e) { +// logger.debug(e.getMessage()); +// throw e; +// } catch (Exception e) { +// logger.error(e.getMessage()); +// throw new JwtAuthException(ERROR_AUTHENTICATION_FAIL, "Token invalid"); +// } +// break; case "api_key": String apiKeyName = PropManager.getInstance().getProperty("ApiConfig", "api.key.name", "x-api-key"); String apiKey = request.getHeader(apiKeyName); @@ -158,7 +189,7 @@ public class ApiAuthFilter implements HttpAdapterFilter { return message; } - private boolean verifyClientId(Properties prop, SignedJWT signedJWT) { + private boolean verifyClientId(Properties prop, SignedJWT signedJWT) throws JwtAuthException { try { // 이전 filter에서 셋팅한 clientId 확보 String headerClientId = prop.getProperty(HttpAdapterServiceSupport.PROPERTIES_NAME_CLIENT_ID); @@ -176,6 +207,7 @@ public class ApiAuthFilter implements HttpAdapterFilter { } } catch (Exception e) { logger.error(e.getMessage()); + throw new JwtAuthException(ERROR_AUTHENTICATION_FAIL, "Token invalid"); } return true; @@ -227,8 +259,16 @@ public class ApiAuthFilter implements HttpAdapterFilter { if (scopeArr == null || scopeArr.length == 0) { return false; } + + String passScope = "oob,public"; + String[] passScopeArr = org.springframework.util.StringUtils.tokenizeToStringArray(passScope, ","); for (String scope : scopeArr) { + for (String pScope : passScopeArr) { + if ( StringUtils.equalsAny(scope, pScope)) { + return true; + } + } if (scopeSet.contains(scope)) { return true; } diff --git a/src/main/java/com/eactive/eai/adapter/http/dynamic/filter/JwtAuthFilter.java b/src/main/java/com/eactive/eai/adapter/http/dynamic/filter/JwtAuthFilter.java index 1de5a38..306f651 100644 --- a/src/main/java/com/eactive/eai/adapter/http/dynamic/filter/JwtAuthFilter.java +++ b/src/main/java/com/eactive/eai/adapter/http/dynamic/filter/JwtAuthFilter.java @@ -88,7 +88,9 @@ public class JwtAuthFilter implements HttpAdapterFilter { String token = JwtAuthFilter.extractJWTToken(request); SignedJWT signedJWT = SignedJWT.parse(token); - if (new Date().after(signedJWT.getJWTClaimsSet().getExpirationTime())) { + if (signedJWT.getJWTClaimsSet().getExpirationTime() == null) { + logger.debug("Static Token"); + } else if (new Date().after(signedJWT.getJWTClaimsSet().getExpirationTime())) { throw new JwtAuthException(ERROR_TOKEN_EXPIRED, "Access token expired"); } @@ -118,7 +120,7 @@ public class JwtAuthFilter implements HttpAdapterFilter { return message; } - private boolean verifyClientId(Properties prop, SignedJWT signedJWT) { + private boolean verifyClientId(Properties prop, SignedJWT signedJWT) throws JwtAuthException { try { // 이전 filter에서 셋팅한 clientId 확보 String headerClientId = prop.getProperty(HttpAdapterServiceSupport.PROPERTIES_NAME_CLIENT_ID); @@ -136,6 +138,7 @@ public class JwtAuthFilter implements HttpAdapterFilter { } } catch (Exception e) { logger.error(e.getMessage()); + throw new JwtAuthException(ERROR_AUTHENTICATION_FAIL, "Token invalid"); } return true; From 85048d74528a5657d9107ab657711c677a9a9e25 Mon Sep 17 00:00:00 2001 From: "Yunsam.Eo" Date: Wed, 10 Dec 2025 23:08:20 +0900 Subject: [PATCH 032/159] =?UTF-8?q?messageKey=20=EC=B6=94=EC=B6=9C=20Reque?= =?UTF-8?q?st=20Action=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../AdapterGroupNameMethodRequestAction.java | 70 +++++++++++++++++++ 1 file changed, 70 insertions(+) create mode 100644 src/main/java/com/eactive/eai/inbound/action/AdapterGroupNameMethodRequestAction.java diff --git a/src/main/java/com/eactive/eai/inbound/action/AdapterGroupNameMethodRequestAction.java b/src/main/java/com/eactive/eai/inbound/action/AdapterGroupNameMethodRequestAction.java new file mode 100644 index 0000000..c808571 --- /dev/null +++ b/src/main/java/com/eactive/eai/inbound/action/AdapterGroupNameMethodRequestAction.java @@ -0,0 +1,70 @@ +package com.eactive.eai.inbound.action; + +import com.eactive.eai.adapter.http.dynamic.impl.HttpAdapterServiceRest; +import com.eactive.eai.common.exception.ExceptionUtil; +import com.eactive.eai.common.util.MessageKeyExtractor; + +/** +* 1. 기능 : Inbound Adapter를 통해 전달받은 비표준메시지에서 EAI메시지를 생성하기 위한 키값을 추출 +* 2. 처리 개요 : +* - 어뎁터의 업무그룹명을 키값앞에 추가한다. +* - MessageKeyExtractor를 통해 Adapter별 추출 Rule에 따라 메시지를 구분할 수 있는 키값을 추출한다. +* 3. 주의사항 +* +* @author : +* @version : v 1.0.0 +* @see : +* @since : +*/ +public class AdapterGroupNameMethodRequestAction extends RequestActionSupport +{ + public static final String STEMSG_METHOD_DELIMITER = ":"; + public static final String STEMSG_SERVICE_HEADER_DELIMITER = "^"; + + /** + * 1. 기능 : Inbound Adapter를 통해 전달받은 비표준메시지에서 EAI메시지를 생성하기 위한 키값을 추출 + * 2. 처리 개요 : + * - MessageKeyExtractor를 통해 Adapter별 추출 Rule에 따라 메시지를 구분할 수 있는 키값을 추출한다. + * 3. 주의사항 + * + * @param message Object 타입의 요청메시지 + * @return String 비표준메시지의 메시지키값 + * @exception + **/ + public String[] perform(Object message) throws ActionException + { + byte[] tmp = null; + String key[] = null; + + String adptGrpName = adapterGroupName; + String requestMethod = prop.getProperty(HttpAdapterServiceRest.PROPERTIES_NAME_HTTP_REQUEST_METHOD); + + if(message instanceof byte[]) { + try { + key = MessageKeyExtractor.getMessageKeyValue(this.adapterGroupName, message); + } catch(Exception e) { + throw new ActionException(ExceptionUtil.getErrorCode(e, "RECEAIIRA001")); + } + tmp = (byte[])message; + if (logger.isInfo()) logger.info(adapterName+"] received data >> "+ new String(tmp)); + } else { + try { + key = MessageKeyExtractor.getMessageKeyValue(this.adapterGroupName, message); + } catch(Exception e) { + throw new ActionException(ExceptionUtil.getErrorCode(e, "RECEAIIRA001")); + } + if (logger.isInfo()) logger.info(adapterName+"] received data >> "+ message); + } + + String baseMessageKey = adptGrpName.trim() + STEMSG_METHOD_DELIMITER + requestMethod + STEMSG_SERVICE_HEADER_DELIMITER; + for(int i=0; i Date: Wed, 10 Dec 2025 23:10:09 +0900 Subject: [PATCH 033/159] =?UTF-8?q?HTT=20=EC=96=B4=EB=8C=91=ED=84=B0?= =?UTF-8?q?=EB=A1=9C=20=EB=93=A4=EC=96=B4=EC=98=A4=EB=8A=94=EA=B1=B0?= =?UTF-8?q?=EB=9E=98=EB=8A=94=20Prop=EC=97=90=20=EC=84=9C=EB=B9=84?= =?UTF-8?q?=EC=8A=A4=EC=BD=94=EB=93=9C=EA=B0=80=20=EC=97=86=EC=9D=8C.=20->?= =?UTF-8?q?=20=EA=B8=B0=EC=A1=B4=EB=A1=9C=EC=A7=81=20=ED=83=80=EB=8F=84?= =?UTF-8?q?=EB=A1=9D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/com/eactive/eai/inbound/processor/RequestProcessor.java | 1 + 1 file changed, 1 insertion(+) diff --git a/src/main/java/com/eactive/eai/inbound/processor/RequestProcessor.java b/src/main/java/com/eactive/eai/inbound/processor/RequestProcessor.java index 54b1a12..d52a5c4 100644 --- a/src/main/java/com/eactive/eai/inbound/processor/RequestProcessor.java +++ b/src/main/java/com/eactive/eai/inbound/processor/RequestProcessor.java @@ -345,6 +345,7 @@ public class RequestProcessor extends RequestProcessorSupport { //String eaiSvcCd = mapper.getEaiSvcCode(standardMessage); // commnet by jwhong String eaiSvcCd = prop.getProperty("API_SERVICE_CODE"); System.out.println("***** eaiSvcCd is"+ eaiSvcCd); + if (StringUtils.isEmpty(eaiSvcCd)) eaiSvcCd = mapper.getEaiSvcCode(standardMessage); // HTT 어댑터로 들어오는거래는 Prop에 서비스코드가 없음. String guid = mapper.getGuid(standardMessage); String guidSeq = mapper.getGuidSeq(standardMessage); String returnType = mapper.getSendRecvDivision(standardMessage); // S|R From 408f492492899887e328151635cf5f0f0360f29b Mon Sep 17 00:00:00 2001 From: "Yunsam.Eo" Date: Wed, 10 Dec 2025 23:11:08 +0900 Subject: [PATCH 034/159] =?UTF-8?q?Bypass=20=EC=96=B4=EB=8C=91=ED=84=B0?= =?UTF-8?q?=EC=9D=98=20Simulator=20=EC=84=A4=EC=A0=95=EC=B2=98=EB=A6=AC=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/com/eactive/eai/outbound/RESTProcess.java | 1 + 1 file changed, 1 insertion(+) diff --git a/src/main/java/com/eactive/eai/outbound/RESTProcess.java b/src/main/java/com/eactive/eai/outbound/RESTProcess.java index 77e1d9d..bc4f0cf 100644 --- a/src/main/java/com/eactive/eai/outbound/RESTProcess.java +++ b/src/main/java/com/eactive/eai/outbound/RESTProcess.java @@ -501,6 +501,7 @@ public class RESTProcess extends HTTPProcess { String url = StringUtils.removeEnd(simAddr, "/") + "/mockapi/" + this.reqEaiMsg.getEAISvcCd(); this.outboundProp.put(HttpClientAdapterServiceKey.URL, url); + this.tempProp.remove(HttpAdapterServiceKey.INBOUND_REWRITE_PATH); logger.debug("simUrl=" + url); } } catch (Exception e) { From 39244dc0dff721b41ec1ab2e9703001551f49a2c Mon Sep 17 00:00:00 2001 From: yunjy-hp Date: Thu, 11 Dec 2025 10:04:24 +0900 Subject: [PATCH 035/159] =?UTF-8?q?inflow=20group=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ReloadInflowGroupControlCommand.java | 56 ++++++ .../RemoveInflowGroupControlCommand.java | 45 +++++ .../com/eactive/eai/common/inflow/Bucket.java | 5 + .../eai/common/inflow/InflowControlDAO.java | 95 ++++++++++ .../common/inflow/InflowControlManager.java | 172 ++++++++++++++++++ .../eai/common/inflow/InflowGroupVO.java | 102 +++++++++++ .../mapper/HttpAdapterExtraHeaderMapper.java | 22 --- .../inbound/processor/RequestProcessor.java | 42 ++++- 8 files changed, 508 insertions(+), 31 deletions(-) create mode 100644 src/main/java/com/eactive/eai/agent/inflow/ReloadInflowGroupControlCommand.java create mode 100644 src/main/java/com/eactive/eai/agent/inflow/RemoveInflowGroupControlCommand.java create mode 100644 src/main/java/com/eactive/eai/common/inflow/InflowGroupVO.java delete mode 100644 src/main/java/com/eactive/eai/common/logger/mapper/HttpAdapterExtraHeaderMapper.java diff --git a/src/main/java/com/eactive/eai/agent/inflow/ReloadInflowGroupControlCommand.java b/src/main/java/com/eactive/eai/agent/inflow/ReloadInflowGroupControlCommand.java new file mode 100644 index 0000000..0582f01 --- /dev/null +++ b/src/main/java/com/eactive/eai/agent/inflow/ReloadInflowGroupControlCommand.java @@ -0,0 +1,56 @@ +package com.eactive.eai.agent.inflow; + +import com.eactive.eai.agent.command.Command; +import com.eactive.eai.agent.command.CommandException; +import com.eactive.eai.common.inflow.InflowControlManager; +import com.eactive.eai.common.util.Logger; + +public class ReloadInflowGroupControlCommand extends Command { + + private static final long serialVersionUID = 1L; + + public ReloadInflowGroupControlCommand() { + super("ReloadInflowGroupControlCommand"); + } + + public Object execute() throws CommandException { + Logger logger = Logger.getLogger(Logger.LOGGER_DEFAULT); + if (logger.isInfo()) + logger.info(this.name + " is executed"); + + if (!(args instanceof String)) { + String rspErrorCode = "RECEAIMCM001"; + String msg = makeException(rspErrorCode, null); + if (logger.isError()) + logger.error(msg); + throw new CommandException(msg); + } + + String keyName = (String) args; + try { + InflowControlManager manager = InflowControlManager.getInstance(); + + if (keyName != null) { + if ("ALL".equals(keyName)) { + manager.reloadGroup(); + if (logger.isWarn()) + logger.warn(this.name + "] all group rule Reload."); + } else { + manager.reloadGroup(keyName); + if (logger.isWarn()) + logger.warn(this.name + "] group " + keyName + " Reload."); + } + } + + } catch (Exception e) { + String rspErrorCode = "RECEAIMCM002"; + String msg = makeException(rspErrorCode, e); + if (logger.isError()) + logger.error(msg, e); + throw new CommandException(msg); + } + return "success"; + + } + +} diff --git a/src/main/java/com/eactive/eai/agent/inflow/RemoveInflowGroupControlCommand.java b/src/main/java/com/eactive/eai/agent/inflow/RemoveInflowGroupControlCommand.java new file mode 100644 index 0000000..a4bdf03 --- /dev/null +++ b/src/main/java/com/eactive/eai/agent/inflow/RemoveInflowGroupControlCommand.java @@ -0,0 +1,45 @@ +package com.eactive.eai.agent.inflow; + +import com.eactive.eai.agent.command.Command; +import com.eactive.eai.agent.command.CommandException; +import com.eactive.eai.common.inflow.InflowControlManager; +import com.eactive.eai.common.util.Logger; + +public class RemoveInflowGroupControlCommand extends Command { + + private static final long serialVersionUID = 1L; + + public RemoveInflowGroupControlCommand() { + super("RemoveInflowGroupControlCommand"); + } + + public Object execute() throws CommandException { + Logger logger = Logger.getLogger(Logger.LOGGER_DEFAULT); + if (logger.isInfo()) + logger.info(this.name + " is executed"); + + if (!(args instanceof String)) { + String rspErrorCode = "RECEAIMCM001"; + String msg = makeException(rspErrorCode, null); + if (logger.isError()) + logger.error(msg); + throw new CommandException(msg); + } + + String key = (String) args; + try { + InflowControlManager manager = InflowControlManager.getInstance(); + manager.removeGroup(key); + if (logger.isWarn()) + logger.warn(this.name + "] group " + key + " removed."); + } catch (Exception e) { + String rspErrorCode = "RECEAIMCM002"; + String msg = makeException(rspErrorCode, e); + if (logger.isError()) + logger.error(msg, e); + throw new CommandException(msg); + } + return "success"; + } + +} diff --git a/src/main/java/com/eactive/eai/common/inflow/Bucket.java b/src/main/java/com/eactive/eai/common/inflow/Bucket.java index 51db277..3896171 100644 --- a/src/main/java/com/eactive/eai/common/inflow/Bucket.java +++ b/src/main/java/com/eactive/eai/common/inflow/Bucket.java @@ -6,4 +6,9 @@ public interface Bucket { public InflowTargetVO getAdapterInflowThreashold(String adapter); public InflowTargetVO getInterfaceInflowThreashold(String inter); public InflowTargetVO getInflowThreashold(String inter); + + // 그룹 관련 메서드 + public boolean isGroupPass(String groupId); + public InflowGroupVO getGroupInflowThreshold(String groupId); + public String getGroupIdByInterface(String interfaceId); } diff --git a/src/main/java/com/eactive/eai/common/inflow/InflowControlDAO.java b/src/main/java/com/eactive/eai/common/inflow/InflowControlDAO.java index b294bc7..8ff7b3a 100644 --- a/src/main/java/com/eactive/eai/common/inflow/InflowControlDAO.java +++ b/src/main/java/com/eactive/eai/common/inflow/InflowControlDAO.java @@ -12,10 +12,14 @@ import org.springframework.transaction.annotation.Transactional; import com.eactive.eai.common.dao.BaseDAO; import com.eactive.eai.common.dao.DAOException; import com.eactive.eai.common.exception.ExceptionUtil; +import com.eactive.eai.common.inflow.loader.InflowControlGroupLoader; +import com.eactive.eai.common.inflow.loader.InflowControlGroupMappingLoader; import com.eactive.eai.common.inflow.loader.InflowControlLoader; import com.eactive.eai.common.inflow.loader.InflowControlLogLogger; import com.eactive.eai.common.util.Logger; import com.eactive.eai.data.entity.onl.inflow.InflowControl; +import com.eactive.eai.data.entity.onl.inflow.InflowControlGroup; +import com.eactive.eai.data.entity.onl.inflow.InflowControlGroupMapping; import com.eactive.eai.data.entity.onl.inflow.InflowControlLog; import com.eactive.eai.data.entity.onl.inflow.InflowControlLogId; @@ -30,6 +34,12 @@ public class InflowControlDAO extends BaseDAO { @Autowired private InflowControlLogLogger inflowControlLogLogger; + @Autowired + private InflowControlGroupLoader inflowControlGroupLoader; + + @Autowired + private InflowControlGroupMappingLoader inflowControlGroupMappingLoader; + public List getInflowAdapterList() throws DAOException { return getInflowList("01"); } @@ -132,4 +142,89 @@ public class InflowControlDAO extends BaseDAO { throw new DAOException(ExceptionUtil.getErrorCode(e, "RECEAICMM101")); } } + + // ==================== 그룹 관련 메서드 ==================== + + /** + * 활성화된 유량제어 그룹 목록 조회 + */ + public List getInflowGroupList() throws DAOException { + try { + Iterable groups = inflowControlGroupLoader.findActiveGroups(); + List groupList = new ArrayList<>(); + logger.info("[ @@ Load InflowControlGroup Configuration - starting >>>>>>>>>>>>>>>>> ]"); + + for (InflowControlGroup group : groups) { + InflowGroupVO vo = convertToGroupVO(group); + // 그룹에 속한 인터페이스 목록 조회 + Iterable mappings = inflowControlGroupMappingLoader.findActiveByGroupId(group.getGroupId()); + for (InflowControlGroupMapping mapping : mappings) { + vo.addInterface(mapping.getInterfaceId()); + } + groupList.add(vo); + } + logger.info("[>>Load InflowControlGroup Configuration - ended. count=" + groupList.size() + " ]"); + return groupList; + } catch (Exception e) { + throw new DAOException(ExceptionUtil.getErrorCode(e, "RECEAICMM101")); + } + } + + /** + * 인터페이스ID → 그룹ID 매핑 조회 + */ + public Map getInterfaceToGroupMap() throws DAOException { + try { + Iterable mappings = inflowControlGroupMappingLoader.findActiveMappings(); + Map interfaceToGroupMap = new HashMap<>(); + logger.info("[ @@ Load InterfaceToGroupMap Configuration - starting >>>>>>>>>>>>>>>>> ]"); + + for (InflowControlGroupMapping mapping : mappings) { + interfaceToGroupMap.put(mapping.getInterfaceId(), mapping.getGroupId()); + } + logger.info("[>>Load InterfaceToGroupMap Configuration - ended. count=" + interfaceToGroupMap.size() + " ]"); + return interfaceToGroupMap; + } catch (Exception e) { + throw new DAOException(ExceptionUtil.getErrorCode(e, "RECEAICMM101")); + } + } + + /** + * 특정 그룹 조회 + */ + public Map getInflowTargetByGroup(String groupId) throws DAOException { + try { + Iterable groups = inflowControlGroupLoader.findByConditions(groupId); + Map groupMap = new HashMap<>(); + logger.info("[ @@ Load InflowControlGroup getInflowTargetByGroup Configuration - starting >>>>>>>>>>>>>>>>> ]"); + + for (InflowControlGroup group : groups) { + InflowGroupVO vo = convertToGroupVO(group); + // 그룹에 속한 인터페이스 목록 조회 + Iterable mappings = inflowControlGroupMappingLoader.findActiveByGroupId(group.getGroupId()); + for (InflowControlGroupMapping mapping : mappings) { + vo.addInterface(mapping.getInterfaceId()); + } + groupMap.put(vo.getGroupId(), vo); + } + logger.info("[>>Load InflowControlGroup getInflowTargetByGroup Configuration - ended ]"); + return groupMap; + } catch (Exception e) { + throw new DAOException(ExceptionUtil.getErrorCode(e, "RECEAICMM101")); + } + } + + /** + * Entity → VO 변환 + */ + private InflowGroupVO convertToGroupVO(InflowControlGroup group) { + InflowGroupVO vo = new InflowGroupVO(); + vo.setGroupId(group.getGroupId()); + vo.setGroupName(group.getGroupName()); + vo.setThreshold(group.getThreshold() != null ? group.getThreshold() : 0); + vo.setThresholdPerSecond(group.getThresholdPerSecond() != null ? group.getThresholdPerSecond() : 0); + vo.setThresholdTimeUnit(group.getThresholdTimeUnit()); + vo.setActivate(!"0".equals(group.getUseYn())); + return vo; + } } \ No newline at end of file diff --git a/src/main/java/com/eactive/eai/common/inflow/InflowControlManager.java b/src/main/java/com/eactive/eai/common/inflow/InflowControlManager.java index 1f33788..5b2d6d3 100644 --- a/src/main/java/com/eactive/eai/common/inflow/InflowControlManager.java +++ b/src/main/java/com/eactive/eai/common/inflow/InflowControlManager.java @@ -40,6 +40,9 @@ public class InflowControlManager implements Lifecycle, Bucket { private Map adapterBucketList = new HashMap<>(); private Map interfaceBucketList = new HashMap<>(); + private Map groupBucketList = new HashMap<>(); + private Map interfaceToGroupMap = new HashMap<>(); + private Map groupVoMap = new HashMap<>(); private boolean started; private LifecycleSupport lifecycle = new LifecycleSupport(this); @@ -91,6 +94,7 @@ public class InflowControlManager implements Lifecycle, Bucket { private void init() throws Exception { initAdapter(); initInterface(); + initGroup(); } private void initAdapter() throws Exception { @@ -121,6 +125,33 @@ public class InflowControlManager implements Lifecycle, Bucket { } } + private void initGroup() throws Exception { + groupBucketList = new HashMap<>(); + interfaceToGroupMap = new HashMap<>(); + groupVoMap = new HashMap<>(); + + List inflowGroupVoList = inflowControlDAO.getInflowGroupList(); + + for (InflowGroupVO groupVo : inflowGroupVoList) { + if (isInflowGroupTarget(groupVo)) { + CustomBucket bucket = makeBucketUsingGroupVO(groupVo); + if (bucket != null) { + groupBucketList.put(groupVo.getGroupId(), bucket); + groupVoMap.put(groupVo.getGroupId(), groupVo); + // 인터페이스 → 그룹 매핑 등록 + for (String interfaceId : groupVo.getInterfaceList()) { + interfaceToGroupMap.put(interfaceId, groupVo.getGroupId()); + } + } + } + } + + if (logger.isInfo()) { + logger.info("InflowControlManager] initGroup completed. groups=" + groupBucketList.size() + + ", mappings=" + interfaceToGroupMap.size()); + } + } + public synchronized void reloadAdapter() throws Exception { if (logger.isWarn()) { logger.warn("InflowControlManager] reload all Started ..."); @@ -200,6 +231,61 @@ public class InflowControlManager implements Lifecycle, Bucket { } } + public synchronized void reloadGroup() throws Exception { + if (logger.isWarn()) { + logger.warn("InflowControlManager] reloadGroup all Started ..."); + } + initGroup(); + if (logger.isWarn()) { + logger.warn("InflowControlManager] reloadGroup all finished ..."); + } + } + + public synchronized void reloadGroup(String groupId) throws Exception { + if (logger.isWarn()) { + logger.warn("InflowControlManager] reloadGroup Started ... groupId=" + groupId); + } + Map map = inflowControlDAO.getInflowTargetByGroup(groupId); + if (map != null) { + // 기존 그룹에 속한 인터페이스 매핑 제거 + Iterator> mappingIt = interfaceToGroupMap.entrySet().iterator(); + while (mappingIt.hasNext()) { + Map.Entry entry = mappingIt.next(); + if (groupId.equals(entry.getValue())) { + mappingIt.remove(); + } + } + + Iterator it = map.keySet().iterator(); + while (it.hasNext()) { + String key = it.next(); + InflowGroupVO groupVo = map.get(key); + + if (isInflowGroupTarget(groupVo)) { + CustomBucket bucket = makeBucketUsingGroupVO(groupVo); + if (bucket != null) { + groupBucketList.put(groupVo.getGroupId(), bucket); + groupVoMap.put(groupVo.getGroupId(), groupVo); + // 인터페이스 → 그룹 매핑 재등록 + for (String interfaceId : groupVo.getInterfaceList()) { + interfaceToGroupMap.put(interfaceId, groupVo.getGroupId()); + } + } else { + groupBucketList.remove(groupVo.getGroupId()); + groupVoMap.remove(groupVo.getGroupId()); + } + } else { + groupBucketList.remove(groupVo.getGroupId()); + groupVoMap.remove(groupVo.getGroupId()); + } + } + } + + if (logger.isWarn()) { + logger.warn("InflowControlManager] reloadGroup finished ..."); + } + } + public void stop() throws LifecycleException { // Validate and update our current component state if (!started) @@ -210,6 +296,9 @@ public class InflowControlManager implements Lifecycle, Bucket { adapterBucketList.clear(); interfaceBucketList.clear(); + groupBucketList.clear(); + interfaceToGroupMap.clear(); + groupVoMap.clear(); started = false; // Notify our interested LifecycleListeners @@ -260,6 +349,29 @@ public class InflowControlManager implements Lifecycle, Bucket { interfaceBucketList.remove(inter); } + public void removeGroup(String groupId) { + groupBucketList.remove(groupId); + groupVoMap.remove(groupId); + // 해당 그룹에 속한 인터페이스 매핑도 제거 + Iterator> it = interfaceToGroupMap.entrySet().iterator(); + while (it.hasNext()) { + Map.Entry entry = it.next(); + if (groupId.equals(entry.getValue())) { + it.remove(); + } + } + } + + public String[] getGroupAllKeys() { + Iterator it = this.groupBucketList.keySet().iterator(); + String[] groupIds = new String[this.groupBucketList.size()]; + for (int i = 0; it.hasNext(); i++) { + groupIds[i] = it.next(); + } + Arrays.sort(groupIds); + return groupIds; + } + private CustomBucket makeBucketUsingInflowVO(InflowTargetVO inflowTarget) { if (InflowControlManager.isInflowTarget(inflowTarget)) { LocalBucketBuilder builder = Bucket4j.builder(); @@ -278,6 +390,32 @@ public class InflowControlManager implements Lifecycle, Bucket { return null; } + private CustomBucket makeBucketUsingGroupVO(InflowGroupVO groupVo) { + if (isInflowGroupTarget(groupVo)) { + LocalBucketBuilder builder = Bucket4j.builder(); + if (groupVo.getThresholdPerSecond() > 0) { + builder.addLimit(Bandwidth.simple(groupVo.getThresholdPerSecond(), Duration.ofSeconds(1))); + } + + if (groupVo.getThreshold() > 0 && StringUtils.isNotBlank(groupVo.getThresholdTimeUnit())) { + builder.addLimit(Bandwidth.simple(groupVo.getThreshold(), + InflowControlManager.getPeriod(groupVo.getThresholdTimeUnit()))); + } + + // InflowTargetVO로 변환하여 CustomBucket 생성 + InflowTargetVO targetVo = new InflowTargetVO(); + targetVo.setName(groupVo.getGroupId()); + targetVo.setThreshold(groupVo.getThreshold()); + targetVo.setThresholdPerSecond(groupVo.getThresholdPerSecond()); + targetVo.setThresholdTimeUnit(groupVo.getThresholdTimeUnit()); + targetVo.setActivate(groupVo.isActivate()); + + return new CustomBucket(builder.build(), targetVo); + } + + return null; + } + @Override public boolean isAdapterPass(String adapter) { CustomBucket b = adapterBucketList.get(adapter); @@ -327,6 +465,30 @@ public class InflowControlManager implements Lifecycle, Bucket { return getInterfaceInflowThreashold(inter); } + @Override + public boolean isGroupPass(String groupId) { + CustomBucket b = groupBucketList.get(groupId); + + if (b == null) + return true; + + return b.getLocalBucket().tryConsume(1); + } + + @Override + public InflowGroupVO getGroupInflowThreshold(String groupId) { + return groupVoMap.get(groupId); + } + + @Override + public String getGroupIdByInterface(String interfaceId) { + return interfaceToGroupMap.get(interfaceId); + } + + public InflowGroupVO getGroupInflow(String groupId) { + return getGroupInflowThreshold(groupId); + } + public static boolean isInflowTarget(InflowTargetVO inflowTarget) { if (inflowTarget == null || !inflowTarget.isActivate()) { return false; @@ -338,6 +500,16 @@ public class InflowControlManager implements Lifecycle, Bucket { } + public static boolean isInflowGroupTarget(InflowGroupVO groupVo) { + if (groupVo == null || !groupVo.isActivate()) { + return false; + } + + return groupVo.getThresholdPerSecond() > 0 || (groupVo.getThreshold() > 0 && StringUtils + .equalsAnyIgnoreCase(groupVo.getThresholdTimeUnit(), QUOTA_TIMEUNIT_DAY, QUOTA_TIMEUNIT_SECOND, + QUOTA_TIMEUNIT_MINUTE, QUOTA_TIMEUNIT_HOUR, QUOTA_TIMEUNIT_DAY, QUOTA_TIMEUNIT_MONTH)); + } + public static Duration getPeriod(String timeUnit) { if (StringUtils.equalsIgnoreCase(timeUnit, QUOTA_TIMEUNIT_SECOND)) { return Duration.ofSeconds(1); diff --git a/src/main/java/com/eactive/eai/common/inflow/InflowGroupVO.java b/src/main/java/com/eactive/eai/common/inflow/InflowGroupVO.java new file mode 100644 index 0000000..4c05bdc --- /dev/null +++ b/src/main/java/com/eactive/eai/common/inflow/InflowGroupVO.java @@ -0,0 +1,102 @@ +package com.eactive.eai.common.inflow; + +import java.io.Serializable; +import java.util.ArrayList; +import java.util.List; + +@SuppressWarnings("serial") +public class InflowGroupVO implements Serializable { + private String groupId; + private String groupName; + private long thresholdPerSecond; + private long threshold; + private String thresholdTimeUnit; + private boolean activate; + private List interfaceList = new ArrayList<>(); + + @Override + public boolean equals(Object obj) { + if (obj instanceof InflowGroupVO) { + return groupId.equals(((InflowGroupVO) obj).getGroupId()); + } + return false; + } + + @Override + public int hashCode() { + return groupId != null ? groupId.hashCode() : 0; + } + + public String getGroupId() { + return groupId; + } + + public void setGroupId(String groupId) { + this.groupId = groupId; + } + + public String getGroupName() { + return groupName; + } + + public void setGroupName(String groupName) { + this.groupName = groupName; + } + + public long getThresholdPerSecond() { + return thresholdPerSecond; + } + + public void setThresholdPerSecond(long thresholdPerSecond) { + this.thresholdPerSecond = thresholdPerSecond; + } + + public long getThreshold() { + return threshold; + } + + public void setThreshold(long threshold) { + this.threshold = threshold; + } + + public String getThresholdTimeUnit() { + return thresholdTimeUnit; + } + + public void setThresholdTimeUnit(String thresholdTimeUnit) { + this.thresholdTimeUnit = thresholdTimeUnit; + } + + public boolean isActivate() { + return activate; + } + + public void setActivate(boolean activate) { + this.activate = activate; + } + + public List getInterfaceList() { + return interfaceList; + } + + public void setInterfaceList(List interfaceList) { + this.interfaceList = interfaceList; + } + + public void addInterface(String interfaceId) { + if (this.interfaceList == null) { + this.interfaceList = new ArrayList<>(); + } + this.interfaceList.add(interfaceId); + } + + @Override + public String toString() { + return "InflowGroupVO [groupId=" + groupId + ", groupName=" + groupName + + ", thresholdPerSecond=" + thresholdPerSecond + + ", threshold=" + threshold + + ", thresholdTimeUnit=" + thresholdTimeUnit + + ", activate=" + activate + + ", interfaceCount=" + (interfaceList != null ? interfaceList.size() : 0) + "]"; + } +} diff --git a/src/main/java/com/eactive/eai/common/logger/mapper/HttpAdapterExtraHeaderMapper.java b/src/main/java/com/eactive/eai/common/logger/mapper/HttpAdapterExtraHeaderMapper.java deleted file mode 100644 index b609dee..0000000 --- a/src/main/java/com/eactive/eai/common/logger/mapper/HttpAdapterExtraHeaderMapper.java +++ /dev/null @@ -1,22 +0,0 @@ -//package com.eactive.eai.common.logger.mapper; -// -//import com.eactive.eai.common.logger.HttpAdapterExtraHeaderVo; -//import com.eactive.eai.data.entity.onl.logger.HttpAdapterExtraHeader; -//import com.eactive.eai.data.mapper.BaseMapperConfig; -//import com.eactive.eai.data.mapper.GenericMapper; -// -//import org.mapstruct.InheritInverseConfiguration; -//import org.mapstruct.Mapper; -//import org.mapstruct.Mapping; -// -//@Mapper(config = BaseMapperConfig.class) -//public interface HttpAdapterExtraHeaderMapper extends GenericMapper { -// -// @Override -// @Mapping(source = "id.name", target = "name") -// HttpAdapterExtraHeaderVo toVo(HttpAdapterExtraHeader entity); -// -// @Override -// @InheritInverseConfiguration -// HttpAdapterExtraHeader toEntity(HttpAdapterExtraHeaderVo vo); -//} diff --git a/src/main/java/com/eactive/eai/inbound/processor/RequestProcessor.java b/src/main/java/com/eactive/eai/inbound/processor/RequestProcessor.java index 54b1a12..5ed8d8b 100644 --- a/src/main/java/com/eactive/eai/inbound/processor/RequestProcessor.java +++ b/src/main/java/com/eactive/eai/inbound/processor/RequestProcessor.java @@ -27,6 +27,7 @@ import com.eactive.eai.common.exception.ExceptionUtil; import com.eactive.eai.common.inflow.Bucket; import com.eactive.eai.common.inflow.InflowControlDAO; import com.eactive.eai.common.inflow.InflowControlUtil; +import com.eactive.eai.common.inflow.InflowGroupVO; import com.eactive.eai.common.inflow.InflowTargetVO; import com.eactive.eai.common.logger.EAILogSender; import com.eactive.eai.common.message.EAIMessage; @@ -1014,24 +1015,39 @@ public class RequestProcessor extends RequestProcessorSupport { Bucket bucket = InflowControlUtil.getBucket(); String blockedType = ""; + // Adapter 유량제어 체크 if (!bucket.isAdapterPass(vo.getAdapterGroupName())) { blockedType += "A"; } - if (!bucket.isInterfacePass(vo.getEaiSvcCd())) { - blockedType += "I"; + // 그룹 우선, 없으면 인터페이스 유량제어 체크 + String groupId = bucket.getGroupIdByInterface(vo.getEaiSvcCd()); + if (groupId != null) { + // 그룹에 속한 인터페이스 → 그룹 유량제어 체크 + if (!bucket.isGroupPass(groupId)) { + blockedType += "G"; + } + } else { + // 그룹에 속하지 않은 인터페이스 → 인터페이스 유량제어 체크 + if (!bucket.isInterfacePass(vo.getEaiSvcCd())) { + blockedType += "I"; + } } if (blockedType.length() > 0) { InflowTargetVO inflowTargetVO = null; + InflowGroupVO inflowGroupVO = null; if (blockedType.startsWith("A")) { inflowTargetVO = bucket.getAdapterInflowThreashold(vo.getAdapterGroupName()); + } else if (blockedType.contains("G")) { + inflowGroupVO = bucket.getGroupInflowThreshold(groupId); } else { inflowTargetVO = bucket.getInterfaceInflowThreashold(vo.getEaiSvcCd()); } // 에러처리 vo.setRspErrorCode(EAIMessageKeys.EAI_INFLOW_BLOCKED_CODE); - vo.setRspErrorMsg(ExceptionUtil.make(vo.getRspErrorCode(), vo.getEaiSvcCd() ) + ", " - + inflowTargetVO.toString()); + String inflowInfo = (inflowGroupVO != null) ? inflowGroupVO.toString() : + (inflowTargetVO != null ? inflowTargetVO.toString() : "N/A"); + vo.setRspErrorMsg(ExceptionUtil.make(vo.getRspErrorCode(), vo.getEaiSvcCd() ) + ", " + inflowInfo); // eaiMsg.setRspErrCd(vo.getRspErrorCode()); // eaiMsg.setRspErrMsg(vo.getRspErrorMsg()); @@ -1040,16 +1056,21 @@ public class RequestProcessor extends RequestProcessorSupport { try { Properties inFlowProp = PropManager.getInstance().getProperties("INFLOW"); String controlInflowHistory = inFlowProp.getProperty("inflow.control.history.yn", "N"); - if (StringUtils.equalsIgnoreCase(controlInflowHistory, "Y") && inflowTargetVO != null) { + if (StringUtils.equalsIgnoreCase(controlInflowHistory, "Y") && (inflowTargetVO != null || inflowGroupVO != null)) { DAOFactory factory = DAOFactory.newInstance(); // InflowControlDAO restrictDao = (InflowControlDAO) factory.create(InflowControlDAO.class); // InflowControlDAO를 서비스로 만들어서 factory.create로 하면 안됨. InflowControlDAO restrictDao = (InflowControlDAO) ApplicationContextProvider.getContext().getBean(InflowControlDAO.class); + // 그룹 유량제어 정보가 있으면 그룹 정보로, 없으면 기존 inflowTargetVO 정보로 로그 + long thresholdPerSecond = (inflowGroupVO != null) ? inflowGroupVO.getThresholdPerSecond() : inflowTargetVO.getThresholdPerSecond(); + long threshold = (inflowGroupVO != null) ? inflowGroupVO.getThreshold() : inflowTargetVO.getThreshold(); + String thresholdTimeUnit = (inflowGroupVO != null) ? inflowGroupVO.getThresholdTimeUnit() : inflowTargetVO.getThresholdTimeUnit(); + String logGroupName = (inflowGroupVO != null) ? inflowGroupVO.getGroupId() : vo.getAdapterGroupName(); + restrictDao.addInflowServicetLog(eaiMsg.getBwkCls(), DatetimeUtil.getCurrentTime(eaiMsg.getMsgRcvTm()), eaiMsg.getSvcOgNo(), - eaiServerManager.getLocalServerName(), eaiMsg.getEAISvcCd(), vo.getAdapterGroupName(), - inflowTargetVO.getThresholdPerSecond(), inflowTargetVO.getThreshold(), - inflowTargetVO.getThresholdTimeUnit()); + eaiServerManager.getLocalServerName(), eaiMsg.getEAISvcCd(), logGroupName, + thresholdPerSecond, threshold, thresholdTimeUnit); } } catch (Exception ex) { if (logger.isError()) { @@ -1060,7 +1081,10 @@ public class RequestProcessor extends RequestProcessorSupport { sb.append("EAISevrInstncName [" + eaiServerManager.getLocalServerName() + "]\n"); sb.append("EAISvcName [" + eaiMsg.getEAISvcCd() + "]\n"); sb.append("ADPTRBZWKGROUPNAME[" + vo.getAdapterGroupName() + "]\n"); - sb.append("InflowTargetVO [" + inflowTargetVO.toString() + "]\n"); + sb.append("InflowInfo [" + inflowInfo + "]\n"); + if (groupId != null) { + sb.append("InflowGroupId [" + groupId + "]\n"); + } logger.error(guidLogPrefix + " 유량제어 건수 Log 실패 - " + ex.toString() + "\n" + sb.toString()); } From d326ffc373f01b40142549080d4b6c3a1b353bda Mon Sep 17 00:00:00 2001 From: yunjy-hp Date: Thu, 11 Dec 2025 11:04:11 +0900 Subject: [PATCH 036/159] =?UTF-8?q?feat:=20=EC=9C=A0=EB=9F=89=EC=A0=9C?= =?UTF-8?q?=EC=96=B4=20=EA=B7=B8=EB=A3=B9=20=EB=B2=84=ED=82=B7=20=EB=B6=84?= =?UTF-8?q?=EB=A6=AC=20=EB=B0=8F=20=ED=98=84=ED=99=A9=20=ED=99=94=EB=A9=B4?= =?UTF-8?q?=20=EA=B0=9C=EC=84=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - CustomGroupBucket 클래스 신규 생성: 초당/추가 임계치를 별도 LocalBucket으로 분리하여 개별 토큰 조회 가능 - InflowControlManager 수정: groupBucketList 타입을 CustomGroupBucket으로 변경, makeGroupBucket() 메서드 추가 - InflowGroupBucketService 단순화: 복잡한 리플렉션 로직 제거, CustomGroupBucket 직접 메서드 사용 - 현황 탭에 전체 인스턴스 합산 요약 추가 (활성 인스턴스 수, 초당/추가 임계치 합산) - 추가 임계치 시간단위에서 '초(SEC)' 옵션 제거 - 저장 완료 후 리스트 화면 이동 제거 --- .../eai/common/inflow/CustomGroupBucket.java | 77 +++++++++++++++++++ .../common/inflow/InflowControlManager.java | 58 +++++++------- 2 files changed, 108 insertions(+), 27 deletions(-) create mode 100644 src/main/java/com/eactive/eai/common/inflow/CustomGroupBucket.java diff --git a/src/main/java/com/eactive/eai/common/inflow/CustomGroupBucket.java b/src/main/java/com/eactive/eai/common/inflow/CustomGroupBucket.java new file mode 100644 index 0000000..296fb15 --- /dev/null +++ b/src/main/java/com/eactive/eai/common/inflow/CustomGroupBucket.java @@ -0,0 +1,77 @@ +package com.eactive.eai.common.inflow; + +import io.github.bucket4j.local.LocalBucket; + +/** + * 그룹 유량제어 전용 버킷 + * 초당 임계치와 추가 임계치를 별도 버킷으로 관리하여 개별 토큰 조회 가능 + */ +public class CustomGroupBucket { + private LocalBucket perSecondBucket; // 초당 임계치 버킷 (null 가능) + private LocalBucket thresholdBucket; // 추가 임계치 버킷 (null 가능) + private InflowGroupVO groupVo; + + public CustomGroupBucket(LocalBucket perSecondBucket, LocalBucket thresholdBucket, InflowGroupVO groupVo) { + this.perSecondBucket = perSecondBucket; + this.thresholdBucket = thresholdBucket; + this.groupVo = groupVo; + } + + /** + * 두 버킷 모두에서 토큰 소비 시도 + * @return 모든 버킷에서 소비 성공 시 true + */ + public boolean tryConsume() { + boolean perSecondPass = (perSecondBucket == null) || perSecondBucket.tryConsume(1); + if (!perSecondPass) { + return false; + } + + boolean thresholdPass = (thresholdBucket == null) || thresholdBucket.tryConsume(1); + if (!thresholdPass) { + // 초당 버킷에서 이미 소비했으므로 롤백은 불가 (Token Bucket 특성상) + // 하지만 초당 버킷은 빠르게 리필되므로 실질적 영향 미미 + return false; + } + + return true; + } + + /** + * 초당 임계치 버킷의 사용 가능한 토큰 수 + */ + public long getPerSecondAvailableTokens() { + return (perSecondBucket != null) ? perSecondBucket.getAvailableTokens() : -1; + } + + /** + * 추가 임계치 버킷의 사용 가능한 토큰 수 + */ + public long getThresholdAvailableTokens() { + return (thresholdBucket != null) ? thresholdBucket.getAvailableTokens() : -1; + } + + public LocalBucket getPerSecondBucket() { + return perSecondBucket; + } + + public void setPerSecondBucket(LocalBucket perSecondBucket) { + this.perSecondBucket = perSecondBucket; + } + + public LocalBucket getThresholdBucket() { + return thresholdBucket; + } + + public void setThresholdBucket(LocalBucket thresholdBucket) { + this.thresholdBucket = thresholdBucket; + } + + public InflowGroupVO getGroupVo() { + return groupVo; + } + + public void setGroupVo(InflowGroupVO groupVo) { + this.groupVo = groupVo; + } +} diff --git a/src/main/java/com/eactive/eai/common/inflow/InflowControlManager.java b/src/main/java/com/eactive/eai/common/inflow/InflowControlManager.java index 5b2d6d3..29933bf 100644 --- a/src/main/java/com/eactive/eai/common/inflow/InflowControlManager.java +++ b/src/main/java/com/eactive/eai/common/inflow/InflowControlManager.java @@ -27,6 +27,7 @@ import com.ext.eai.common.stdmessage.STDMessageKeys; import io.github.bucket4j.Bandwidth; import io.github.bucket4j.Bucket4j; +import io.github.bucket4j.local.LocalBucket; import io.github.bucket4j.local.LocalBucketBuilder; @Component @@ -40,7 +41,7 @@ public class InflowControlManager implements Lifecycle, Bucket { private Map adapterBucketList = new HashMap<>(); private Map interfaceBucketList = new HashMap<>(); - private Map groupBucketList = new HashMap<>(); + private Map groupBucketList = new HashMap<>(); private Map interfaceToGroupMap = new HashMap<>(); private Map groupVoMap = new HashMap<>(); private boolean started; @@ -134,7 +135,7 @@ public class InflowControlManager implements Lifecycle, Bucket { for (InflowGroupVO groupVo : inflowGroupVoList) { if (isInflowGroupTarget(groupVo)) { - CustomBucket bucket = makeBucketUsingGroupVO(groupVo); + CustomGroupBucket bucket = makeGroupBucket(groupVo); if (bucket != null) { groupBucketList.put(groupVo.getGroupId(), bucket); groupVoMap.put(groupVo.getGroupId(), groupVo); @@ -262,7 +263,7 @@ public class InflowControlManager implements Lifecycle, Bucket { InflowGroupVO groupVo = map.get(key); if (isInflowGroupTarget(groupVo)) { - CustomBucket bucket = makeBucketUsingGroupVO(groupVo); + CustomGroupBucket bucket = makeGroupBucket(groupVo); if (bucket != null) { groupBucketList.put(groupVo.getGroupId(), bucket); groupVoMap.put(groupVo.getGroupId(), groupVo); @@ -390,30 +391,33 @@ public class InflowControlManager implements Lifecycle, Bucket { return null; } - private CustomBucket makeBucketUsingGroupVO(InflowGroupVO groupVo) { - if (isInflowGroupTarget(groupVo)) { - LocalBucketBuilder builder = Bucket4j.builder(); - if (groupVo.getThresholdPerSecond() > 0) { - builder.addLimit(Bandwidth.simple(groupVo.getThresholdPerSecond(), Duration.ofSeconds(1))); - } - - if (groupVo.getThreshold() > 0 && StringUtils.isNotBlank(groupVo.getThresholdTimeUnit())) { - builder.addLimit(Bandwidth.simple(groupVo.getThreshold(), - InflowControlManager.getPeriod(groupVo.getThresholdTimeUnit()))); - } - - // InflowTargetVO로 변환하여 CustomBucket 생성 - InflowTargetVO targetVo = new InflowTargetVO(); - targetVo.setName(groupVo.getGroupId()); - targetVo.setThreshold(groupVo.getThreshold()); - targetVo.setThresholdPerSecond(groupVo.getThresholdPerSecond()); - targetVo.setThresholdTimeUnit(groupVo.getThresholdTimeUnit()); - targetVo.setActivate(groupVo.isActivate()); - - return new CustomBucket(builder.build(), targetVo); + /** + * 그룹용 버킷 생성 - 초당/추가 임계치를 별도 버킷으로 분리 + */ + private CustomGroupBucket makeGroupBucket(InflowGroupVO groupVo) { + if (!isInflowGroupTarget(groupVo)) { + return null; } - return null; + LocalBucket perSecondBucket = null; + LocalBucket thresholdBucket = null; + + // 초당 임계치 버킷 (별도) + if (groupVo.getThresholdPerSecond() > 0) { + perSecondBucket = Bucket4j.builder() + .addLimit(Bandwidth.simple(groupVo.getThresholdPerSecond(), Duration.ofSeconds(1))) + .build(); + } + + // 추가 임계치 버킷 (별도) + if (groupVo.getThreshold() > 0 && StringUtils.isNotBlank(groupVo.getThresholdTimeUnit())) { + thresholdBucket = Bucket4j.builder() + .addLimit(Bandwidth.simple(groupVo.getThreshold(), + InflowControlManager.getPeriod(groupVo.getThresholdTimeUnit()))) + .build(); + } + + return new CustomGroupBucket(perSecondBucket, thresholdBucket, groupVo); } @Override @@ -467,12 +471,12 @@ public class InflowControlManager implements Lifecycle, Bucket { @Override public boolean isGroupPass(String groupId) { - CustomBucket b = groupBucketList.get(groupId); + CustomGroupBucket b = groupBucketList.get(groupId); if (b == null) return true; - return b.getLocalBucket().tryConsume(1); + return b.tryConsume(); } @Override From 51c0cc4f54b528a30a427851c9da1831ec144c22 Mon Sep 17 00:00:00 2001 From: pksup Date: Thu, 11 Dec 2025 13:38:28 +0900 Subject: [PATCH 037/159] =?UTF-8?q?feat:=20=ED=91=9C=EC=A4=80=20JSON=20?= =?UTF-8?q?=EC=98=A4=EB=A5=98=20=EB=A9=94=EC=8B=9C=EC=A7=80=20=EC=83=9D?= =?UTF-8?q?=EC=84=B1=20=EA=B8=B0=EB=8A=A5=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit API 오류 발생 시 일관된 응답을 생성하도록 MessageUtil.makeJsonErrorMessage 메서드를 수정합니다. --- .../eactive/eai/common/util/MessageUtil.java | 69 ++++++++++--------- 1 file changed, 38 insertions(+), 31 deletions(-) diff --git a/src/main/java/com/eactive/eai/common/util/MessageUtil.java b/src/main/java/com/eactive/eai/common/util/MessageUtil.java index fc5c9a9..4304ff1 100644 --- a/src/main/java/com/eactive/eai/common/util/MessageUtil.java +++ b/src/main/java/com/eactive/eai/common/util/MessageUtil.java @@ -1,5 +1,25 @@ package com.eactive.eai.common.util; +import java.io.BufferedInputStream; +import java.io.UnsupportedEncodingException; +import java.nio.charset.Charset; +import java.util.Iterator; + +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; +import javax.xml.xpath.XPath; +import javax.xml.xpath.XPathConstants; +import javax.xml.xpath.XPathFactory; + +import org.apache.commons.lang3.StringUtils; +import org.apache.tools.ant.filters.StringInputStream; +import org.json.simple.JSONArray; +import org.json.simple.JSONObject; +import org.json.simple.JSONValue; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.w3c.dom.Document; + import com.eactive.eai.common.EAIKeys; import com.eactive.eai.common.message.MessageType; import com.eactive.eai.common.monitor.EAIServiceMonitor; @@ -10,30 +30,16 @@ import com.eactive.eai.transformer.util.ISO8583DumpUtil; import com.ext.eai.common.stdmessage.STDMessageErrorKeys; import com.jayway.jsonpath.JsonPath; import com.solab.iso8583.IsoMessage; -import org.apache.commons.lang3.StringUtils; -import org.apache.tools.ant.filters.StringInputStream; -import org.json.simple.JSONArray; -import org.json.simple.JSONObject; -import org.json.simple.JSONValue; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.w3c.dom.Document; - -import javax.xml.parsers.DocumentBuilder; -import javax.xml.parsers.DocumentBuilderFactory; -import javax.xml.xpath.XPath; -import javax.xml.xpath.XPathConstants; -import javax.xml.xpath.XPathFactory; -import java.io.BufferedInputStream; -import java.io.UnsupportedEncodingException; -import java.nio.charset.Charset; -import java.util.Iterator; -import java.util.List; -import java.util.Map; public final class MessageUtil { static Logger logger = LoggerFactory.getLogger(MessageUtil.class); + public static final String ERROR_MESSAGE_DEFAULT_FORMAT = "{\"error\":{\"code\":\"%s\",\"message\":\"%s\"}}"; + + public static final String ERROR_CODE_AP_ERROR = "E.GW.AP_ERROR"; + public static final String ERROR_CODE_AUTH_FAIL = "E.GW.AUTH_FAIL"; + public static final String ERROR_CODE_SERVICE_NOT_FOUND = "E.GW.SERVICE_NOT_FOUND"; + private MessageUtil() { } @@ -492,12 +498,10 @@ public final class MessageUtil { public static String makeErrorMessageByMessageType(String msgType, String msgCharset, String code, String msg, String errorFormat) { - if (StringUtils.equals(msgType, MessageType.JSON)) { - return makeJsonErrorMessage(code, msg, errorFormat); - } else if (StringUtils.equals(msgType, MessageType.XML)) { + if (StringUtils.equals(msgType, MessageType.XML)) { return makeXmlErrorMessage(code, msg, msgCharset, errorFormat); } else { - return "[errCd]" + code + "[/errCd]" + "[errMsg]" + msg + "[/errMsg]"; + return makeJsonErrorMessage(code, msg, errorFormat); } } @@ -510,14 +514,17 @@ public final class MessageUtil { } public static String makeJsonErrorMessage(String code, String msg, String errorFormat) { - if (StringUtils.isNotBlank(errorFormat)) { - try { - return String.format(errorFormat, code, JSONValue.escape(msg)); - } catch (Exception e) { - logger.error(e.getMessage()); - } + if (StringUtils.isBlank(errorFormat)) { + errorFormat = ERROR_MESSAGE_DEFAULT_FORMAT; + } + + // errorFormat에 %s가 1개만 있으면 msg만, 2개 이상이면 code, msg 전달 + int paramCount = StringUtils.countMatches(errorFormat, "%s"); + if (paramCount == 1) { + return String.format(errorFormat, JSONValue.escape(msg)); + } else { + return String.format(errorFormat, code, JSONValue.escape(msg)); } - return String.format("{\"error\":\"%s\",\"error_description\":\"%s\"}", code, JSONValue.escape(msg)); } public static String makeXmlErrorMessage(String code, String msg, String charset, String errorFormat) { From 6b71d4414cfd50cd5bef13f687cb4e5712833317 Mon Sep 17 00:00:00 2001 From: yunjy-hp Date: Thu, 11 Dec 2025 14:27:12 +0900 Subject: [PATCH 038/159] =?UTF-8?q?=EC=9C=A0=EB=9F=89=EC=A0=9C=EC=96=B4=20?= =?UTF-8?q?=EC=98=A4=EB=A5=98=20=EB=A9=94=EC=8B=9C=EC=A7=80=20=EA=B0=9C?= =?UTF-8?q?=EC=84=A0=20->=20API=20=ED=98=B8=EC=B6=9C=20=ED=95=9C=EB=8F=84?= =?UTF-8?q?=20=EC=B4=88=EA=B3=BC=20[=ED=85=8C=EC=8A=A4=ED=8A=B8=20?= =?UTF-8?q?=EA=B7=B8=EB=A3=B91:=2010req/MIN]?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/eactive/eai/common/inflow/Bucket.java | 3 ++- .../eai/common/inflow/CustomGroupBucket.java | 17 ++++++++---- .../common/inflow/InflowControlManager.java | 4 +-- .../session/SessionManagerForEhcache.java | 2 +- .../inbound/processor/RequestProcessor.java | 27 +++++++++++++++---- 5 files changed, 39 insertions(+), 14 deletions(-) diff --git a/src/main/java/com/eactive/eai/common/inflow/Bucket.java b/src/main/java/com/eactive/eai/common/inflow/Bucket.java index 3896171..b0888b0 100644 --- a/src/main/java/com/eactive/eai/common/inflow/Bucket.java +++ b/src/main/java/com/eactive/eai/common/inflow/Bucket.java @@ -8,7 +8,8 @@ public interface Bucket { public InflowTargetVO getInflowThreashold(String inter); // 그룹 관련 메서드 - public boolean isGroupPass(String groupId); + /** @return null이면 통과, "PER_SECOND" 또는 "THRESHOLD"면 해당 버킷에서 차단 */ + public String isGroupPass(String groupId); public InflowGroupVO getGroupInflowThreshold(String groupId); public String getGroupIdByInterface(String interfaceId); } diff --git a/src/main/java/com/eactive/eai/common/inflow/CustomGroupBucket.java b/src/main/java/com/eactive/eai/common/inflow/CustomGroupBucket.java index 296fb15..49d0aba 100644 --- a/src/main/java/com/eactive/eai/common/inflow/CustomGroupBucket.java +++ b/src/main/java/com/eactive/eai/common/inflow/CustomGroupBucket.java @@ -17,24 +17,31 @@ public class CustomGroupBucket { this.groupVo = groupVo; } + /** 소비 결과: 성공 */ + public static final String RESULT_PASS = null; + /** 소비 결과: 초당 임계치 초과 */ + public static final String RESULT_BLOCKED_PER_SECOND = "PER_SECOND"; + /** 소비 결과: 추가 임계치 초과 */ + public static final String RESULT_BLOCKED_THRESHOLD = "THRESHOLD"; + /** * 두 버킷 모두에서 토큰 소비 시도 - * @return 모든 버킷에서 소비 성공 시 true + * @return null이면 성공, "PER_SECOND" 또는 "THRESHOLD"면 해당 버킷에서 차단 */ - public boolean tryConsume() { + public String tryConsume() { boolean perSecondPass = (perSecondBucket == null) || perSecondBucket.tryConsume(1); if (!perSecondPass) { - return false; + return RESULT_BLOCKED_PER_SECOND; } boolean thresholdPass = (thresholdBucket == null) || thresholdBucket.tryConsume(1); if (!thresholdPass) { // 초당 버킷에서 이미 소비했으므로 롤백은 불가 (Token Bucket 특성상) // 하지만 초당 버킷은 빠르게 리필되므로 실질적 영향 미미 - return false; + return RESULT_BLOCKED_THRESHOLD; } - return true; + return RESULT_PASS; } /** diff --git a/src/main/java/com/eactive/eai/common/inflow/InflowControlManager.java b/src/main/java/com/eactive/eai/common/inflow/InflowControlManager.java index 29933bf..9c527fd 100644 --- a/src/main/java/com/eactive/eai/common/inflow/InflowControlManager.java +++ b/src/main/java/com/eactive/eai/common/inflow/InflowControlManager.java @@ -470,11 +470,11 @@ public class InflowControlManager implements Lifecycle, Bucket { } @Override - public boolean isGroupPass(String groupId) { + public String isGroupPass(String groupId) { CustomGroupBucket b = groupBucketList.get(groupId); if (b == null) - return true; + return null; return b.tryConsume(); } diff --git a/src/main/java/com/eactive/eai/common/session/SessionManagerForEhcache.java b/src/main/java/com/eactive/eai/common/session/SessionManagerForEhcache.java index 571afa3..8c876c3 100644 --- a/src/main/java/com/eactive/eai/common/session/SessionManagerForEhcache.java +++ b/src/main/java/com/eactive/eai/common/session/SessionManagerForEhcache.java @@ -155,7 +155,7 @@ public class SessionManagerForEhcache extends SessionManager { } System.setProperty("net.sf.ehcache.skipUpdateCheck", "true"); - String bootstrapAsynchronously = "false"; + String bootstrapAsynchronously = "true"; Configuration cf = new Configuration(); FactoryConfiguration ppFactory = new FactoryConfiguration(); diff --git a/src/main/java/com/eactive/eai/inbound/processor/RequestProcessor.java b/src/main/java/com/eactive/eai/inbound/processor/RequestProcessor.java index 43d84fb..7175d74 100644 --- a/src/main/java/com/eactive/eai/inbound/processor/RequestProcessor.java +++ b/src/main/java/com/eactive/eai/inbound/processor/RequestProcessor.java @@ -1022,9 +1022,11 @@ public class RequestProcessor extends RequestProcessorSupport { } // 그룹 우선, 없으면 인터페이스 유량제어 체크 String groupId = bucket.getGroupIdByInterface(vo.getEaiSvcCd()); + String groupBlockedType = null; if (groupId != null) { // 그룹에 속한 인터페이스 → 그룹 유량제어 체크 - if (!bucket.isGroupPass(groupId)) { + groupBlockedType = bucket.isGroupPass(groupId); + if (groupBlockedType != null) { blockedType += "G"; } } else { @@ -1044,11 +1046,26 @@ public class RequestProcessor extends RequestProcessorSupport { } else { inflowTargetVO = bucket.getInterfaceInflowThreashold(vo.getEaiSvcCd()); } + String inflowErrorMsg; // 에러처리 vo.setRspErrorCode(EAIMessageKeys.EAI_INFLOW_BLOCKED_CODE); - String inflowInfo = (inflowGroupVO != null) ? inflowGroupVO.toString() : - (inflowTargetVO != null ? inflowTargetVO.toString() : "N/A"); - vo.setRspErrorMsg(ExceptionUtil.make(vo.getRspErrorCode(), vo.getEaiSvcCd() ) + ", " + inflowInfo); + if (inflowGroupVO != null) { + if ("PER_SECOND".equals(groupBlockedType)) { + inflowErrorMsg = String.format("API 호출 한도 초과 [%s: %dreq/sec]", + inflowGroupVO.getGroupName(), + inflowGroupVO.getThresholdPerSecond()); + } else { + inflowErrorMsg = String.format("API 호출 한도 초과 [%s: %dreq/%s]", + inflowGroupVO.getGroupName(), + inflowGroupVO.getThreshold(), + inflowGroupVO.getThresholdTimeUnit()); + } + } else if (inflowTargetVO != null) { + inflowErrorMsg = String.format("API 호출 한도 초과 [%s]", inflowTargetVO.getName()); + } else { + inflowErrorMsg = "API 호출 한도 초과"; + } + vo.setRspErrorMsg(inflowErrorMsg); // eaiMsg.setRspErrCd(vo.getRspErrorCode()); // eaiMsg.setRspErrMsg(vo.getRspErrorMsg()); @@ -1082,7 +1099,7 @@ public class RequestProcessor extends RequestProcessorSupport { sb.append("EAISevrInstncName [" + eaiServerManager.getLocalServerName() + "]\n"); sb.append("EAISvcName [" + eaiMsg.getEAISvcCd() + "]\n"); sb.append("ADPTRBZWKGROUPNAME[" + vo.getAdapterGroupName() + "]\n"); - sb.append("InflowInfo [" + inflowInfo + "]\n"); + sb.append("InflowInfo [" + inflowErrorMsg + "]\n"); if (groupId != null) { sb.append("InflowGroupId [" + groupId + "]\n"); } From efb829403fbb83725de3b9efa2ec6225b47ba351 Mon Sep 17 00:00:00 2001 From: "Yunsam.Eo" Date: Sun, 14 Dec 2025 16:36:18 +0900 Subject: [PATCH 039/159] =?UTF-8?q?scope=EC=B2=B4=ED=81=AC=EB=A1=9C?= =?UTF-8?q?=EC=A7=81=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../http/dynamic/filter/ApiAuthFilter.java | 55 +++++++++---------- 1 file changed, 27 insertions(+), 28 deletions(-) diff --git a/src/main/java/com/eactive/eai/adapter/http/dynamic/filter/ApiAuthFilter.java b/src/main/java/com/eactive/eai/adapter/http/dynamic/filter/ApiAuthFilter.java index 569b64b..2babcee 100644 --- a/src/main/java/com/eactive/eai/adapter/http/dynamic/filter/ApiAuthFilter.java +++ b/src/main/java/com/eactive/eai/adapter/http/dynamic/filter/ApiAuthFilter.java @@ -109,6 +109,7 @@ public class ApiAuthFilter implements HttpAdapterFilter { return message; } + boolean isPassScope = false; switch (eaiMessage.getAuthType()){ case "oauth": try { @@ -127,10 +128,25 @@ public class ApiAuthFilter implements HttpAdapterFilter { OAuth2Manager manager = OAuth2Manager.getInstance(); HashSet scopeSet = manager.getApiScopeMap().get(apiId); - if (!verifyScope(scopeSet, signedJWT)) { + + String[] scopeArr = signedJWT.getJWTClaimsSet().getStringArrayClaim(PAYLOAD_PARAM_NAME_SCOPE); + if (scopeArr == null || scopeArr.length == 0) { throw new JwtAuthException(ERROR_AUTHORIZATION_FAIL, String.format("Insufficient [Scope](Allowed Scope=%s)", scopeSet.toString())); } + + for (String scope : scopeArr) { + if (StringUtils.equals(scope, "oob") || StringUtils.equals(scope, "public")) { + isPassScope = true; + } + } + + if (!isPassScope) { + if (!verifyScope(scopeSet, signedJWT)) { + throw new JwtAuthException(ERROR_AUTHORIZATION_FAIL, + String.format("Insufficient [Scope](Allowed Scope=%s)", scopeSet.toString())); + } + } // header 값으로 전송된 clientId와 토큰 소유 clientId check if (!verifyClientId(prop, signedJWT)) { @@ -144,26 +160,6 @@ public class ApiAuthFilter implements HttpAdapterFilter { throw new JwtAuthException(ERROR_AUTHENTICATION_FAIL, "Token invalid"); } break; -// case "bearer": -// try { -// String token = ApiAuthFilter.extractJWTToken(request); -// BearerTokenInfo CATokenInfo = CATokenStore.get(token); -// -// if (CATokenInfo == null) { -// throw new JwtAuthException(ERROR_AUTHENTICATION_FAIL, "Token invalid"); -// } -// -// if (CATokenInfo.isExpired()) { -// throw new JwtAuthException(ERROR_TOKEN_EXPIRED, "Access token expired"); -// } -// } catch (JwtAuthException e) { -// logger.debug(e.getMessage()); -// throw e; -// } catch (Exception e) { -// logger.error(e.getMessage()); -// throw new JwtAuthException(ERROR_AUTHENTICATION_FAIL, "Token invalid"); -// } -// break; case "api_key": String apiKeyName = PropManager.getInstance().getProperty("ApiConfig", "api.key.name", "x-api-key"); String apiKey = request.getHeader(apiKeyName); @@ -171,19 +167,22 @@ public class ApiAuthFilter implements HttpAdapterFilter { throw new JwtAuthException(ERROR_AUTHENTICATION_FAIL, "Invalid or missing API key \""+apiKeyName+"\" in Http Header"); } prop.setProperty(HttpAdapterServiceSupport.PROPERTIES_NAME_CLIENT_ID, apiKey); + isPassScope = true; break; case "none": return message; } - String clientId = prop.getProperty(HttpAdapterServiceSupport.PROPERTIES_NAME_CLIENT_ID); - ClientVO clientVO = OAuth2Manager.getInstance().getClientVO(clientId); - if(clientVO == null){ - throw new JwtAuthException(ERROR_AUTHENTICATION_FAIL, "Unregistered APP"); - } + if (isPassScope) { + String clientId = prop.getProperty(HttpAdapterServiceSupport.PROPERTIES_NAME_CLIENT_ID); + ClientVO clientVO = OAuth2Manager.getInstance().getClientVO(clientId); + if(clientVO == null){ + throw new JwtAuthException(ERROR_AUTHENTICATION_FAIL, "Unregistered APP"); + } - if(clientVO.getApiMap().containsKey(eaiSvcCd) == false){ - throw new JwtAuthException(ERROR_AUTHENTICATION_FAIL, "Unregistered API ["+eaiSvcCd+"] in ["+clientVO.getClientName()+"] APP"); + if(clientVO.getApiMap().containsKey(eaiSvcCd) == false){ + throw new JwtAuthException(ERROR_AUTHENTICATION_FAIL, "Unregistered API ["+eaiSvcCd+"] in ["+clientVO.getClientName()+"] APP"); + } } return message; From c08024d9bb2dcc07208b307c43cf8cc4121b5993 Mon Sep 17 00:00:00 2001 From: "Yunsam.Eo" Date: Sun, 14 Dec 2025 16:38:08 +0900 Subject: [PATCH 040/159] =?UTF-8?q?KJB=EC=9A=A9=20HmacSHA256=ED=95=84?= =?UTF-8?q?=ED=84=B0=20=EC=B6=94=EA=B0=80,=20Custom=20Filter=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80=EA=B0=80=EB=8A=A5=ED=95=98=EB=8F=84=EB=A1=9D=20?= =?UTF-8?q?=EC=88=98=EC=A0=95.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../dynamic/HttpAdapterServiceSupport.java | 11 +- .../filter/HmacSha256VerifyFilterKjb.java | 149 ++++++++++++++++++ .../filter/HttpAdapterFilterFactoryKjb.java | 64 ++++++++ .../dynamic/filter/HttpAdapterFilterType.java | 1 + 4 files changed, 218 insertions(+), 7 deletions(-) create mode 100644 src/main/java/com/eactive/eai/adapter/http/dynamic/filter/HmacSha256VerifyFilterKjb.java create mode 100644 src/main/java/com/eactive/eai/adapter/http/dynamic/filter/HttpAdapterFilterFactoryKjb.java diff --git a/src/main/java/com/eactive/eai/adapter/http/dynamic/HttpAdapterServiceSupport.java b/src/main/java/com/eactive/eai/adapter/http/dynamic/HttpAdapterServiceSupport.java index 0077de4..8be66b3 100644 --- a/src/main/java/com/eactive/eai/adapter/http/dynamic/HttpAdapterServiceSupport.java +++ b/src/main/java/com/eactive/eai/adapter/http/dynamic/HttpAdapterServiceSupport.java @@ -9,14 +9,11 @@ import org.apache.commons.lang3.StringUtils; import com.eactive.eai.adapter.AdapterGroupVO; import com.eactive.eai.adapter.AdapterManager; -import com.eactive.eai.adapter.AdapterPropManager; -import com.eactive.eai.adapter.AdapterVO; import com.eactive.eai.adapter.RequestDispatcher; import com.eactive.eai.adapter.http.client.HttpClientAdapterServiceKey; import com.eactive.eai.adapter.http.dynamic.filter.HttpAdapterFilter; -import com.eactive.eai.adapter.http.dynamic.filter.HttpAdapterFilterFactory; +import com.eactive.eai.adapter.http.dynamic.filter.HttpAdapterFilterFactoryKjb; import com.eactive.eai.adapter.http.dynamic.filter.HttpAdapterFilterType; -import com.eactive.eai.data.entity.onl.adapter.AdapterProp; public abstract class HttpAdapterServiceSupport implements HttpAdapterService, HttpAdapterServiceKey { protected long slowTranTime = 2000L; @@ -65,7 +62,7 @@ public abstract class HttpAdapterServiceSupport implements HttpAdapterService, H if (!"HTC".equals(group.getType())) { String allowIp = prop.getProperty(ALLOW_IP,""); if (StringUtils.isNotBlank(allowIp)) { - HttpAdapterFilter adapterFilter = HttpAdapterFilterFactory.createFilter(HttpAdapterFilterType.ADAPTERALLOWIPLISTFILTER.toString()); + HttpAdapterFilter adapterFilter = HttpAdapterFilterFactoryKjb.createFilter(HttpAdapterFilterType.ADAPTERALLOWIPLISTFILTER.toString()); if (adapterFilter != null) { message = adapterFilter.doPreFilter(adptGrpName, adptName, message, prop, request, response); } @@ -83,7 +80,7 @@ public abstract class HttpAdapterServiceSupport implements HttpAdapterService, H continue; } - HttpAdapterFilter adapterFilter = HttpAdapterFilterFactory.createFilter(filterName.trim()); + HttpAdapterFilter adapterFilter = HttpAdapterFilterFactoryKjb.createFilter(filterName.trim()); if (adapterFilter != null) { message = adapterFilter.doPreFilter(adptGrpName, adptName, message, prop, request, response); } else { @@ -106,7 +103,7 @@ public abstract class HttpAdapterServiceSupport implements HttpAdapterService, H continue; } - HttpAdapterFilter adapterFilter = HttpAdapterFilterFactory.createFilter(filterName.trim()); + HttpAdapterFilter adapterFilter = HttpAdapterFilterFactoryKjb.createFilter(filterName.trim()); if (adapterFilter != null) { resultMessage = adapterFilter.doPostFilter(adptGrpName, adptName, resultMessage, prop, request, response); diff --git a/src/main/java/com/eactive/eai/adapter/http/dynamic/filter/HmacSha256VerifyFilterKjb.java b/src/main/java/com/eactive/eai/adapter/http/dynamic/filter/HmacSha256VerifyFilterKjb.java new file mode 100644 index 0000000..a908c2d --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/http/dynamic/filter/HmacSha256VerifyFilterKjb.java @@ -0,0 +1,149 @@ +package com.eactive.eai.adapter.http.dynamic.filter; + +import java.io.UnsupportedEncodingException; +import java.security.InvalidKeyException; +import java.security.NoSuchAlgorithmException; +import java.util.Base64; +import java.util.Properties; + +import javax.crypto.Mac; +import javax.crypto.spec.SecretKeySpec; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +//import org.apache.commons.net.util.Base64; +import org.springframework.http.HttpStatus; +import org.apache.commons.lang3.StringUtils; + +import com.eactive.eai.adapter.http.dynamic.HttpAdapterServiceKey; +import com.eactive.eai.adapter.http.dynamic.HttpAdapterServiceSupport; +import com.eactive.eai.authserver.service.OAuth2Manager; +import com.eactive.eai.authserver.vo.ClientVO; +import com.eactive.eai.common.util.Logger; + +public class HmacSha256VerifyFilterKjb implements HttpAdapterFilter { + + static Logger logger = Logger.getLogger(Logger.LOGGER_ADAPTER); + + public HmacSha256VerifyFilterKjb() { + super(); + } + + @Override + public Object doPreFilter(String adptGrpName, String adptName, Object message, Properties prop, + HttpServletRequest request, HttpServletResponse response) throws Exception { + + String inboundMethod = prop.getProperty(HttpAdapterServiceKey.INBOUND_METHOD); + String inboundUri = prop.getProperty(HttpAdapterServiceKey.INBOUND_URI); + String inboundBody = prop.getProperty(HttpAdapterServiceKey.INBOUND_REQUEST_MESSAGE); + + try { + String xObpPartnercode = request.getHeader("x-obp-partnercode"); + String xObpSignatureUrl = request.getHeader("x-obp-signature-url"); + String xObpSignatureBody = request.getHeader("x-obp-signature-body"); + if (StringUtils.isBlank(xObpPartnercode) + || StringUtils.isBlank(xObpSignatureUrl) + || StringUtils.isBlank(xObpSignatureBody)) { + throw new JwtAuthException( + String.valueOf(HttpStatus.UNAUTHORIZED.value()), + "Can not find mandatory Http Header"); + } + + if (StringUtils.isNotBlank(prop.getProperty(HttpAdapterServiceKey.INBOUND_QUERY_STRING))) { + inboundUri = inboundUri + "?" + prop.getProperty(HttpAdapterServiceKey.INBOUND_QUERY_STRING); + inboundBody = ""; + } + String chkUrl = inboundMethod + "&" + inboundUri; + String chkBody = inboundBody; + String clientSecret = assignClientSecret(prop, request); + + String macUrl = calculateHMAC(chkUrl, clientSecret); + String macBody = calculateHMAC(chkBody, clientSecret); + + if (!StringUtils.equals(xObpSignatureUrl, macUrl)) { + throw new JwtAuthException( + String.valueOf(HttpStatus.UNAUTHORIZED.value()), + "Signature verifying failed : x-obp-signature-url"); + } + + if (!StringUtils.equals(xObpSignatureBody, macBody)) { + throw new JwtAuthException( + String.valueOf(HttpStatus.UNAUTHORIZED.value()), + "Signature verifying failed : x-obp-signature-body"); + } + + } catch (JwtAuthException e) { + logger.debug(e.getMessage()); + throw e; + } catch (Exception e) { + logger.error(e.getMessage()); + throw new JwtAuthException( + String.valueOf(HttpStatus.UNAUTHORIZED.value()), + "Signature verifying failed(unkown)"); + } + + return message; + } + + public static String calculateHMAC(String data, String key) + throws NoSuchAlgorithmException, InvalidKeyException, UnsupportedEncodingException { + + Mac mac = Mac.getInstance("HmacSHA256"); + mac.init(new SecretKeySpec(key.getBytes(), "HmacSHA256")); + return Base64.getEncoder().encodeToString(mac.doFinal(data.getBytes("UTF-8"))); + } + + private String assignClientSecret(Properties prop, HttpServletRequest request) throws Exception { + String clientId = assignClientId(prop, request); + if (StringUtils.isBlank(clientId)) { + throw new JwtAuthException( + String.valueOf(HttpStatus.UNAUTHORIZED.value()), + "Can not find clientId info"); + } + + ClientVO client = (ClientVO) OAuth2Manager.getInstance().getClientDeatilsStore().get(clientId); + if (client == null) { + throw new JwtAuthException( + String.valueOf(HttpStatus.UNAUTHORIZED.value()), + "Can not find client info"); + } + + return client.getClientSecret(); + } + + private String assignClientId(Properties prop, HttpServletRequest request) { + String clientId = null; + try { + // 이전 filter에서 셋팅한 clientId 확보 + clientId = prop.getProperty(HttpAdapterServiceSupport.PROPERTIES_NAME_CLIENT_ID); + + // 이전 filter에서 셋팅한 값이 없다면 header 정보에서 확보 + if (StringUtils.isBlank(clientId)) { + clientId = request.getHeader(HttpAdapterServiceSupport.HEADER_NAME_CLIENT_ID); + } + } catch (Exception e) { + logger.error(e.getMessage()); + } + + return clientId; + } + + @Override + public Object doPostFilter(String adptGrpName, String adptName, Object resultMessage, Properties prop, + HttpServletRequest request, HttpServletResponse response) throws Exception { + + String outboundBody = (String) resultMessage; + + try { + String clientSecret = assignClientSecret(prop, request); + String macBody = calculateHMAC(outboundBody, clientSecret); + + response.addHeader("x-obp-signature-body", macBody); + } catch (Exception e) { + logger.error(e.getMessage()); + } + + return resultMessage; + } + +} diff --git a/src/main/java/com/eactive/eai/adapter/http/dynamic/filter/HttpAdapterFilterFactoryKjb.java b/src/main/java/com/eactive/eai/adapter/http/dynamic/filter/HttpAdapterFilterFactoryKjb.java new file mode 100644 index 0000000..977f92f --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/http/dynamic/filter/HttpAdapterFilterFactoryKjb.java @@ -0,0 +1,64 @@ +package com.eactive.eai.adapter.http.dynamic.filter; + +import java.util.concurrent.ConcurrentHashMap; + +import com.eactive.eai.common.util.Logger; + +public class HttpAdapterFilterFactoryKjb extends HttpAdapterFilterFactory { + static Logger logger = Logger.getLogger(Logger.LOGGER_ADAPTER); + static String basePackage = "com.eactive.eai.custom.adapter.http.dynamic.filter"; + static private ConcurrentHashMap h = new ConcurrentHashMap(); + + public HttpAdapterFilterFactoryKjb() { + super(); + } + + @SuppressWarnings("rawtypes") + public static HttpAdapterFilter createFilter(String type) { + if (h.containsKey(type)) { + return (HttpAdapterFilter) h.get(type); + } + + HttpAdapterFilter filter = null; + switch (HttpAdapterFilterType.getValue(type)) { + case APIAUTHFILTER: + filter = new ApiAuthFilter(); + break; + case JWTAUTHFILTER: + filter = new JwtAuthFilter(); + break; + case IPWHITELISTFILTER: + filter = new IpWhiteListFilter(); + break; + case ADAPTERALLOWIPLISTFILTER: + filter = new AdapterAllowIPListFilter(); + break; + case HMAC_SHA256: + filter = new HmacSha256VerifyFilterKjb(); + break; + default: + filter = classForName(type); + if (filter == null) { + filter = classForName(basePackage + "." + type); + } + break; + } + + if (filter != null) { + h.put(type, filter); + return filter; + } else { + return null; + } + } + + private static HttpAdapterFilter classForName(String type) { + try { + Class cl = Class.forName(type); + return (HttpAdapterFilter) cl.newInstance(); + } catch (ClassNotFoundException | IllegalAccessException | InstantiationException e) { + logger.error("Cannot create a HttpAdapterFilter. - {}", type); + return null; + } + } +} diff --git a/src/main/java/com/eactive/eai/adapter/http/dynamic/filter/HttpAdapterFilterType.java b/src/main/java/com/eactive/eai/adapter/http/dynamic/filter/HttpAdapterFilterType.java index 6231c74..c522614 100644 --- a/src/main/java/com/eactive/eai/adapter/http/dynamic/filter/HttpAdapterFilterType.java +++ b/src/main/java/com/eactive/eai/adapter/http/dynamic/filter/HttpAdapterFilterType.java @@ -5,6 +5,7 @@ public enum HttpAdapterFilterType { JWTAUTHFILTER, IPWHITELISTFILTER, ADAPTERALLOWIPLISTFILTER, + HMAC_SHA256, UNKNOWN; public static HttpAdapterFilterType getValue(String type) { From 73454018e2f2944ae2a4e531e3498e0f5dd51b9a Mon Sep 17 00:00:00 2001 From: "Yunsam.Eo" Date: Mon, 15 Dec 2025 18:06:41 +0900 Subject: [PATCH 041/159] =?UTF-8?q?ApiScopeMap=20Loading=20=EC=98=A4?= =?UTF-8?q?=EB=A5=98=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/eactive/eai/authserver/dao/ScopeDAO.java | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/src/main/java/com/eactive/eai/authserver/dao/ScopeDAO.java b/src/main/java/com/eactive/eai/authserver/dao/ScopeDAO.java index 83676f6..3cae28a 100644 --- a/src/main/java/com/eactive/eai/authserver/dao/ScopeDAO.java +++ b/src/main/java/com/eactive/eai/authserver/dao/ScopeDAO.java @@ -31,9 +31,15 @@ public class ScopeDAO extends BaseDAO { Map> clientEntitymap = new HashMap<>(); scopeEntities.forEach(scopeEntity -> { - HashSet set = new HashSet<>(); - String scopeId = scopeEntity.getId().getBzwksvckeyname() + scopeEntity.getId().getScopeid(); - clientEntitymap.put(scopeId, set); + String apiId = scopeEntity.getId().getBzwksvckeyname(); + HashSet scopeSet = clientEntitymap.get(apiId); + if (scopeSet == null) { + scopeSet = new HashSet(); + clientEntitymap.put(apiId, scopeSet); + } + String scopeId = scopeEntity.getId().getScopeid(); + clientEntitymap.get(apiId).add(scopeId); +// clientEntitymap.put(scopeId, set); }); return clientEntitymap; From 7dd17f0db9a23118ac2ac4b06998f3c6a442e4f1 Mon Sep 17 00:00:00 2001 From: jaewohong Date: Tue, 16 Dec 2025 11:07:05 +0900 Subject: [PATCH 042/159] =?UTF-8?q?Async-Sync=20=EC=8B=9C=20400=EC=97=90?= =?UTF-8?q?=20=EB=8C=80=ED=95=9C=20=EC=9D=91=EB=8B=B5=20500=20=EB=A1=9C?= =?UTF-8?q?=EA=B7=B8=20=EC=B6=9C=EB=A0=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../eactive/eai/outbound/DefaultProcess.java | 20 +++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/src/main/java/com/eactive/eai/outbound/DefaultProcess.java b/src/main/java/com/eactive/eai/outbound/DefaultProcess.java index 691e07a..65e10d7 100644 --- a/src/main/java/com/eactive/eai/outbound/DefaultProcess.java +++ b/src/main/java/com/eactive/eai/outbound/DefaultProcess.java @@ -37,6 +37,7 @@ import com.eactive.eai.message.manager.StandardMessageManager; import com.eactive.eai.message.mapper.MessageMapper; import com.eactive.eai.message.service.InterfaceMapper; import com.ext.eai.common.stdmessage.STDMessageKeys; +import com.eactive.eai.common.message.ServiceMessage; // jwhong public abstract class DefaultProcess extends Process { protected static Logger logger = Logger.getLogger(Logger.LOGGER_DEFAULT); @@ -252,6 +253,13 @@ public abstract class DefaultProcess extends Process { } // 송신결과확인 checkSendResult(); + // 400 Async 에 대한 ack 오는것 500 으로 log에 저장, jwhong for kjbank + if(isAsyncSyncPattern()){ + StandardMessage standardMessage = this.resEaiMsg.getStandardMessage(); + standardMessage.setBizData(this.resObject, this.outboundCharset); + this.logPssSno = 500; + logSenderCtrlSendRes(); + } // SA if (isSyncAsyncPattern()) { try { @@ -474,6 +482,18 @@ public abstract class DefaultProcess extends Process { return false; } } + + // jwhong + public boolean isAsyncSyncPattern() { + ServiceMessage firstService = this.reqEaiMsg.getSvcMsg(0); + ServiceMessage secondService = this.reqEaiMsg.getSvcMsg(1); + if (EAIMessageKeys.ASYNC_SVC.equals(this.reqEaiMsg.getSvcTsmtUsgTp()) + && EAIMessageKeys.SYNC_SVC.equals(firstService.getPsvItfTp()) + && EAIMessageKeys.ASYNC_SVC.equals(secondService.getPsvItfTp())){ + return true; + } + return false; + } public boolean isSyncAsyncPattern() { if (!MessageUtil.checkRspErrCd(this.resEaiMsg.getRspErrCd())) { From 5357eb8f635bcaccf6a76453664a825a73ff0d02 Mon Sep 17 00:00:00 2001 From: jaewohong Date: Tue, 16 Dec 2025 11:08:36 +0900 Subject: [PATCH 043/159] =?UTF-8?q?Niceon=20token=EB=B0=9C=EC=83=9D=20?= =?UTF-8?q?=EA=B4=80=EB=A0=A8=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../impl/HttpClient5AdapterServiceRest.java | 87 ++++++++++++------- ...entAccessTokenServiceWithBase64Header.java | 14 +-- 2 files changed, 65 insertions(+), 36 deletions(-) diff --git a/src/main/java/com/eactive/eai/adapter/http/client/impl/HttpClient5AdapterServiceRest.java b/src/main/java/com/eactive/eai/adapter/http/client/impl/HttpClient5AdapterServiceRest.java index 86a47aa..fe84003 100644 --- a/src/main/java/com/eactive/eai/adapter/http/client/impl/HttpClient5AdapterServiceRest.java +++ b/src/main/java/com/eactive/eai/adapter/http/client/impl/HttpClient5AdapterServiceRest.java @@ -306,7 +306,8 @@ public class HttpClient5AdapterServiceRest extends HttpClient5AdapterServiceSupp accessToken = (OAuth2AccessTokenVO) tokenManager.getAccessTokenVO(vo.getAdapterGroupName()); // 토큰이 없거나 만료 됐으면 재발급 - if (accessToken == null || accessToken.isExpired()) { + //if (accessToken == null || accessToken.isExpired()) { + if (accessToken == null || accessToken.isExpired() || accessToken.getAccessToken() == null ) { // jwhong String oldToken = accessToken == null ? null : accessToken.getAccessToken(); accessToken = (OAuth2AccessTokenVO) tokenManager.retryAccessTokenVO(vo.getAdapterGroupName(), prop, oldToken); @@ -321,6 +322,9 @@ public class HttpClient5AdapterServiceRest extends HttpClient5AdapterServiceSupp String encryptAlgorithm = properties.getProperty("ENCRYPT_ALGORITHM"); // jwhong if (useAdapterToken && "AES256-NICEON".equals(encryptAlgorithm)) { String niceToken = accessToken.getAccessToken(); + if ( niceToken == null || niceToken == "") { + throw new Exception("NiceOn Token is empty, toke failed to be issued, TOKEN = [" + niceToken + "]"); + } String clientId = JwtClientIdExtractor(niceToken); long currentTime = System.currentTimeMillis(); auth = niceToken + ":" + currentTime + ":" + clientId ; @@ -827,46 +831,67 @@ public class HttpClient5AdapterServiceRest extends HttpClient5AdapterServiceSupp // map에 담기 Map map = new HashMap<>(); for (String entry : entries) { - String[] kv = entry.split("=", 2); - if (kv.length == 2) { - map.put(kv[0].trim(), kv[1].trim()); - } + String[] kv = entry.split("=", 2); + if (kv.length == 2) { + map.put(kv[0].trim(), kv[1].trim()); + } } for (String k : map.keySet()) { - if (k.equalsIgnoreCase("authorization")) { - authorization = map.get(k); - break; - } + if (k.equalsIgnoreCase("authorization")) { + authorization = map.get(k); + break; + } } - } + } } catch (Exception e) { - e.printStackTrace(); + e.printStackTrace(); } - + String jwtToken = ""; - + if (authorization != null && authorization.startsWith("Bearer ")) { - jwtToken = authorization.substring(7); // "Bearer " 이후의 JWT만 추출 + jwtToken = authorization.substring(7); // "Bearer " 이후의 JWT만 추출 } - + /* 업체정보 */ - String clientId = JwtClientIdExtractor(jwtToken); - method.setHeader("clientId", clientId); - - /* APIM 거래추적자 */ - String uuid = tempProp.getProperty(TransactionContextKeys.TRANSACTION_UUID, ""); - method.setHeader("traceId", uuid); - - /* GUID */ - String guid = tempProp.getProperty(TransactionContextKeys.GUID, ""); - method.setHeader("guid", guid); - - /* 최초요청시간 */ - String receivedTimestamp = tempProp.getProperty(HttpAdapterServiceKey.INBOUND_REQUESTED_TIME, ""); - method.setHeader("receivedTimestamp", receivedTimestamp); - - return jwtToken; + String clientId = JwtClientIdExtractor(jwtToken); + method.setHeader("clientId", clientId); + + /* APIM 거래추적자 */ + String uuid = tempProp.getProperty(TransactionContextKeys.TRANSACTION_UUID, ""); + method.setHeader("traceId", uuid); + + /* GUID */ + String guid = tempProp.getProperty(TransactionContextKeys.GUID, ""); + method.setHeader("guid", guid); + + /* 최초요청시간 */ + String receivedTimestamp = tempProp.getProperty(HttpAdapterServiceKey.INBOUND_REQUESTED_TIME, ""); + method.setHeader("receivedTimestamp", receivedTimestamp); + + return jwtToken; } + + private static Map parseInboundHeader(String str) { + java.util.HashMap map = new java.util.HashMap<>(); + if (str == null || str.isEmpty()) return map; + + // 중괄호 제거 + str = str.trim(); + if (str.startsWith("{") && str.endsWith("}")) { + str = str.substring(1, str.length() - 1); + } + + // key=value 쌍 분리 + String[] pairs = str.split(","); + for (String pair : pairs) { + String[] kv = pair.split("=", 2); + if (kv.length == 2) { + map.put(kv[0].trim(), kv[1].trim()); + } + } + return map; + } @SuppressWarnings("deprecation") private void assignPostBody(Object eaiBody, String contentType, String charset, HttpUriRequestBase method, String adapterName, String niceAuth, String inboundToken) { diff --git a/src/main/java/com/eactive/eai/authoutbound/client/impl/HttpClientAccessTokenServiceWithBase64Header.java b/src/main/java/com/eactive/eai/authoutbound/client/impl/HttpClientAccessTokenServiceWithBase64Header.java index 295c2f3..07f7864 100644 --- a/src/main/java/com/eactive/eai/authoutbound/client/impl/HttpClientAccessTokenServiceWithBase64Header.java +++ b/src/main/java/com/eactive/eai/authoutbound/client/impl/HttpClientAccessTokenServiceWithBase64Header.java @@ -114,9 +114,7 @@ public class HttpClientAccessTokenServiceWithBase64Header implements HttpClientA "uri:{}, charset:{}, transactionTimeout:{}, connectionTimeout:{}, useForwardProxy:{}, forwardProxyUrl:{}", uri, encode, timeout, connectionTimeout, useForwardProxy, forwardProxyUrl); - - - + // mTLS config with default connection parameters boolean useMtls = StringUtils.equalsIgnoreCase(adapterProp.getProperty(HttpClientAdapterServiceKey.USE_MTLS), "Y"); @@ -237,17 +235,19 @@ public class HttpClientAccessTokenServiceWithBase64Header implements HttpClientA logger.debug("contentType = [" + contentType + "]"); logger.debug("encode = [" + encode + "]"); + OAuth2AccessTokenVO accessToken = new OAuth2AccessTokenVO(); try (CloseableHttpResponse response = httpClient.execute(httpPost)) { if (response.getCode() != 200) { throw new Exception("OAuth token receive status fail value= " + response.getCode()); } + + logger.info("HttpClientAccessTokenServiceWithBase64Header==>" + response.getCode()); HttpEntity entity = response.getEntity(); String responseString = EntityUtils.toString(entity, encode); - logger.debug("oauthToken RECV = [" + responseString + "]"); + logger.debug("Base64Header oauthToken RECV = [" + responseString + "]"); if (StringUtils.isNotBlank(responseString)) { - OAuth2AccessTokenVO accessToken = new OAuth2AccessTokenVO(); ObjectMapper objectMapper = new ObjectMapper(); JsonNode responseJSON = objectMapper.readTree(responseString); @@ -272,6 +272,10 @@ public class HttpClientAccessTokenServiceWithBase64Header implements HttpClientA } else { throw new Exception("oauth token return null"); } + } catch (Exception e) { + e.printStackTrace(); + logger.error("[HttpClientAccessTokenServiceWithBase64Header] retrieve accessToken exception :" + e.getMessage()); + return accessToken; } } } From 037f857a5f79fa7ad7f63d14979fb744cfc59708 Mon Sep 17 00:00:00 2001 From: jaewohong Date: Tue, 16 Dec 2025 11:08:54 +0900 Subject: [PATCH 044/159] =?UTF-8?q?bucket=20=EC=9C=A0=EB=9F=89=EC=A0=9C?= =?UTF-8?q?=EC=96=B4=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/com/eactive/eai/common/inflow/InflowControlDAO.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/main/java/com/eactive/eai/common/inflow/InflowControlDAO.java b/src/main/java/com/eactive/eai/common/inflow/InflowControlDAO.java index 8ff7b3a..9cbd12e 100644 --- a/src/main/java/com/eactive/eai/common/inflow/InflowControlDAO.java +++ b/src/main/java/com/eactive/eai/common/inflow/InflowControlDAO.java @@ -26,6 +26,7 @@ import com.eactive.eai.data.entity.onl.inflow.InflowControlLogId; @Service @Transactional public class InflowControlDAO extends BaseDAO { + private static Logger logger = Logger.getLogger(Logger.LOGGER_DEFAULT); @Autowired @@ -227,4 +228,5 @@ public class InflowControlDAO extends BaseDAO { vo.setActivate(!"0".equals(group.getUseYn())); return vo; } + } \ No newline at end of file From 9890f889a41f7a967bad67efb4091b4393141aed Mon Sep 17 00:00:00 2001 From: jaewohong Date: Tue, 16 Dec 2025 17:55:42 +0900 Subject: [PATCH 045/159] =?UTF-8?q?NiceOn=20token=20=EA=B4=80=EB=A0=A8?= =?UTF-8?q?=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../impl/HttpClient5AdapterServiceRest.java | 2 +- ...entAccessTokenServiceWithBase64Header.java | 3 +- ...entAccessTokenServiceWithBase64NiceOn.java | 298 ++++++++++++++++++ 3 files changed, 300 insertions(+), 3 deletions(-) create mode 100644 src/main/java/com/eactive/eai/authoutbound/client/impl/HttpClientAccessTokenServiceWithBase64NiceOn.java diff --git a/src/main/java/com/eactive/eai/adapter/http/client/impl/HttpClient5AdapterServiceRest.java b/src/main/java/com/eactive/eai/adapter/http/client/impl/HttpClient5AdapterServiceRest.java index fe84003..2491d51 100644 --- a/src/main/java/com/eactive/eai/adapter/http/client/impl/HttpClient5AdapterServiceRest.java +++ b/src/main/java/com/eactive/eai/adapter/http/client/impl/HttpClient5AdapterServiceRest.java @@ -323,7 +323,7 @@ public class HttpClient5AdapterServiceRest extends HttpClient5AdapterServiceSupp if (useAdapterToken && "AES256-NICEON".equals(encryptAlgorithm)) { String niceToken = accessToken.getAccessToken(); if ( niceToken == null || niceToken == "") { - throw new Exception("NiceOn Token is empty, toke failed to be issued, TOKEN = [" + niceToken + "]"); + throw new Exception("NiceOn Token is empty, TOKEN failed to be issued, TOKEN = [" + niceToken + "]"); } String clientId = JwtClientIdExtractor(niceToken); long currentTime = System.currentTimeMillis(); diff --git a/src/main/java/com/eactive/eai/authoutbound/client/impl/HttpClientAccessTokenServiceWithBase64Header.java b/src/main/java/com/eactive/eai/authoutbound/client/impl/HttpClientAccessTokenServiceWithBase64Header.java index 07f7864..30ef683 100644 --- a/src/main/java/com/eactive/eai/authoutbound/client/impl/HttpClientAccessTokenServiceWithBase64Header.java +++ b/src/main/java/com/eactive/eai/authoutbound/client/impl/HttpClientAccessTokenServiceWithBase64Header.java @@ -96,8 +96,7 @@ public class HttpClientAccessTokenServiceWithBase64Header implements HttpClientA if (!UrlUtils.isAbsoluteUrl(uri)) { uri = appendPath(adapterUrl, uri); } - //String contentType = "application/json;"; // comment by jwhong - String contentType = "application/x-www-form-urlencoded"; // 광주은행 나이스지키미 + String contentType = "application/json;"; Charset charset; if (StringUtils.isNotBlank(encode)) { diff --git a/src/main/java/com/eactive/eai/authoutbound/client/impl/HttpClientAccessTokenServiceWithBase64NiceOn.java b/src/main/java/com/eactive/eai/authoutbound/client/impl/HttpClientAccessTokenServiceWithBase64NiceOn.java new file mode 100644 index 0000000..51d0382 --- /dev/null +++ b/src/main/java/com/eactive/eai/authoutbound/client/impl/HttpClientAccessTokenServiceWithBase64NiceOn.java @@ -0,0 +1,298 @@ + +package com.eactive.eai.authoutbound.client.impl; + +import com.eactive.eai.adapter.AdapterGroupVO; +import com.eactive.eai.adapter.AdapterManager; +import com.eactive.eai.adapter.http.client.HttpClientAdapterServiceKey; +import com.eactive.eai.adapter.http.secure.HttpClient5SSLContextFactory; +import com.eactive.eai.authoutbound.OutboundOAuthCredentialVo; +import com.eactive.eai.authoutbound.client.HttpClientAccessTokenServiceByDB; +import com.eactive.eai.common.util.Logger; +import com.eactive.eai.httpouttlsinfo.HttpOutTlsInfoManager; +import com.eactive.eai.httpouttlsinfo.HttpOutTlsInfoVO; +import com.eactive.eai.util.TestModeChecker; +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.openbanking.eai.common.token.AccessTokenVO; +import com.openbanking.eai.common.token.OAuth2AccessTokenVO; +import org.apache.commons.lang3.StringUtils; +import org.apache.hc.client5.http.classic.methods.HttpPost; +import org.apache.hc.client5.http.config.RequestConfig; +import org.apache.hc.client5.http.impl.classic.CloseableHttpClient; +import org.apache.hc.client5.http.impl.classic.CloseableHttpResponse; +import org.apache.hc.client5.http.impl.classic.HttpClients; +import org.apache.hc.client5.http.impl.io.PoolingHttpClientConnectionManager; +import org.apache.hc.client5.http.impl.io.PoolingHttpClientConnectionManagerBuilder; +import org.apache.hc.client5.http.ssl.NoopHostnameVerifier; +import org.apache.hc.client5.http.ssl.SSLConnectionSocketFactory; +import org.apache.hc.client5.http.ssl.TrustAllStrategy; +import org.apache.hc.core5.http.ContentType; +import org.apache.hc.core5.http.HttpEntity; +import org.apache.hc.core5.http.HttpHost; +import org.apache.hc.core5.http.NameValuePair; +import org.apache.hc.core5.http.io.entity.EntityUtils; +import org.apache.hc.core5.http.io.entity.StringEntity; +import org.apache.hc.core5.http.message.BasicNameValuePair; +import org.apache.hc.core5.ssl.SSLContextBuilder; +import org.apache.hc.core5.util.Timeout; +import org.springframework.security.web.util.UrlUtils; +import tcseed.base64; + +import javax.net.ssl.SSLContext; +import java.io.IOException; +import java.nio.charset.Charset; +import java.nio.charset.StandardCharsets; +import java.security.KeyManagementException; +import java.security.KeyStoreException; +import java.security.NoSuchAlgorithmException; +import java.security.UnrecoverableKeyException; +import java.security.cert.CertificateException; +import java.util.*; +import org.apache.hc.client5.http.entity.UrlEncodedFormEntity; + +/** + * 1. 기능 : HTTP 웹 컴포넌트를 POST 방식으로 호출할 수 있는 기능을 제공한다. 2. 처리 개요 : * - 2009.11.24 + * retry 로직 제거 : 요청 3. 주의사항 + * + * @author : + * @version : v 1.0.0 + * @see : WLIAdapterFactory.java, WLIAdapter.java, WLIDefaultAdapter.java + * @since : + * + */ +public class HttpClientAccessTokenServiceWithBase64NiceOn implements HttpClientAccessTokenServiceByDB { + + public static Logger logger = Logger.getLogger(Logger.LOGGER_DEFAULT); + + private static boolean testMode = TestModeChecker.isTestMode(); + + /** + * 1. 기능 : 법인검증 토큰 발급에 사용 2. 처리 개요 : - 속성 정보를 설정 하고 토큰 발급 URL 호출 한다. 3. 주의사항 + * - JSON 방식 + * - ( Header Authorization Basic ) 으로 구성 + * @param adapterProp Http Adapter 속성 정보 + * @return 반환 된 AccessTokenVO + * @exception Exception 수동 시스템 간 통신 중 발생 + **/ + public AccessTokenVO execute(String name, Properties adapterProp, OutboundOAuthCredentialVo oAuthCredentialVo) + throws Exception { + AdapterGroupVO gvo = AdapterManager.getInstance().getAdapterGroupVO(name); + String adapterUrl = adapterProp.getProperty("URL"); + String encode = gvo.getMessageEncode(); + String timeoutTemp = adapterProp.getProperty("HTTP_TIME_OUT"); + if (StringUtils.isBlank(timeoutTemp)) { + timeoutTemp = "30000"; + } + String connectionTimeoutTemp = adapterProp.getProperty("CONNECTION_TIMEOUT"); + if (StringUtils.isBlank(connectionTimeoutTemp)) { + connectionTimeoutTemp = "30000"; + } + + int timeout = Integer.parseInt(timeoutTemp); + int connectionTimeout = Integer.parseInt(connectionTimeoutTemp); + long currentTime = System.currentTimeMillis(); + + String uri = oAuthCredentialVo.getUrl(); + + if (!UrlUtils.isAbsoluteUrl(uri)) { + uri = appendPath(adapterUrl, uri); + } + String contentType = "application/x-www-form-urlencoded"; // 광주은행 나이스지키미 + + Charset charset; + if (StringUtils.isNotBlank(encode)) { + charset = Charset.forName(encode); + } else { + charset = Charset.defaultCharset(); + encode = charset.toString(); + } + + boolean useForwardProxy = StringUtils.equalsIgnoreCase(adapterProp.getProperty("FORWARD_PROXY_USE_YN"), "Y"); + String forwardProxyUrl = adapterProp.getProperty("FORWARD_PROXY_URL"); + + logger.debug( + "uri:{}, charset:{}, transactionTimeout:{}, connectionTimeout:{}, useForwardProxy:{}, forwardProxyUrl:{}", + uri, encode, timeout, connectionTimeout, useForwardProxy, forwardProxyUrl); + + List formParams = new ArrayList<>(); + formParams.add(new BasicNameValuePair("client_id", oAuthCredentialVo.getClientId())); + formParams.add(new BasicNameValuePair("client_secret", oAuthCredentialVo.getClientSecret())); + formParams.add(new BasicNameValuePair("scope", oAuthCredentialVo.getScope())); + formParams.add(new BasicNameValuePair("grant_type", oAuthCredentialVo.getGrantType())); + + // mTLS config with default connection parameters + boolean useMtls = StringUtils.equalsIgnoreCase(adapterProp.getProperty(HttpClientAdapterServiceKey.USE_MTLS), + "Y"); + AdapterGroupVO adapterGroup = AdapterManager.getInstance().getAdapterGroup(name); + String clientId = adapterGroup.getClientId(); + + if (logger.isInfo()) { + logger.info("MTLS adapterGroupName. : {}, useMtls. : {}, clientId : {}", name, useMtls, clientId); + } + + int maxTotalConnections = HttpClientAdapterServiceKey.DEFAULT_MAX_TOTAL_CONNECTIONS; + int maxHostConnections = HttpClientAdapterServiceKey.DEFAULT_MAX_CONNECTION_PER_HOST; + + HttpOutTlsInfoVO mtlsInfo = null; + SSLContext sslContext = null; + PoolingHttpClientConnectionManagerBuilder cmBuilder = PoolingHttpClientConnectionManagerBuilder.create(); + PoolingHttpClientConnectionManager connectionManager = null; + + try { + if (useMtls) { + HttpOutTlsInfoManager tlsManager = HttpOutTlsInfoManager.getInstance(); + if (StringUtils.isNotEmpty(clientId)) { + mtlsInfo = tlsManager.getHttpOutTlsInfo(clientId); + } + } + + if (useMtls && mtlsInfo != null) { + String storeType = mtlsInfo.getStoreType(); + String keyStoreInfo = mtlsInfo.getKeystoreInfo(); + String keyStorePassword = mtlsInfo.getKeystorePassword(); + String trustStoreInfo = mtlsInfo.getTruststoreInfo(); + String trustStorePassword = mtlsInfo.getTruststorePassword(); + + String[] tlsVersions = null; + String[] cipherSuites = null; + + if (StringUtils.isAnyEmpty(keyStoreInfo, keyStorePassword)) { + throw new Exception("mTLS keyStore config error"); + } + + boolean skipTrust = false; + if (StringUtils.isAnyEmpty(trustStoreInfo, trustStorePassword)) { + if (logger.isWarn()) + logger.warn("Skip trustStore validation adapterGroupName : " + name); + skipTrust = true; + } + + sslContext = HttpClient5SSLContextFactory.createMTLSContextFromContent(storeType, keyStoreInfo, + keyStorePassword, trustStoreInfo, trustStorePassword, skipTrust, tlsVersions, cipherSuites); + + SSLConnectionSocketFactory sslSocketFactory = null; + if (testMode) { + sslSocketFactory = new SSLConnectionSocketFactory(sslContext, NoopHostnameVerifier.INSTANCE); + } else { + sslSocketFactory = new SSLConnectionSocketFactory(sslContext); + } + cmBuilder.setSSLSocketFactory(sslSocketFactory); + } else { + sslContext = SSLContextBuilder.create().loadTrustMaterial(new TrustAllStrategy()).build(); + SSLConnectionSocketFactory csf = new SSLConnectionSocketFactory(sslContext); + cmBuilder.setSSLSocketFactory(csf); + } + } catch (KeyManagementException | NoSuchAlgorithmException | KeyStoreException | CertificateException + | IOException | UnrecoverableKeyException e) { + throw new RuntimeException(e); + } catch (Exception e) { + throw new RuntimeException(e); + } + + connectionManager = cmBuilder.build(); + connectionManager.setMaxTotal(maxTotalConnections); + connectionManager.setDefaultMaxPerRoute(maxHostConnections); + + try (CloseableHttpClient httpClient = HttpClients.custom().setConnectionManager(connectionManager).build();) { + HttpPost httpPost = new HttpPost(uri); + httpPost.setEntity(new UrlEncodedFormEntity(formParams, charset)); + httpPost.setHeader("Content-Type", contentType+" charset=" + encode); + + //HTTP HEADER에 client id, client secret를 base64Encode 한 후 추가 + String cId = oAuthCredentialVo.getClientId(); + String cSecret = oAuthCredentialVo.getClientSecret(); + String authValue = cId + ":" + cSecret; + String encodedAuth = Base64.getEncoder().encodeToString(authValue.getBytes(StandardCharsets.UTF_8)); + httpPost.setHeader("Authorization","Basic "+ encodedAuth); + + + RequestConfig.Builder requestConfigBuilder = RequestConfig.custom(); + + if (useForwardProxy) { + java.net.URL url = new java.net.URL(forwardProxyUrl); + + // 프로토콜, 호스트, 포트 추출 + String protocol = url.getProtocol(); + String host = url.getHost(); + int port = url.getPort(); + HttpHost proxy = new HttpHost(protocol, host, port); + requestConfigBuilder.setProxy(proxy); + } + + RequestConfig requestConfig = requestConfigBuilder + .setConnectTimeout(Timeout.ofMilliseconds(connectionTimeout)) + .setResponseTimeout(Timeout.ofMilliseconds(timeout)).build(); + httpPost.setConfig(requestConfig); + + logger.debug("uri = [" + uri + "]"); + logger.debug("oauthClientId = [" + oAuthCredentialVo.getClientId() + "]"); + logger.debug("oauthClientSecret = [" + oAuthCredentialVo.getClientSecret() + "]"); + logger.debug("oauthScope = [" + oAuthCredentialVo.getScope() + "]"); + logger.debug("oauthGrantType = [" + oAuthCredentialVo.getGrantType() + "]"); + logger.debug("oauthauthValue = [" + authValue + "]"); + logger.debug("oauthauthEncodedAuth = [" + encodedAuth + "]"); + logger.debug("contentType = [" + contentType + "]"); + logger.debug("encode = [" + encode + "]"); + + OAuth2AccessTokenVO accessToken = new OAuth2AccessTokenVO(); + try (CloseableHttpResponse response = httpClient.execute(httpPost)) { + if (response.getCode() != 200) { + throw new Exception("NiceOn token receive status fail value= " + response.getCode()); + } + + logger.info("HttpClientAccessTokenServiceWithBase64NiceOn==>" + response.getCode()); + + HttpEntity entity = response.getEntity(); + String responseString = EntityUtils.toString(entity, encode); + logger.debug("Base64NiceOn oauthToken RECV = [" + responseString + "]"); + + if (StringUtils.isNotBlank(responseString)) { + + ObjectMapper objectMapper = new ObjectMapper(); + JsonNode responseJSON = objectMapper.readTree(responseString); + + if (responseJSON.has("access_token") && responseJSON.has("token_type") + && responseJSON.has("expires_in") && responseJSON.has("scope")) { + accessToken.setAccessToken(responseJSON.get("access_token").asText()); + accessToken.setTokenType(responseJSON.get("token_type").asText()); + + long expiresIn = responseJSON.get("expires_in").asLong(); + accessToken.setExpiration(new Date(currentTime + expiresIn * 1000L)); + accessToken.setScope(responseJSON.get("scope").asText()); + } + + if (responseJSON.has("client_use_code")) { + accessToken.setClientUseCode(responseJSON.get("client_use_code").asText()); + } + + logger.debug("oauthToken =" + accessToken.toString()); + + return accessToken; + } else { + throw new Exception("oauth token return null"); + } + } catch (Exception e) { + e.printStackTrace(); + logger.error("[HttpClientAccessTokenServiceWithBase64NiceOn] retrieve accessToken exception :" + e.getMessage()); + return accessToken; + } + } + } + + /** + * URL에 경로를 추가합니다. 중복되는 슬래시를 방지합니다. + * + * @param baseUrl 기본 URL + * @param pathToAdd 추가할 경로 + * @return 완성된 URL 문자열 + */ + public static String appendPath(String baseUrl, String pathToAdd) { + if (!baseUrl.endsWith("/") && !pathToAdd.startsWith("/")) { + return baseUrl + "/" + pathToAdd; + } else if (baseUrl.endsWith("/") && pathToAdd.startsWith("/")) { + return baseUrl + pathToAdd.substring(1); + } else { + return baseUrl + pathToAdd; + } + } +} From 02b9717890b47c2eb8a43d5d02ce5a154ea23af3 Mon Sep 17 00:00:00 2001 From: jaewohong Date: Wed, 17 Dec 2025 10:20:38 +0900 Subject: [PATCH 046/159] =?UTF-8?q?NICEON=20Token=20=ED=9A=8D=EB=93=9D=20?= =?UTF-8?q?=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../impl/HttpClientAccessTokenServiceWithBase64NiceOn.java | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/main/java/com/eactive/eai/authoutbound/client/impl/HttpClientAccessTokenServiceWithBase64NiceOn.java b/src/main/java/com/eactive/eai/authoutbound/client/impl/HttpClientAccessTokenServiceWithBase64NiceOn.java index 51d0382..d960c82 100644 --- a/src/main/java/com/eactive/eai/authoutbound/client/impl/HttpClientAccessTokenServiceWithBase64NiceOn.java +++ b/src/main/java/com/eactive/eai/authoutbound/client/impl/HttpClientAccessTokenServiceWithBase64NiceOn.java @@ -120,6 +120,9 @@ public class HttpClientAccessTokenServiceWithBase64NiceOn implements HttpClientA formParams.add(new BasicNameValuePair("scope", oAuthCredentialVo.getScope())); formParams.add(new BasicNameValuePair("grant_type", oAuthCredentialVo.getGrantType())); + String postParameters = "client_id=" + oAuthCredentialVo.getClientId() + "&client_secret=" + oAuthCredentialVo.getClientSecret() + "&scope=" + oAuthCredentialVo.getScope() + "&grant_type=" + oAuthCredentialVo.getGrantType(); + + // mTLS config with default connection parameters boolean useMtls = StringUtils.equalsIgnoreCase(adapterProp.getProperty(HttpClientAdapterServiceKey.USE_MTLS), "Y"); @@ -195,7 +198,8 @@ public class HttpClientAccessTokenServiceWithBase64NiceOn implements HttpClientA try (CloseableHttpClient httpClient = HttpClients.custom().setConnectionManager(connectionManager).build();) { HttpPost httpPost = new HttpPost(uri); - httpPost.setEntity(new UrlEncodedFormEntity(formParams, charset)); + //httpPost.setEntity(new UrlEncodedFormEntity(formParams, charset)); + httpPost.setEntity(new StringEntity(postParameters, StandardCharsets.UTF_8)); httpPost.setHeader("Content-Type", contentType+" charset=" + encode); //HTTP HEADER에 client id, client secret를 base64Encode 한 후 추가 From 2bef37c86aff8ef25256dc4f1a2488cba327de43 Mon Sep 17 00:00:00 2001 From: 25W0075 <25W0075@P9801Z.kjbank.dom> Date: Wed, 17 Dec 2025 11:13:56 +0900 Subject: [PATCH 047/159] =?UTF-8?q?=EC=88=98=EC=A0=95=20FOR=20TEST?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../impl/HttpClientAccessTokenServiceWithBase64NiceOn.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/com/eactive/eai/authoutbound/client/impl/HttpClientAccessTokenServiceWithBase64NiceOn.java b/src/main/java/com/eactive/eai/authoutbound/client/impl/HttpClientAccessTokenServiceWithBase64NiceOn.java index d960c82..6890c9c 100644 --- a/src/main/java/com/eactive/eai/authoutbound/client/impl/HttpClientAccessTokenServiceWithBase64NiceOn.java +++ b/src/main/java/com/eactive/eai/authoutbound/client/impl/HttpClientAccessTokenServiceWithBase64NiceOn.java @@ -241,7 +241,7 @@ public class HttpClientAccessTokenServiceWithBase64NiceOn implements HttpClientA OAuth2AccessTokenVO accessToken = new OAuth2AccessTokenVO(); try (CloseableHttpResponse response = httpClient.execute(httpPost)) { if (response.getCode() != 200) { - throw new Exception("NiceOn token receive status fail value= " + response.getCode()); + throw new Exception("NiceOn TOKEN receive status fail value== " + response.getCode()); } logger.info("HttpClientAccessTokenServiceWithBase64NiceOn==>" + response.getCode()); From 6d7e14a50e8d9ad65ffb31a6d8f5866ed86d012d Mon Sep 17 00:00:00 2001 From: 25W0075 <25W0075@P9801Z.kjbank.dom> Date: Wed, 17 Dec 2025 11:33:31 +0900 Subject: [PATCH 048/159] =?UTF-8?q?=EC=88=98=EC=A0=95=20test=EC=9C=84?= =?UTF-8?q?=ED=95=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../impl/HttpClientAccessTokenServiceWithBase64NiceOn.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/com/eactive/eai/authoutbound/client/impl/HttpClientAccessTokenServiceWithBase64NiceOn.java b/src/main/java/com/eactive/eai/authoutbound/client/impl/HttpClientAccessTokenServiceWithBase64NiceOn.java index 6890c9c..5fef85f 100644 --- a/src/main/java/com/eactive/eai/authoutbound/client/impl/HttpClientAccessTokenServiceWithBase64NiceOn.java +++ b/src/main/java/com/eactive/eai/authoutbound/client/impl/HttpClientAccessTokenServiceWithBase64NiceOn.java @@ -248,7 +248,7 @@ public class HttpClientAccessTokenServiceWithBase64NiceOn implements HttpClientA HttpEntity entity = response.getEntity(); String responseString = EntityUtils.toString(entity, encode); - logger.debug("Base64NiceOn oauthToken RECV = [" + responseString + "]"); + logger.debug("Base64NiceOn oauthToken RECV == [" + responseString + "]"); if (StringUtils.isNotBlank(responseString)) { From 14b70a5addf6b5747c2d1b4455db4f17ec7e2178 Mon Sep 17 00:00:00 2001 From: 25W0075 <25W0075@P9801Z.kjbank.dom> Date: Wed, 17 Dec 2025 11:45:14 +0900 Subject: [PATCH 049/159] =?UTF-8?q?test=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../impl/HttpClientAccessTokenServiceWithBase64NiceOn.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/main/java/com/eactive/eai/authoutbound/client/impl/HttpClientAccessTokenServiceWithBase64NiceOn.java b/src/main/java/com/eactive/eai/authoutbound/client/impl/HttpClientAccessTokenServiceWithBase64NiceOn.java index 5fef85f..e694f6f 100644 --- a/src/main/java/com/eactive/eai/authoutbound/client/impl/HttpClientAccessTokenServiceWithBase64NiceOn.java +++ b/src/main/java/com/eactive/eai/authoutbound/client/impl/HttpClientAccessTokenServiceWithBase64NiceOn.java @@ -120,7 +120,8 @@ public class HttpClientAccessTokenServiceWithBase64NiceOn implements HttpClientA formParams.add(new BasicNameValuePair("scope", oAuthCredentialVo.getScope())); formParams.add(new BasicNameValuePair("grant_type", oAuthCredentialVo.getGrantType())); - String postParameters = "client_id=" + oAuthCredentialVo.getClientId() + "&client_secret=" + oAuthCredentialVo.getClientSecret() + "&scope=" + oAuthCredentialVo.getScope() + "&grant_type=" + oAuthCredentialVo.getGrantType(); + //String postParameters = "client_id=" + oAuthCredentialVo.getClientId() + "&client_secret=" + oAuthCredentialVo.getClientSecret() + "&scope=" + oAuthCredentialVo.getScope() + "&grant_type=" + oAuthCredentialVo.getGrantType(); + String postParameters = "grant_type=" + oAuthCredentialVo.getGrantType() + "&scope=" + oAuthCredentialVo.getScope(); // mTLS config with default connection parameters From 908d314576da15159f740c17d4c117ae14c3f41d Mon Sep 17 00:00:00 2001 From: 25W0075 <25W0075@P9801Z.kjbank.dom> Date: Wed, 17 Dec 2025 13:34:48 +0900 Subject: [PATCH 050/159] =?UTF-8?q?test=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../impl/HttpClientAccessTokenServiceWithBase64NiceOn.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/com/eactive/eai/authoutbound/client/impl/HttpClientAccessTokenServiceWithBase64NiceOn.java b/src/main/java/com/eactive/eai/authoutbound/client/impl/HttpClientAccessTokenServiceWithBase64NiceOn.java index e694f6f..8c4a102 100644 --- a/src/main/java/com/eactive/eai/authoutbound/client/impl/HttpClientAccessTokenServiceWithBase64NiceOn.java +++ b/src/main/java/com/eactive/eai/authoutbound/client/impl/HttpClientAccessTokenServiceWithBase64NiceOn.java @@ -201,7 +201,7 @@ public class HttpClientAccessTokenServiceWithBase64NiceOn implements HttpClientA HttpPost httpPost = new HttpPost(uri); //httpPost.setEntity(new UrlEncodedFormEntity(formParams, charset)); httpPost.setEntity(new StringEntity(postParameters, StandardCharsets.UTF_8)); - httpPost.setHeader("Content-Type", contentType+" charset=" + encode); + httpPost.setHeader("Content-Type", contentType+";charset=" + encode); //HTTP HEADER에 client id, client secret를 base64Encode 한 후 추가 String cId = oAuthCredentialVo.getClientId(); From 68aac38f11f28d91defb94d4c9d068561f86ca04 Mon Sep 17 00:00:00 2001 From: jaewohong Date: Thu, 18 Dec 2025 09:36:53 +0900 Subject: [PATCH 051/159] =?UTF-8?q?Niceon=20=EC=95=94=ED=98=B8=ED=99=94=20?= =?UTF-8?q?key=20=EC=83=9D=EC=84=B1=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../impl/HttpClient5AdapterServiceRest.java | 50 +++++++++++++++---- .../http/dynamic/HttpAdapterServiceKey.java | 1 + ...entAccessTokenServiceWithBase64NiceOn.java | 48 ++++++++++-------- .../eai/common/token/OAuth2AccessTokenVO.java | 10 ++++ 4 files changed, 78 insertions(+), 31 deletions(-) diff --git a/src/main/java/com/eactive/eai/adapter/http/client/impl/HttpClient5AdapterServiceRest.java b/src/main/java/com/eactive/eai/adapter/http/client/impl/HttpClient5AdapterServiceRest.java index 2491d51..50eb1f9 100644 --- a/src/main/java/com/eactive/eai/adapter/http/client/impl/HttpClient5AdapterServiceRest.java +++ b/src/main/java/com/eactive/eai/adapter/http/client/impl/HttpClient5AdapterServiceRest.java @@ -91,7 +91,7 @@ import com.kjbank.encrypt.exchange.crypto.AES256GCMCipher; import com.kjbank.encrypt.exchange.crypto.ECDHESA256Cipher; import com.eactive.eai.authserver.service.OAuth2Manager; import java.util.Set; - +import java.util.HashSet; /** * 1. 기능 : EAI HTTP OutBound 용 어댑터로 수동 시스템의 HTTP 웹 컴포넌트를 GET/POST 방식으로 호출할 수 있는 @@ -325,9 +325,10 @@ public class HttpClient5AdapterServiceRest extends HttpClient5AdapterServiceSupp if ( niceToken == null || niceToken == "") { throw new Exception("NiceOn Token is empty, TOKEN failed to be issued, TOKEN = [" + niceToken + "]"); } - String clientId = JwtClientIdExtractor(niceToken); + String clientId = accessToken.getClientId(); // HttpClientAccessTokenServiceWithBase64NiceOn 서 넣어줌 long currentTime = System.currentTimeMillis(); auth = niceToken + ":" + currentTime + ":" + clientId ; + logger.debug("HttpClientAdapterServiceRest] NiceOn auth = [" + auth + "]"); auth = Base64.getEncoder().encodeToString(auth.getBytes("UTF-8")); setNiceOnAuthHeaders(method, auth); @@ -853,21 +854,50 @@ public class HttpClient5AdapterServiceRest extends HttpClient5AdapterServiceSupp jwtToken = authorization.substring(7); // "Bearer " 이후의 JWT만 추출 } + + String headerRelay = PropManager.getInstance().getProperty("HEADER_RELAY_ADAPTER","adapter.name"); + Set values = new HashSet<>(Arrays.asList(headerRelay.split(","))); + String inputAdapter = tempProp.getProperty(HttpAdapterServiceKey.OUT_ADAPTER_GROUP_NAME, ""); + + String[] parts = inputAdapter.split("_"); + String target = parts[1]; // adapter name의 앞의 3자리 + String adapterName = target.substring(0, 3); + + if (values.contains(adapterName)) { + + /* 업체정보 */ + String clientId = JwtClientIdExtractor(jwtToken); + method.setHeader("clientId", clientId); + + /* APIM 거래추적자 */ + String uuid = tempProp.getProperty(TransactionContextKeys.TRANSACTION_UUID, ""); + method.setHeader("traceId", uuid); + + /* GUID */ + String guid = tempProp.getProperty(TransactionContextKeys.GUID, ""); + method.setHeader("guid", guid); + + /* 최초요청시간 */ + String receivedTimestamp = tempProp.getProperty(HttpAdapterServiceKey.INBOUND_REQUESTED_TIME, ""); + method.setHeader("receivedTimestamp", receivedTimestamp); + } + + /* 업체정보 */ - String clientId = JwtClientIdExtractor(jwtToken); - method.setHeader("clientId", clientId); + //String clientId = JwtClientIdExtractor(jwtToken); + //method.setHeader("clientId", clientId); /* APIM 거래추적자 */ - String uuid = tempProp.getProperty(TransactionContextKeys.TRANSACTION_UUID, ""); - method.setHeader("traceId", uuid); + //String uuid = tempProp.getProperty(TransactionContextKeys.TRANSACTION_UUID, ""); + //method.setHeader("traceId", uuid); /* GUID */ - String guid = tempProp.getProperty(TransactionContextKeys.GUID, ""); - method.setHeader("guid", guid); + //String guid = tempProp.getProperty(TransactionContextKeys.GUID, ""); + //method.setHeader("guid", guid); /* 최초요청시간 */ - String receivedTimestamp = tempProp.getProperty(HttpAdapterServiceKey.INBOUND_REQUESTED_TIME, ""); - method.setHeader("receivedTimestamp", receivedTimestamp); + //String receivedTimestamp = tempProp.getProperty(HttpAdapterServiceKey.INBOUND_REQUESTED_TIME, ""); + //method.setHeader("receivedTimestamp", receivedTimestamp); return jwtToken; } diff --git a/src/main/java/com/eactive/eai/adapter/http/dynamic/HttpAdapterServiceKey.java b/src/main/java/com/eactive/eai/adapter/http/dynamic/HttpAdapterServiceKey.java index 9fdc548..cbc6ad4 100644 --- a/src/main/java/com/eactive/eai/adapter/http/dynamic/HttpAdapterServiceKey.java +++ b/src/main/java/com/eactive/eai/adapter/http/dynamic/HttpAdapterServiceKey.java @@ -80,6 +80,7 @@ public interface HttpAdapterServiceKey { static final String INBOUND_REQUESTED_TIME = "INBOUND_REQUESTED_TIME"; // jwhong static final String GUID = "GUID"; // jwhong static final String API_SERVICE_CODE = "API_SERVICE_CODE"; // jwhong + static final String OUT_ADAPTER_GROUP_NAME = "OUT_ADAPTER_GROUP_NAME"; // jwhong //응답 처리 용 표준 전문 오브젝트 static final String STANDARD_MESSAGE_OBJECT = "STANDARD_MESSAGE_OBJECT"; diff --git a/src/main/java/com/eactive/eai/authoutbound/client/impl/HttpClientAccessTokenServiceWithBase64NiceOn.java b/src/main/java/com/eactive/eai/authoutbound/client/impl/HttpClientAccessTokenServiceWithBase64NiceOn.java index d960c82..88cf398 100644 --- a/src/main/java/com/eactive/eai/authoutbound/client/impl/HttpClientAccessTokenServiceWithBase64NiceOn.java +++ b/src/main/java/com/eactive/eai/authoutbound/client/impl/HttpClientAccessTokenServiceWithBase64NiceOn.java @@ -115,12 +115,11 @@ public class HttpClientAccessTokenServiceWithBase64NiceOn implements HttpClientA uri, encode, timeout, connectionTimeout, useForwardProxy, forwardProxyUrl); List formParams = new ArrayList<>(); - formParams.add(new BasicNameValuePair("client_id", oAuthCredentialVo.getClientId())); - formParams.add(new BasicNameValuePair("client_secret", oAuthCredentialVo.getClientSecret())); - formParams.add(new BasicNameValuePair("scope", oAuthCredentialVo.getScope())); + //formParams.add(new BasicNameValuePair("client_id", oAuthCredentialVo.getClientId())); + //formParams.add(new BasicNameValuePair("client_secret", oAuthCredentialVo.getClientSecret())); formParams.add(new BasicNameValuePair("grant_type", oAuthCredentialVo.getGrantType())); - - String postParameters = "client_id=" + oAuthCredentialVo.getClientId() + "&client_secret=" + oAuthCredentialVo.getClientSecret() + "&scope=" + oAuthCredentialVo.getScope() + "&grant_type=" + oAuthCredentialVo.getGrantType(); + formParams.add(new BasicNameValuePair("scope", oAuthCredentialVo.getScope())); + //String postParameters = "grant_type=" + oAuthCredentialVo.getGrantType() + "&scope=" + oAuthCredentialVo.getScope(); // mTLS config with default connection parameters @@ -198,9 +197,9 @@ public class HttpClientAccessTokenServiceWithBase64NiceOn implements HttpClientA try (CloseableHttpClient httpClient = HttpClients.custom().setConnectionManager(connectionManager).build();) { HttpPost httpPost = new HttpPost(uri); - //httpPost.setEntity(new UrlEncodedFormEntity(formParams, charset)); - httpPost.setEntity(new StringEntity(postParameters, StandardCharsets.UTF_8)); - httpPost.setHeader("Content-Type", contentType+" charset=" + encode); + httpPost.setEntity(new UrlEncodedFormEntity(formParams, charset)); + //httpPost.setEntity(new StringEntity(postParameters, StandardCharsets.UTF_8)); + httpPost.setHeader("Content-Type", contentType+";charset=" + encode); // 중간에 ; 주어야 함 //HTTP HEADER에 client id, client secret를 base64Encode 한 후 추가 String cId = oAuthCredentialVo.getClientId(); @@ -228,32 +227,38 @@ public class HttpClientAccessTokenServiceWithBase64NiceOn implements HttpClientA .setResponseTimeout(Timeout.ofMilliseconds(timeout)).build(); httpPost.setConfig(requestConfig); - logger.debug("uri = [" + uri + "]"); - logger.debug("oauthClientId = [" + oAuthCredentialVo.getClientId() + "]"); - logger.debug("oauthClientSecret = [" + oAuthCredentialVo.getClientSecret() + "]"); - logger.debug("oauthScope = [" + oAuthCredentialVo.getScope() + "]"); - logger.debug("oauthGrantType = [" + oAuthCredentialVo.getGrantType() + "]"); - logger.debug("oauthauthValue = [" + authValue + "]"); + logger.debug("uri = [" + uri + "]"); + logger.debug("oauthClientId = [" + oAuthCredentialVo.getClientId() + "]"); + logger.debug("oauthClientSecret = [" + oAuthCredentialVo.getClientSecret() + "]"); + logger.debug("oauthScope = [" + oAuthCredentialVo.getScope() + "]"); + logger.debug("oauthGrantType = [" + oAuthCredentialVo.getGrantType() + "]"); + logger.debug("oauthauthValue = [" + authValue + "]"); logger.debug("oauthauthEncodedAuth = [" + encodedAuth + "]"); - logger.debug("contentType = [" + contentType + "]"); - logger.debug("encode = [" + encode + "]"); + logger.debug("contentType = [" + contentType + "]"); + logger.debug("encode = [" + encode + "]"); OAuth2AccessTokenVO accessToken = new OAuth2AccessTokenVO(); try (CloseableHttpResponse response = httpClient.execute(httpPost)) { if (response.getCode() != 200) { - throw new Exception("NiceOn token receive status fail value= " + response.getCode()); + throw new Exception("NiceOn token receive status fail value== " + response.getCode()); } logger.info("HttpClientAccessTokenServiceWithBase64NiceOn==>" + response.getCode()); HttpEntity entity = response.getEntity(); String responseString = EntityUtils.toString(entity, encode); - logger.debug("Base64NiceOn oauthToken RECV = [" + responseString + "]"); + logger.debug("Base64NiceOn oauthToken RECV == [" + responseString + "]"); if (StringUtils.isNotBlank(responseString)) { ObjectMapper objectMapper = new ObjectMapper(); - JsonNode responseJSON = objectMapper.readTree(responseString); + JsonNode responseJSONRtn = objectMapper.readTree(responseString); + JsonNode responseJSON = null; + String gwRsltCd = responseJSONRtn.get("dataHeader").get("GW_RSLT_CD").asText(); + + if ("1200".equals(gwRsltCd)) { + responseJSON = responseJSONRtn.get("dataBody"); + } if (responseJSON.has("access_token") && responseJSON.has("token_type") && responseJSON.has("expires_in") && responseJSON.has("scope")) { @@ -263,13 +268,14 @@ public class HttpClientAccessTokenServiceWithBase64NiceOn implements HttpClientA long expiresIn = responseJSON.get("expires_in").asLong(); accessToken.setExpiration(new Date(currentTime + expiresIn * 1000L)); accessToken.setScope(responseJSON.get("scope").asText()); + accessToken.setClientId(cId); } if (responseJSON.has("client_use_code")) { accessToken.setClientUseCode(responseJSON.get("client_use_code").asText()); } - logger.debug("oauthToken =" + accessToken.toString()); + logger.debug("NiceOn oauthToken =" + accessToken.toString()); return accessToken; } else { @@ -277,7 +283,7 @@ public class HttpClientAccessTokenServiceWithBase64NiceOn implements HttpClientA } } catch (Exception e) { e.printStackTrace(); - logger.error("[HttpClientAccessTokenServiceWithBase64NiceOn] retrieve accessToken exception :" + e.getMessage()); + logger.error("[HttpClientAccessTokenServiceWithBase64NiceOn] retrieve accessToken exception :" + e.getMessage()); return accessToken; } } diff --git a/src/main/java/com/openbanking/eai/common/token/OAuth2AccessTokenVO.java b/src/main/java/com/openbanking/eai/common/token/OAuth2AccessTokenVO.java index 78d4fb5..920121c 100644 --- a/src/main/java/com/openbanking/eai/common/token/OAuth2AccessTokenVO.java +++ b/src/main/java/com/openbanking/eai/common/token/OAuth2AccessTokenVO.java @@ -24,6 +24,7 @@ public class OAuth2AccessTokenVO implements AccessTokenVO, Serializable private Date expiration; private String scope; private String clientUseCode; + private String clientId; public OAuth2AccessTokenVO() { @@ -35,6 +36,7 @@ public class OAuth2AccessTokenVO implements AccessTokenVO, Serializable this.expiration = oAuth2AccessTokenVO.getExpiration(); this.scope = oAuth2AccessTokenVO.getScope(); this.clientUseCode = oAuth2AccessTokenVO.getClientUseCode(); + this.clientId = oAuth2AccessTokenVO.getClientId(); } public String getAccessToken() { @@ -92,6 +94,14 @@ public class OAuth2AccessTokenVO implements AccessTokenVO, Serializable public void setClientUseCode(String clientUseCode) { this.clientUseCode = clientUseCode; } + + public String getClientId() { + return clientId; + } + + public void setClientId(String clientId) { + this.clientId = clientId; + } public String toString() { return ReflectionToStringBuilder.toString(this, ToStringStyle.DEFAULT_STYLE); From c48a30acb46aaa0cfa0b46ed212ebf6e83c9ff5f Mon Sep 17 00:00:00 2001 From: "Yunsam.Eo" Date: Thu, 18 Dec 2025 15:30:03 +0900 Subject: [PATCH 052/159] =?UTF-8?q?doPostFilter=20:=20response=20Header=20?= =?UTF-8?q?Key=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../adapter/http/dynamic/filter/HmacSha256VerifyFilterKjb.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/main/java/com/eactive/eai/adapter/http/dynamic/filter/HmacSha256VerifyFilterKjb.java b/src/main/java/com/eactive/eai/adapter/http/dynamic/filter/HmacSha256VerifyFilterKjb.java index a908c2d..4cd3bcf 100644 --- a/src/main/java/com/eactive/eai/adapter/http/dynamic/filter/HmacSha256VerifyFilterKjb.java +++ b/src/main/java/com/eactive/eai/adapter/http/dynamic/filter/HmacSha256VerifyFilterKjb.java @@ -19,6 +19,7 @@ import com.eactive.eai.adapter.http.dynamic.HttpAdapterServiceKey; import com.eactive.eai.adapter.http.dynamic.HttpAdapterServiceSupport; import com.eactive.eai.authserver.service.OAuth2Manager; import com.eactive.eai.authserver.vo.ClientVO; +import com.eactive.eai.common.TransactionContextKeys; import com.eactive.eai.common.util.Logger; public class HmacSha256VerifyFilterKjb implements HttpAdapterFilter { @@ -139,6 +140,8 @@ public class HmacSha256VerifyFilterKjb implements HttpAdapterFilter { String macBody = calculateHMAC(outboundBody, clientSecret); response.addHeader("x-obp-signature-body", macBody); + response.addHeader("x-obp-partnercode", request.getHeader("x-obp-partnercode")); + response.addHeader("x-obp-txid", prop.getProperty(TransactionContextKeys.TRANSACTION_UUID,"")); } catch (Exception e) { logger.error(e.getMessage()); } From 204953227c9765216ae8e056f0f4bbab832849b5 Mon Sep 17 00:00:00 2001 From: "Yunsam.Eo" Date: Thu, 18 Dec 2025 15:31:23 +0900 Subject: [PATCH 053/159] =?UTF-8?q?getApiScopeRelationsByApiId=20return?= =?UTF-8?q?=EA=B0=92=20=EC=98=A4=EB=A5=98=20=EC=88=98=EC=A0=95(=EC=98=A4?= =?UTF-8?q?=ED=98=95=EC=84=9D=EC=9D=B4=EC=82=AC=20=EA=B0=80=EC=9D=B4?= =?UTF-8?q?=EB=93=9C)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/com/eactive/eai/authserver/dao/ScopeDAO.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/com/eactive/eai/authserver/dao/ScopeDAO.java b/src/main/java/com/eactive/eai/authserver/dao/ScopeDAO.java index 3cae28a..d24d681 100644 --- a/src/main/java/com/eactive/eai/authserver/dao/ScopeDAO.java +++ b/src/main/java/com/eactive/eai/authserver/dao/ScopeDAO.java @@ -54,7 +54,7 @@ public class ScopeDAO extends BaseDAO { ScopeEntity scopeEntity = scopeLoader.findByIdBzwksvckeyname(apiId); - scopeSet.add(scopeEntity.getId().getBzwksvckeyname()); + scopeSet.add(scopeEntity.getId().getScopeid()); return scopeSet; } catch (Exception e) { throw new DAOException(ExceptionUtil.getErrorCode(e, "RECEAIAUC001")); From 459890380333a7aeffd9e23df76605fce628122d Mon Sep 17 00:00:00 2001 From: pksup Date: Thu, 18 Dec 2025 15:58:28 +0900 Subject: [PATCH 054/159] =?UTF-8?q?error=20message=20format=20=EB=B3=80?= =?UTF-8?q?=EA=B2=BD=20-=20OAuth2=20RFC=206749=2022a2a0fd2268cdc2635dfcda5?= =?UTF-8?q?c407756a799316b?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/com/eactive/eai/common/util/MessageUtil.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/com/eactive/eai/common/util/MessageUtil.java b/src/main/java/com/eactive/eai/common/util/MessageUtil.java index 4304ff1..6ff58b1 100644 --- a/src/main/java/com/eactive/eai/common/util/MessageUtil.java +++ b/src/main/java/com/eactive/eai/common/util/MessageUtil.java @@ -34,7 +34,7 @@ import com.solab.iso8583.IsoMessage; public final class MessageUtil { static Logger logger = LoggerFactory.getLogger(MessageUtil.class); - public static final String ERROR_MESSAGE_DEFAULT_FORMAT = "{\"error\":{\"code\":\"%s\",\"message\":\"%s\"}}"; + public static final String ERROR_MESSAGE_DEFAULT_FORMAT = "{\"error\":\"%s\",\"error_description\":\"%s\"}"; public static final String ERROR_CODE_AP_ERROR = "E.GW.AP_ERROR"; public static final String ERROR_CODE_AUTH_FAIL = "E.GW.AUTH_FAIL"; From 445117c4fb245824fc965cd5b3e875da0ab0e012 Mon Sep 17 00:00:00 2001 From: yunjy-hp Date: Thu, 18 Dec 2025 17:28:18 +0900 Subject: [PATCH 055/159] =?UTF-8?q?=EC=84=9C=ED=82=B7=20=EB=B8=8C=EB=A0=88?= =?UTF-8?q?=EC=9D=B4=EC=BB=A4=20SMS=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/com/eactive/eai/outbound/RESTProcess.java | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/main/java/com/eactive/eai/outbound/RESTProcess.java b/src/main/java/com/eactive/eai/outbound/RESTProcess.java index bc4f0cf..47db22c 100644 --- a/src/main/java/com/eactive/eai/outbound/RESTProcess.java +++ b/src/main/java/com/eactive/eai/outbound/RESTProcess.java @@ -5,12 +5,14 @@ import java.util.Properties; import com.eactive.eai.common.TransactionContextKeys; import com.eactive.eai.common.circuitBreaker.CircuitBreakerManager; +import com.eactive.eai.common.util.SMSLogUtil; import com.eactive.eai.message.StandardMessage; import com.eactive.eai.util.PropertiesUtil; import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.node.ObjectNode; import com.initech.core.util.PropertiesManager; +import io.github.resilience4j.circuitbreaker.CallNotPermittedException; import io.github.resilience4j.circuitbreaker.CircuitBreaker; import org.apache.commons.lang3.StringUtils; @@ -105,7 +107,12 @@ public class RESTProcess extends HTTPProcess { combinedNode.set("metrics", objectMapper.valueToTree(circuitBreaker.getMetrics())); logger.info("CircuitBreaker state "+combinedNode.toString()); - this.resObject = circuitBreaker.executeCallable(() -> HttpSender.callService(this.adapterGroupName, this.outboundProp, this.reqObject, this.tempProp)); + try { + this.resObject = circuitBreaker.executeCallable(() -> HttpSender.callService(this.adapterGroupName, this.outboundProp, this.reqObject, this.tempProp)); + }catch(CallNotPermittedException callNotPermittedException){ + SMSLogUtil.loggingSMS(reqEaiMsg.getEAISvcCd(), "CIRCUIT_IS_OPEN!"); + throw callNotPermittedException; + } }else{ this.resObject = HttpSender.callService(this.adapterGroupName, this.outboundProp, this.reqObject, this.tempProp); } From 0aa9dbee6f93799ad1bcae8e97844dff91304c9f Mon Sep 17 00:00:00 2001 From: jaewohong Date: Fri, 19 Dec 2025 10:49:58 +0900 Subject: [PATCH 056/159] =?UTF-8?q?NiceOn=20=EC=97=85=EB=AC=B4=EC=9A=94?= =?UTF-8?q?=EC=B2=AD=EC=8B=9C=20header=20=EC=88=98=EC=A0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../http/client/impl/HttpClient5AdapterServiceRest.java | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/eactive/eai/adapter/http/client/impl/HttpClient5AdapterServiceRest.java b/src/main/java/com/eactive/eai/adapter/http/client/impl/HttpClient5AdapterServiceRest.java index 50eb1f9..48a27bd 100644 --- a/src/main/java/com/eactive/eai/adapter/http/client/impl/HttpClient5AdapterServiceRest.java +++ b/src/main/java/com/eactive/eai/adapter/http/client/impl/HttpClient5AdapterServiceRest.java @@ -92,6 +92,7 @@ import com.kjbank.encrypt.exchange.crypto.ECDHESA256Cipher; import com.eactive.eai.authserver.service.OAuth2Manager; import java.util.Set; import java.util.HashSet; +import java.util.Date; /** * 1. 기능 : EAI HTTP OutBound 용 어댑터로 수동 시스템의 HTTP 웹 컴포넌트를 GET/POST 방식으로 호출할 수 있는 @@ -326,7 +327,8 @@ public class HttpClient5AdapterServiceRest extends HttpClient5AdapterServiceSupp throw new Exception("NiceOn Token is empty, TOKEN failed to be issued, TOKEN = [" + niceToken + "]"); } String clientId = accessToken.getClientId(); // HttpClientAccessTokenServiceWithBase64NiceOn 서 넣어줌 - long currentTime = System.currentTimeMillis(); + Date currentDate = new Date(); + long currentTime = currentDate.getTime() / 1000; auth = niceToken + ":" + currentTime + ":" + clientId ; logger.debug("HttpClientAdapterServiceRest] NiceOn auth = [" + auth + "]"); auth = Base64.getEncoder().encodeToString(auth.getBytes("UTF-8")); @@ -339,7 +341,7 @@ public class HttpClient5AdapterServiceRest extends HttpClient5AdapterServiceSupp if (logger.isDebug()) { logger.debug("HttpClientAdapterServiceRest] SEND (" + vo.getAdapterGroupName() - + ") RequestHeader [Authorization=" + method.getHeader("Authorization") + "]"); + + ") RequestHeader [" + method.getHeader("Authorization").getName() + ": " + method.getHeader("Authorization").getValue() + "]"); } } From 3901c92c94909a800ddd67d399e56216a221e418 Mon Sep 17 00:00:00 2001 From: 25W0075 <25W0075@P9801Z.kjbank.dom> Date: Fri, 19 Dec 2025 14:14:08 +0900 Subject: [PATCH 057/159] =?UTF-8?q?productcd=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../adapter/http/client/impl/HttpClient5AdapterServiceRest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/com/eactive/eai/adapter/http/client/impl/HttpClient5AdapterServiceRest.java b/src/main/java/com/eactive/eai/adapter/http/client/impl/HttpClient5AdapterServiceRest.java index 48a27bd..26be9b2 100644 --- a/src/main/java/com/eactive/eai/adapter/http/client/impl/HttpClient5AdapterServiceRest.java +++ b/src/main/java/com/eactive/eai/adapter/http/client/impl/HttpClient5AdapterServiceRest.java @@ -729,7 +729,7 @@ public class HttpClient5AdapterServiceRest extends HttpClient5AdapterServiceSupp private void setNiceOnAuthHeaders(HttpUriRequestBase method, String auth) throws Exception { method.setHeader("Authorization", String.format("%s %s", AccessTokenVO.BEARER_TYPE, auth)); // 나이스지키미 format임 - method.setHeader("ProductID", "2303345072"); + method.setHeader("ProductID", "2303102120"); //method.setHeader("Authorization", // String.format("%s %s", AccessTokenVO.BEARER_TYPE, accessToken.getAccessToken())); } From 409dafa4753f60afa9ab7dcd6a7a71e5374a106a Mon Sep 17 00:00:00 2001 From: jaewohong Date: Fri, 19 Dec 2025 16:19:35 +0900 Subject: [PATCH 058/159] =?UTF-8?q?NiceOn=20=EC=97=85=EB=AC=B4=EC=9A=94?= =?UTF-8?q?=EC=B2=AD=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../impl/HttpClient5AdapterServiceRest.java | 32 +++++++++++++++---- 1 file changed, 25 insertions(+), 7 deletions(-) diff --git a/src/main/java/com/eactive/eai/adapter/http/client/impl/HttpClient5AdapterServiceRest.java b/src/main/java/com/eactive/eai/adapter/http/client/impl/HttpClient5AdapterServiceRest.java index 48a27bd..5e49e25 100644 --- a/src/main/java/com/eactive/eai/adapter/http/client/impl/HttpClient5AdapterServiceRest.java +++ b/src/main/java/com/eactive/eai/adapter/http/client/impl/HttpClient5AdapterServiceRest.java @@ -7,6 +7,7 @@ import java.net.ConnectException; import java.net.SocketTimeoutException; import java.net.URI; import java.nio.charset.StandardCharsets; +import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.HashMap; import java.util.List; @@ -729,7 +730,8 @@ public class HttpClient5AdapterServiceRest extends HttpClient5AdapterServiceSupp private void setNiceOnAuthHeaders(HttpUriRequestBase method, String auth) throws Exception { method.setHeader("Authorization", String.format("%s %s", AccessTokenVO.BEARER_TYPE, auth)); // 나이스지키미 format임 - method.setHeader("ProductID", "2303345072"); + String productId = PropManager.getInstance().getProperty("NiceOnProperty","productId.value"); + method.setHeader("ProductID", productId); //method.setHeader("Authorization", // String.format("%s %s", AccessTokenVO.BEARER_TYPE, accessToken.getAccessToken())); } @@ -1101,11 +1103,27 @@ public class HttpClient5AdapterServiceRest extends HttpClient5AdapterServiceSupp //break; } - Map map = new HashMap<>(); - map.put(encryptedJsonKey, encryptedMessage); - JSONObject json = new JSONObject(); - json.putAll(map); - return json.toJSONString(); + if (encryptAlgorithm.equals("AES256-NICEON")) { + String goodsCls = PropManager.getInstance().getProperty("NiceOnProperty","goods.cls.value"); + Map map = new HashMap<>(); + SimpleDateFormat sdfDateTime =new SimpleDateFormat("yyyyMMddHHmmss"); + map.put("req_dtm", sdfDateTime); + map.put("goods_cls", goodsCls); + map.put(encryptedJsonKey, encryptedMessage); + JSONObject dataBody = new JSONObject(); + dataBody.putAll(map); + + JSONObject json = new JSONObject(); + json.put("dataBody", dataBody); + return json.toJSONString(); + } else { + Map map = new HashMap<>(); + map.put(encryptedJsonKey, encryptedMessage); + JSONObject json = new JSONObject(); + json.putAll(map); + return json.toJSONString(); + } + //return encryptedMessage; } @@ -1303,7 +1321,7 @@ public class HttpClient5AdapterServiceRest extends HttpClient5AdapterServiceSupp jsonKey = "encryptedData"; break; case "AES256-NICEON": - jsonKey = "preScreeningRequest"; + jsonKey = "enc_data"; break; case "AES256GCM": break; From 0792c481290d9d392355d7a5063e74f28dcec5e2 Mon Sep 17 00:00:00 2001 From: jaewohong Date: Fri, 19 Dec 2025 17:52:38 +0900 Subject: [PATCH 059/159] =?UTF-8?q?niceon=20currentdata=20=EA=B4=80?= =?UTF-8?q?=EB=A0=A8=20=EC=88=98=EC=A0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../impl/HttpClient5AdapterServiceRest.java | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/src/main/java/com/eactive/eai/adapter/http/client/impl/HttpClient5AdapterServiceRest.java b/src/main/java/com/eactive/eai/adapter/http/client/impl/HttpClient5AdapterServiceRest.java index 5e49e25..337ee9c 100644 --- a/src/main/java/com/eactive/eai/adapter/http/client/impl/HttpClient5AdapterServiceRest.java +++ b/src/main/java/com/eactive/eai/adapter/http/client/impl/HttpClient5AdapterServiceRest.java @@ -303,6 +303,7 @@ public class HttpClient5AdapterServiceRest extends HttpClient5AdapterServiceSupp // OAuth2AccessToken check 부분을 뒤에서 여기로 위치를 옮김, 나이스지키미 암호화 KEY를 얻기 위해서. JWHONG OAuth2AccessTokenVO accessToken = null; String auth =""; + Date currentDate = new Date(); if (useAdapterToken) { AccessTokenManagerByDB tokenManager = AccessTokenManagerByDB.getInstance(); accessToken = (OAuth2AccessTokenVO) tokenManager.getAccessTokenVO(vo.getAdapterGroupName()); @@ -327,8 +328,7 @@ public class HttpClient5AdapterServiceRest extends HttpClient5AdapterServiceSupp if ( niceToken == null || niceToken == "") { throw new Exception("NiceOn Token is empty, TOKEN failed to be issued, TOKEN = [" + niceToken + "]"); } - String clientId = accessToken.getClientId(); // HttpClientAccessTokenServiceWithBase64NiceOn 서 넣어줌 - Date currentDate = new Date(); + String clientId = accessToken.getClientId(); // HttpClientAccessTokenServiceWithBase64NiceOn 서 넣어줌 long currentTime = currentDate.getTime() / 1000; auth = niceToken + ":" + currentTime + ":" + clientId ; logger.debug("HttpClientAdapterServiceRest] NiceOn auth = [" + auth + "]"); @@ -377,7 +377,7 @@ public class HttpClient5AdapterServiceRest extends HttpClient5AdapterServiceSupp //assignPostBody(dataContent, contentType, vo.getEncode(), method); // jwhong commnet // KJBank API 추적정보를 Header에 제공. jwhong String inboundToken= assignRequestKJHeaders(method, prop, tempProp ); - assignPostBody(dataContent, contentType, vo.getEncode(), method, vo.getAdapterName(), auth, inboundToken); + assignPostBody(dataContent, contentType, vo.getEncode(), method, vo.getAdapterName(), auth, inboundToken, currentDate); break; default: break; @@ -928,7 +928,7 @@ public class HttpClient5AdapterServiceRest extends HttpClient5AdapterServiceSupp } @SuppressWarnings("deprecation") - private void assignPostBody(Object eaiBody, String contentType, String charset, HttpUriRequestBase method, String adapterName, String niceAuth, String inboundToken) { + private void assignPostBody(Object eaiBody, String contentType, String charset, HttpUriRequestBase method, String adapterName, String niceAuth, String inboundToken, Date currentDate) { if (eaiBody == null) { return; } @@ -949,7 +949,7 @@ public class HttpClient5AdapterServiceRest extends HttpClient5AdapterServiceSupp } else { ContentType contentTypeObj = ContentType.create(contentType, charset); - String eaiBodyMessage = doOutboundPreFilter(eaiBody, adapterName, niceAuth, inboundToken); // jwhong + String eaiBodyMessage = doOutboundPreFilter(eaiBody, adapterName, niceAuth, inboundToken, currentDate); // jwhong StringEntity entity = new StringEntity(eaiBodyMessage, contentTypeObj); // 요청 본문을 StringEntity 객체로 생성 //StringEntity entity = new StringEntity(eaiBody.toString(), contentTypeObj); @@ -960,7 +960,7 @@ public class HttpClient5AdapterServiceRest extends HttpClient5AdapterServiceSupp } // from here by jwhong - private String doOutboundPreFilter(Object eaiBody, String adapterName, String niceAuth, String inboundToken) { + private String doOutboundPreFilter(Object eaiBody, String adapterName, String niceAuth, String inboundToken, Date currentDate) { Properties properties = AdapterPropManager.getInstance().getProperties(adapterName); // jwhong String encryptAlgorithm = properties.getProperty("ENCRYPT_ALGORITHM",""); // jwhong @@ -995,12 +995,12 @@ public class HttpClient5AdapterServiceRest extends HttpClient5AdapterServiceSupp // 여기서 SECRETY인지 nice-auth 인지 check 하여 clientSecret 값을 정하는 logic 추가하여 넘겨야한다. - String responseMessage = doOutboundPreEncrypt(eaiBody, encryptAlgorithm, clientSecret, encryptAES256Iv, encryptAES256Key, certPath); + String responseMessage = doOutboundPreEncrypt(eaiBody, encryptAlgorithm, clientSecret, encryptAES256Iv, encryptAES256Key, certPath, currentDate); logger.debug("outbound pre encrypte value is :"+responseMessage); return responseMessage; } - private String doOutboundPreEncrypt(Object eaiBody, String encryptAlgorithm, String clientSecretKey, String encryptAES256Iv, String encryptAES256Key, String certPath ) { + private String doOutboundPreEncrypt(Object eaiBody, String encryptAlgorithm, String clientSecretKey, String encryptAES256Iv, String encryptAES256Key, String certPath, Date currentDate ) { String encryptedMessage = ""; String encryptedJsonKey = ""; @@ -1107,7 +1107,7 @@ public class HttpClient5AdapterServiceRest extends HttpClient5AdapterServiceSupp String goodsCls = PropManager.getInstance().getProperty("NiceOnProperty","goods.cls.value"); Map map = new HashMap<>(); SimpleDateFormat sdfDateTime =new SimpleDateFormat("yyyyMMddHHmmss"); - map.put("req_dtm", sdfDateTime); + map.put("req_dtm", sdfDateTime.format(currentDate)); map.put("goods_cls", goodsCls); map.put(encryptedJsonKey, encryptedMessage); JSONObject dataBody = new JSONObject(); From 6d75f1870f9fc8729bf551a01e8b4e3ed8e3482d Mon Sep 17 00:00:00 2001 From: "Yunsam.Eo" Date: Sun, 21 Dec 2025 16:24:17 +0900 Subject: [PATCH 060/159] =?UTF-8?q?Outbound=20Filter=20=EC=A0=81=EC=9A=A9?= =?UTF-8?q?=EC=9D=84=20=EC=9C=84=ED=95=9C=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../impl/HttpClient5AdapterServiceRest.java | 24 ++++++++++++++++++- .../http/dynamic/HttpAdapterServiceKey.java | 2 +- .../com/eactive/eai/outbound/RESTProcess.java | 3 +++ 3 files changed, 27 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/eactive/eai/adapter/http/client/impl/HttpClient5AdapterServiceRest.java b/src/main/java/com/eactive/eai/adapter/http/client/impl/HttpClient5AdapterServiceRest.java index 50eb1f9..5c92523 100644 --- a/src/main/java/com/eactive/eai/adapter/http/client/impl/HttpClient5AdapterServiceRest.java +++ b/src/main/java/com/eactive/eai/adapter/http/client/impl/HttpClient5AdapterServiceRest.java @@ -91,6 +91,7 @@ import com.kjbank.encrypt.exchange.crypto.AES256GCMCipher; import com.kjbank.encrypt.exchange.crypto.ECDHESA256Cipher; import com.eactive.eai.authserver.service.OAuth2Manager; import java.util.Set; +import java.util.Map.Entry; import java.util.HashSet; /** @@ -165,6 +166,7 @@ public class HttpClient5AdapterServiceRest extends HttpClient5AdapterServiceSupp // 레이아웃 메시지 타입 REST URL 추출 시 활용. Default JSON String messageType = prop.getProperty("MESSAGE_TYPE", MessageType.JSON); String inboundMethod = tempProp.getProperty(HttpAdapterServiceKey.INBOUND_METHOD, "POST"); + String inboundToken = tempProp.getProperty(HttpAdapterServiceKey.INBOUND_TOKEN, ""); //Outbound 요청에 대한 응답 메시지의 복호화 여부 결정위해 jwhong encryptResponseApply = StringUtils.equalsIgnoreCase(prop.getProperty("ENCRYPT_RESPONSE_APPLY", "N"), "Y"); @@ -349,6 +351,7 @@ public class HttpClient5AdapterServiceRest extends HttpClient5AdapterServiceSupp // 여기 까지 configureHttpClient(requestConfigBuilder, vo, method); + assignFilterHeaders(method, tempProp); // OutBound PreFilter에서 설정한 Header내용 설정. switch (HttpMethodType.getValue(rmethod)) { case GET: @@ -373,7 +376,7 @@ public class HttpClient5AdapterServiceRest extends HttpClient5AdapterServiceSupp // assignPostBody(dataObject, contentType, vo.getEncode(), method); //assignPostBody(dataContent, contentType, vo.getEncode(), method); // jwhong commnet // KJBank API 추적정보를 Header에 제공. jwhong - String inboundToken= assignRequestKJHeaders(method, prop, tempProp ); +// String inboundToken= assignRequestKJHeaders(method, prop, tempProp ); Filter에서 처리함. assignPostBody(dataContent, contentType, vo.getEncode(), method, vo.getAdapterName(), auth, inboundToken); break; default: @@ -804,6 +807,25 @@ public class HttpClient5AdapterServiceRest extends HttpClient5AdapterServiceSupp } } } + + private void assignFilterHeaders(HttpUriRequestBase method, Properties tempProp) { + try { + Properties filterHeaders = (Properties)tempProp.get("FILTERHEADER"); + if (filterHeaders != null){ + for (Entry e : filterHeaders.entrySet()) { + String key = (String) e.getKey(); + String value = (String) e.getValue(); + method.setHeader(key, value); + + if (logger.isDebugEnabled()) { + logger.debug("OutBound Filter] Request Header :" + key + "=[" + value + "]"); + } + } + } + } catch (Exception e) { + logger.error(e.getMessage()); + } + } /* * KJBank Target System으로 요청 보낼때 header에 clientId(업체정보), APIM거래추적자(UUID), 최초 요청시간, guid 추가해서 보낸다. jwhong diff --git a/src/main/java/com/eactive/eai/adapter/http/dynamic/HttpAdapterServiceKey.java b/src/main/java/com/eactive/eai/adapter/http/dynamic/HttpAdapterServiceKey.java index cbc6ad4..c617084 100644 --- a/src/main/java/com/eactive/eai/adapter/http/dynamic/HttpAdapterServiceKey.java +++ b/src/main/java/com/eactive/eai/adapter/http/dynamic/HttpAdapterServiceKey.java @@ -73,7 +73,7 @@ public interface HttpAdapterServiceKey { static final String ENC_PATHS = "ENC_PATHS"; static final String ENCRYPT_ALGORITHM = "ENCRYPT_ALGORITHM"; //jwhong - static final String INBOUND_TOKEN = "authorization"; // jwhong + static final String INBOUND_TOKEN = "AUTHORIZATION"; // jwhong static final String ENCRYPT_BASE_TYPE = "ENCRYPT_BASE_TYPE"; // jwhong static final String ENCRYPT_AES256_IV = "ENCRYPT_AES256_IV"; // jwhong static final String ENCRYPT_AES256_KEY = "ENCRYPT_AES256_KEY"; // jwhong diff --git a/src/main/java/com/eactive/eai/outbound/RESTProcess.java b/src/main/java/com/eactive/eai/outbound/RESTProcess.java index bc4f0cf..5d364ee 100644 --- a/src/main/java/com/eactive/eai/outbound/RESTProcess.java +++ b/src/main/java/com/eactive/eai/outbound/RESTProcess.java @@ -21,6 +21,7 @@ import com.eactive.eai.adapter.AdapterVO; import com.eactive.eai.adapter.http.HttpStatusException; import com.eactive.eai.adapter.http.client.HttpClientAdapterServiceKey; import com.eactive.eai.adapter.http.dynamic.HttpAdapterServiceKey; +import com.eactive.eai.adapter.http.dynamic.HttpAdapterServiceSupport; import com.eactive.eai.common.EAIKeys; import com.eactive.eai.common.exception.ExceptionUtil; import com.eactive.eai.common.header.HeaderAction; @@ -441,6 +442,8 @@ public class RESTProcess extends HTTPProcess { PropertiesUtil.copyPropertyIfPresent(this.callProp, this.tempProp, HttpAdapterServiceKey.INBOUND_SCHEME); PropertiesUtil.copyPropertyIfPresent(this.callProp, this.tempProp, HttpAdapterServiceKey.INBOUND_REQUESTED_TIME); // jwhong PropertiesUtil.copyPropertyIfPresent(this.callProp, this.tempProp, HttpAdapterServiceKey.GUID); // jwhong + PropertiesUtil.copyPropertyIfPresent(this.callProp, this.tempProp, HttpAdapterServiceKey.INBOUND_TOKEN); // jwhong + PropertiesUtil.copyPropertyIfPresent(this.callProp, this.tempProp, HttpAdapterServiceSupport.PROPERTIES_NAME_CLIENT_ID); // jwhong String svcName = getServiceId(this.reqEaiMsg); if (svcName == null) { From 4b7ee9ee5587f81984f5768471af27ab2e967f12 Mon Sep 17 00:00:00 2001 From: "Yunsam.Eo" Date: Sun, 21 Dec 2025 17:20:16 +0900 Subject: [PATCH 061/159] Merge --- .../impl/HttpClient5AdapterServiceRest.java | 66 +++++++++++-------- 1 file changed, 39 insertions(+), 27 deletions(-) diff --git a/src/main/java/com/eactive/eai/adapter/http/client/impl/HttpClient5AdapterServiceRest.java b/src/main/java/com/eactive/eai/adapter/http/client/impl/HttpClient5AdapterServiceRest.java index b238093..f220556 100644 --- a/src/main/java/com/eactive/eai/adapter/http/client/impl/HttpClient5AdapterServiceRest.java +++ b/src/main/java/com/eactive/eai/adapter/http/client/impl/HttpClient5AdapterServiceRest.java @@ -7,10 +7,12 @@ import java.net.ConnectException; import java.net.SocketTimeoutException; import java.net.URI; import java.nio.charset.StandardCharsets; +import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.Map.Entry; import java.util.Properties; import java.util.regex.Matcher; import java.util.regex.Pattern; @@ -51,8 +53,6 @@ import org.springframework.security.oauth2.provider.ClientDetails; import org.springframework.web.util.UriComponents; import org.springframework.web.util.UriComponentsBuilder; -import com.eactive.eai.adapter.AdapterGroupVO; -import com.eactive.eai.adapter.AdapterManager; import com.eactive.eai.adapter.AdapterPropManager; import com.eactive.eai.adapter.http.HttpMemoryLogger; import com.eactive.eai.adapter.http.HttpMethodType; @@ -60,12 +60,6 @@ import com.eactive.eai.adapter.http.client.HttpClient5AdapterServiceSupport; import com.eactive.eai.adapter.http.client.HttpClientAdapterServiceKey; import com.eactive.eai.adapter.http.client.HttpClientAdapterVO; import com.eactive.eai.adapter.http.dynamic.HttpAdapterServiceKey; -import com.eactive.eai.adapter.http.dynamic.filter.AdapterAllowIPListFilter; -import com.eactive.eai.adapter.http.dynamic.filter.ApiAuthFilter; -import com.eactive.eai.adapter.http.dynamic.filter.HttpAdapterFilter; -import com.eactive.eai.adapter.http.dynamic.filter.HttpAdapterFilterType; -import com.eactive.eai.adapter.http.dynamic.filter.IpWhiteListFilter; -import com.eactive.eai.adapter.http.dynamic.filter.JwtAuthFilter; import com.eactive.eai.common.TransactionContextKeys; import com.eactive.eai.common.authoutbound.AccessTokenManagerByDB; import com.eactive.eai.common.exception.ExceptionUtil; @@ -91,8 +85,8 @@ import com.kjbank.encrypt.exchange.crypto.AES256GCMCipher; import com.kjbank.encrypt.exchange.crypto.ECDHESA256Cipher; import com.eactive.eai.authserver.service.OAuth2Manager; import java.util.Set; -import java.util.Map.Entry; import java.util.HashSet; +import java.util.Date; /** * 1. 기능 : EAI HTTP OutBound 용 어댑터로 수동 시스템의 HTTP 웹 컴포넌트를 GET/POST 방식으로 호출할 수 있는 @@ -303,6 +297,7 @@ public class HttpClient5AdapterServiceRest extends HttpClient5AdapterServiceSupp // OAuth2AccessToken check 부분을 뒤에서 여기로 위치를 옮김, 나이스지키미 암호화 KEY를 얻기 위해서. JWHONG OAuth2AccessTokenVO accessToken = null; String auth =""; + Date currentDate = new Date(); if (useAdapterToken) { AccessTokenManagerByDB tokenManager = AccessTokenManagerByDB.getInstance(); accessToken = (OAuth2AccessTokenVO) tokenManager.getAccessTokenVO(vo.getAdapterGroupName()); @@ -327,8 +322,8 @@ public class HttpClient5AdapterServiceRest extends HttpClient5AdapterServiceSupp if ( niceToken == null || niceToken == "") { throw new Exception("NiceOn Token is empty, TOKEN failed to be issued, TOKEN = [" + niceToken + "]"); } - String clientId = accessToken.getClientId(); // HttpClientAccessTokenServiceWithBase64NiceOn 서 넣어줌 - long currentTime = System.currentTimeMillis(); + String clientId = accessToken.getClientId(); // HttpClientAccessTokenServiceWithBase64NiceOn 서 넣어줌 + long currentTime = currentDate.getTime() / 1000; auth = niceToken + ":" + currentTime + ":" + clientId ; logger.debug("HttpClientAdapterServiceRest] NiceOn auth = [" + auth + "]"); auth = Base64.getEncoder().encodeToString(auth.getBytes("UTF-8")); @@ -341,7 +336,7 @@ public class HttpClient5AdapterServiceRest extends HttpClient5AdapterServiceSupp if (logger.isDebug()) { logger.debug("HttpClientAdapterServiceRest] SEND (" + vo.getAdapterGroupName() - + ") RequestHeader [Authorization=" + method.getHeader("Authorization") + "]"); + + ") RequestHeader [" + method.getHeader("Authorization").getName() + ": " + method.getHeader("Authorization").getValue() + "]"); } } @@ -376,8 +371,8 @@ public class HttpClient5AdapterServiceRest extends HttpClient5AdapterServiceSupp // assignPostBody(dataObject, contentType, vo.getEncode(), method); //assignPostBody(dataContent, contentType, vo.getEncode(), method); // jwhong commnet // KJBank API 추적정보를 Header에 제공. jwhong -// String inboundToken= assignRequestKJHeaders(method, prop, tempProp ); Filter에서 처리함. - assignPostBody(dataContent, contentType, vo.getEncode(), method, vo.getAdapterName(), auth, inboundToken); +// String inboundToken= assignRequestKJHeaders(method, prop, tempProp ); + assignPostBody(dataContent, contentType, vo.getEncode(), method, vo.getAdapterName(), auth, inboundToken, currentDate); break; default: break; @@ -392,7 +387,7 @@ public class HttpClient5AdapterServiceRest extends HttpClient5AdapterServiceSupp // 전달 header 셋팅 // Adapter 레벨 header 보다 data로 넘어온 httpHeader를 우선 적용(header명이 같다면 덮어씀) - assignRequestHeaders(method, httpHeader); + assignRequestHeaders(method, httpHeader); // KJBank API 추적정보를 Header에 제공. jwhong //assignRequestKJHeaders(method, prop, tempProp ); @@ -730,7 +725,8 @@ public class HttpClient5AdapterServiceRest extends HttpClient5AdapterServiceSupp private void setNiceOnAuthHeaders(HttpUriRequestBase method, String auth) throws Exception { method.setHeader("Authorization", String.format("%s %s", AccessTokenVO.BEARER_TYPE, auth)); // 나이스지키미 format임 - method.setHeader("ProductID", "2303345072"); + String productId = PropManager.getInstance().getProperty("NiceOnProperty","productId.value"); + method.setHeader("ProductID", productId); //method.setHeader("Authorization", // String.format("%s %s", AccessTokenVO.BEARER_TYPE, accessToken.getAccessToken())); } @@ -946,7 +942,7 @@ public class HttpClient5AdapterServiceRest extends HttpClient5AdapterServiceSupp } @SuppressWarnings("deprecation") - private void assignPostBody(Object eaiBody, String contentType, String charset, HttpUriRequestBase method, String adapterName, String niceAuth, String inboundToken) { + private void assignPostBody(Object eaiBody, String contentType, String charset, HttpUriRequestBase method, String adapterName, String niceAuth, String inboundToken, Date currentDate) { if (eaiBody == null) { return; } @@ -967,7 +963,7 @@ public class HttpClient5AdapterServiceRest extends HttpClient5AdapterServiceSupp } else { ContentType contentTypeObj = ContentType.create(contentType, charset); - String eaiBodyMessage = doOutboundPreFilter(eaiBody, adapterName, niceAuth, inboundToken); // jwhong + String eaiBodyMessage = doOutboundPreFilter(eaiBody, adapterName, niceAuth, inboundToken, currentDate); // jwhong StringEntity entity = new StringEntity(eaiBodyMessage, contentTypeObj); // 요청 본문을 StringEntity 객체로 생성 //StringEntity entity = new StringEntity(eaiBody.toString(), contentTypeObj); @@ -978,7 +974,7 @@ public class HttpClient5AdapterServiceRest extends HttpClient5AdapterServiceSupp } // from here by jwhong - private String doOutboundPreFilter(Object eaiBody, String adapterName, String niceAuth, String inboundToken) { + private String doOutboundPreFilter(Object eaiBody, String adapterName, String niceAuth, String inboundToken, Date currentDate) { Properties properties = AdapterPropManager.getInstance().getProperties(adapterName); // jwhong String encryptAlgorithm = properties.getProperty("ENCRYPT_ALGORITHM",""); // jwhong @@ -1013,12 +1009,12 @@ public class HttpClient5AdapterServiceRest extends HttpClient5AdapterServiceSupp // 여기서 SECRETY인지 nice-auth 인지 check 하여 clientSecret 값을 정하는 logic 추가하여 넘겨야한다. - String responseMessage = doOutboundPreEncrypt(eaiBody, encryptAlgorithm, clientSecret, encryptAES256Iv, encryptAES256Key, certPath); + String responseMessage = doOutboundPreEncrypt(eaiBody, encryptAlgorithm, clientSecret, encryptAES256Iv, encryptAES256Key, certPath, currentDate); logger.debug("outbound pre encrypte value is :"+responseMessage); return responseMessage; } - private String doOutboundPreEncrypt(Object eaiBody, String encryptAlgorithm, String clientSecretKey, String encryptAES256Iv, String encryptAES256Key, String certPath ) { + private String doOutboundPreEncrypt(Object eaiBody, String encryptAlgorithm, String clientSecretKey, String encryptAES256Iv, String encryptAES256Key, String certPath, Date currentDate) { String encryptedMessage = ""; String encryptedJsonKey = ""; @@ -1121,11 +1117,27 @@ public class HttpClient5AdapterServiceRest extends HttpClient5AdapterServiceSupp //break; } - Map map = new HashMap<>(); - map.put(encryptedJsonKey, encryptedMessage); - JSONObject json = new JSONObject(); - json.putAll(map); - return json.toJSONString(); + if (encryptAlgorithm.equals("AES256-NICEON")) { + String goodsCls = PropManager.getInstance().getProperty("NiceOnProperty","goods.cls.value"); + Map map = new HashMap<>(); + SimpleDateFormat sdfDateTime =new SimpleDateFormat("yyyyMMddHHmmss"); + map.put("req_dtm", sdfDateTime.format(currentDate)); + map.put("goods_cls", goodsCls); + map.put(encryptedJsonKey, encryptedMessage); + JSONObject dataBody = new JSONObject(); + dataBody.putAll(map); + + JSONObject json = new JSONObject(); + json.put("dataBody", dataBody); + return json.toJSONString(); + } else { + Map map = new HashMap<>(); + map.put(encryptedJsonKey, encryptedMessage); + JSONObject json = new JSONObject(); + json.putAll(map); + return json.toJSONString(); + } + //return encryptedMessage; } @@ -1323,7 +1335,7 @@ public class HttpClient5AdapterServiceRest extends HttpClient5AdapterServiceSupp jsonKey = "encryptedData"; break; case "AES256-NICEON": - jsonKey = "preScreeningRequest"; + jsonKey = "enc_data"; break; case "AES256GCM": break; From 01980c7274088b83effc137754176546efff7e45 Mon Sep 17 00:00:00 2001 From: jaewohong Date: Mon, 22 Dec 2025 12:56:15 +0900 Subject: [PATCH 062/159] =?UTF-8?q?nice=20on=20=EC=95=94=ED=98=B8=ED=99=94?= =?UTF-8?q?=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../client/impl/HttpClient5AdapterServiceRest.java | 10 +++++++--- .../HttpClientAccessTokenServiceWithBase64NiceOn.java | 2 +- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/src/main/java/com/eactive/eai/adapter/http/client/impl/HttpClient5AdapterServiceRest.java b/src/main/java/com/eactive/eai/adapter/http/client/impl/HttpClient5AdapterServiceRest.java index f220556..84d91bd 100644 --- a/src/main/java/com/eactive/eai/adapter/http/client/impl/HttpClient5AdapterServiceRest.java +++ b/src/main/java/com/eactive/eai/adapter/http/client/impl/HttpClient5AdapterServiceRest.java @@ -84,6 +84,7 @@ import com.nimbusds.jwt.SignedJWT; import com.kjbank.encrypt.exchange.crypto.AES256GCMCipher; import com.kjbank.encrypt.exchange.crypto.ECDHESA256Cipher; import com.eactive.eai.authserver.service.OAuth2Manager; +import com.kjbank.simple.core.exchange.crypto.ExchangeCrypto; import java.util.Set; import java.util.HashSet; import java.util.Date; @@ -327,6 +328,7 @@ public class HttpClient5AdapterServiceRest extends HttpClient5AdapterServiceSupp auth = niceToken + ":" + currentTime + ":" + clientId ; logger.debug("HttpClientAdapterServiceRest] NiceOn auth = [" + auth + "]"); auth = Base64.getEncoder().encodeToString(auth.getBytes("UTF-8")); + logger.debug("HttpClientAdapterServiceRest] NiceOn Base64 encoded auth = [" + auth + "]"); setNiceOnAuthHeaders(method, auth); } else { @@ -1071,8 +1073,10 @@ public class HttpClient5AdapterServiceRest extends HttpClient5AdapterServiceSupp break; case "AES256-NICEON": try { - String key = clientSecretKey.substring(10,42); + String key = clientSecretKey.substring(10,42); + logger.debug("HttpClientAdapterServiceRest] NICE ON AES256 Encryption key is :+="+key); encryptedMessage = AES256Cipher.encrypt(eaiBody.toString(), key); + //encryptedMessage = ExchangeCrypto.encodedData(eaiStringBody, clientSecretKey); } catch (Exception e) { e.printStackTrace(); logger.error("HttpClientAdapterServiceRest] AES256 Encryption error=" + e.getMessage()); @@ -1257,8 +1261,8 @@ public class HttpClient5AdapterServiceRest extends HttpClient5AdapterServiceSupp } break; case "AES256-NICEON": - try { - String key = clientSecretKey.substring(10,42); + try { + String key = clientSecretKey.substring(10,42); String decryptedStrMessage = AES256Cipher.decrypt(eaiStringBody, key); decryptedMessage = decryptedStrMessage.getBytes(StandardCharsets.UTF_8); } catch (Exception e) { diff --git a/src/main/java/com/eactive/eai/authoutbound/client/impl/HttpClientAccessTokenServiceWithBase64NiceOn.java b/src/main/java/com/eactive/eai/authoutbound/client/impl/HttpClientAccessTokenServiceWithBase64NiceOn.java index 88cf398..450962a 100644 --- a/src/main/java/com/eactive/eai/authoutbound/client/impl/HttpClientAccessTokenServiceWithBase64NiceOn.java +++ b/src/main/java/com/eactive/eai/authoutbound/client/impl/HttpClientAccessTokenServiceWithBase64NiceOn.java @@ -283,7 +283,7 @@ public class HttpClientAccessTokenServiceWithBase64NiceOn implements HttpClientA } } catch (Exception e) { e.printStackTrace(); - logger.error("[HttpClientAccessTokenServiceWithBase64NiceOn] retrieve accessToken exception :" + e.getMessage()); + logger.error("[HttpClientAccessTokenServiceWithBase64NiceOn] retrieve accessToken exception :" + e.getMessage()); return accessToken; } } From da83262fcc6e500a6753fddf9723f71d19aa75ed Mon Sep 17 00:00:00 2001 From: jaewohong Date: Mon, 22 Dec 2025 12:58:11 +0900 Subject: [PATCH 063/159] =?UTF-8?q?niceon=20=EC=95=94=ED=98=B8=ED=99=94=20?= =?UTF-8?q?=EC=88=98=EC=A0=952?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../adapter/http/client/impl/HttpClient5AdapterServiceRest.java | 1 - 1 file changed, 1 deletion(-) diff --git a/src/main/java/com/eactive/eai/adapter/http/client/impl/HttpClient5AdapterServiceRest.java b/src/main/java/com/eactive/eai/adapter/http/client/impl/HttpClient5AdapterServiceRest.java index 84d91bd..d0e92da 100644 --- a/src/main/java/com/eactive/eai/adapter/http/client/impl/HttpClient5AdapterServiceRest.java +++ b/src/main/java/com/eactive/eai/adapter/http/client/impl/HttpClient5AdapterServiceRest.java @@ -84,7 +84,6 @@ import com.nimbusds.jwt.SignedJWT; import com.kjbank.encrypt.exchange.crypto.AES256GCMCipher; import com.kjbank.encrypt.exchange.crypto.ECDHESA256Cipher; import com.eactive.eai.authserver.service.OAuth2Manager; -import com.kjbank.simple.core.exchange.crypto.ExchangeCrypto; import java.util.Set; import java.util.HashSet; import java.util.Date; From 9a2b077b5ec2d934e9b3044a868e161c1ec31d09 Mon Sep 17 00:00:00 2001 From: 25W0075 <25W0075@P9801Z.kjbank.dom> Date: Tue, 23 Dec 2025 09:37:45 +0900 Subject: [PATCH 064/159] =?UTF-8?q?bearer=EC=B2=A0=EC=9E=90=20test?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../adapter/http/client/impl/HttpClient5AdapterServiceRest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/com/eactive/eai/adapter/http/client/impl/HttpClient5AdapterServiceRest.java b/src/main/java/com/eactive/eai/adapter/http/client/impl/HttpClient5AdapterServiceRest.java index d0e92da..c38af50 100644 --- a/src/main/java/com/eactive/eai/adapter/http/client/impl/HttpClient5AdapterServiceRest.java +++ b/src/main/java/com/eactive/eai/adapter/http/client/impl/HttpClient5AdapterServiceRest.java @@ -725,7 +725,7 @@ public class HttpClient5AdapterServiceRest extends HttpClient5AdapterServiceSupp */ private void setNiceOnAuthHeaders(HttpUriRequestBase method, String auth) throws Exception { method.setHeader("Authorization", - String.format("%s %s", AccessTokenVO.BEARER_TYPE, auth)); // 나이스지키미 format임 + String.format("%s %s", "bearer", auth)); // 나이스지키미 format임 String productId = PropManager.getInstance().getProperty("NiceOnProperty","productId.value"); method.setHeader("ProductID", productId); //method.setHeader("Authorization", From f83b555036d82a488fd2c19866ac2045b5541c66 Mon Sep 17 00:00:00 2001 From: jaewohong Date: Tue, 23 Dec 2025 16:08:22 +0900 Subject: [PATCH 065/159] =?UTF-8?q?nice=20on=20=ED=98=B8=EC=B6=9C=EC=8B=9C?= =?UTF-8?q?=20Bearer=EC=9D=84=20bearer=EB=A1=9C=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../adapter/http/client/impl/HttpClient5AdapterServiceRest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/com/eactive/eai/adapter/http/client/impl/HttpClient5AdapterServiceRest.java b/src/main/java/com/eactive/eai/adapter/http/client/impl/HttpClient5AdapterServiceRest.java index d0e92da..9d8a195 100644 --- a/src/main/java/com/eactive/eai/adapter/http/client/impl/HttpClient5AdapterServiceRest.java +++ b/src/main/java/com/eactive/eai/adapter/http/client/impl/HttpClient5AdapterServiceRest.java @@ -725,7 +725,7 @@ public class HttpClient5AdapterServiceRest extends HttpClient5AdapterServiceSupp */ private void setNiceOnAuthHeaders(HttpUriRequestBase method, String auth) throws Exception { method.setHeader("Authorization", - String.format("%s %s", AccessTokenVO.BEARER_TYPE, auth)); // 나이스지키미 format임 + String.format("%s %s", "bearer", auth)); // 나이스지키미 format임, bearer을 소문자로 보내야함 String productId = PropManager.getInstance().getProperty("NiceOnProperty","productId.value"); method.setHeader("ProductID", productId); //method.setHeader("Authorization", From b2e6484c3464f089b063c1a7c3399416d9971a05 Mon Sep 17 00:00:00 2001 From: "Yunsam.Eo" Date: Fri, 26 Dec 2025 16:04:12 +0900 Subject: [PATCH 066/159] =?UTF-8?q?Http=20Adapter=20400=EC=9D=91=EB=8B=B5?= =?UTF-8?q?=EC=8B=9C=20300=EC=97=90=EC=84=9C=20=EC=88=98=EC=8B=A0=ED=95=9C?= =?UTF-8?q?=20Header=EC=9D=98=20Content-Type=20=EA=B7=B8=EB=8C=80=EB=A1=9C?= =?UTF-8?q?=20=EC=84=A4=EC=A0=95=ED=95=98=EA=B2=8C=20=EC=88=98=EC=A0=95.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../impl/HttpAdapterServiceStandard.java | 20 +++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/eactive/eai/adapter/http/dynamic/impl/HttpAdapterServiceStandard.java b/src/main/java/com/eactive/eai/adapter/http/dynamic/impl/HttpAdapterServiceStandard.java index fc2da76..d3e1287 100644 --- a/src/main/java/com/eactive/eai/adapter/http/dynamic/impl/HttpAdapterServiceStandard.java +++ b/src/main/java/com/eactive/eai/adapter/http/dynamic/impl/HttpAdapterServiceStandard.java @@ -6,6 +6,7 @@ import com.eactive.eai.adapter.AdapterVO; import com.eactive.eai.adapter.Keys; import com.eactive.eai.adapter.http.HttpMemoryLogger; import com.eactive.eai.adapter.http.HttpStatusException; +import com.eactive.eai.adapter.http.dynamic.HttpAdapterServiceKey; import com.eactive.eai.adapter.http.dynamic.HttpAdapterServiceSupport; import com.eactive.eai.common.exception.ExceptionUtil; import com.eactive.eai.common.util.CommonLib; @@ -26,8 +27,11 @@ import java.net.URLDecoder; import java.util.ArrayList; import java.util.Collections; import java.util.Enumeration; +import java.util.HashMap; import java.util.List; +import java.util.Map; import java.util.Properties; +import java.util.TreeMap; public class HttpAdapterServiceStandard extends HttpAdapterServiceSupport { @@ -218,8 +222,20 @@ public class HttpAdapterServiceStandard extends HttpAdapterServiceSupport if (addData.length() > 0){ responseData = addData + responseData; } - // UI와 통신시(UTF-8) 변환오류로 ENCODE 제거 - response.setContentType("text/plain"); + + // 300응답에서 받은 Header정보 사용하기 위해 읽어옴. + Map responsePropertyMap = new HashMap(); + responsePropertyMap = (Map) prop.get(OUTBOUND_PROPERTY_MAP); + Properties responseHeaders = (Properties)responsePropertyMap.get(OUTBOUND_RESPONSE_HEADERS); + Map responseHeaderMap = new TreeMap<>(String.CASE_INSENSITIVE_ORDER); + // Properties 내용을 모두 복사 + for (String name : responseHeaders.stringPropertyNames()) { + responseHeaderMap.put(name, responseHeaders.getProperty(name)); + } + String contentTytpe = responseHeaderMap.get("Content-Type"); + + // UI와 통신시(UTF-8) 변환오류로 ENCODE 제거 + response.setContentType(contentTytpe); // 300응답에서 받은 Content-Type을 그대로 적용. response.setCharacterEncoding(encode); response.getWriter().print(responseData); if (logger.isDebug()){ From 35fbb771912e4ea2b3fd7a0972c7272f05b2c1f2 Mon Sep 17 00:00:00 2001 From: yunjy-hp Date: Tue, 30 Dec 2025 10:24:29 +0900 Subject: [PATCH 067/159] =?UTF-8?q?=EC=9C=A0=EB=9F=89=EC=A0=9C=EC=96=B4=20?= =?UTF-8?q?FIX,=20=ED=91=9C=EC=A4=80=EC=A0=84=EB=AC=B8=20FIX?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../eactive/eai/common/inflow/InflowControlManager.java | 4 +--- .../eactive/eai/inbound/processor/RequestProcessor.java | 7 ++++--- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/src/main/java/com/eactive/eai/common/inflow/InflowControlManager.java b/src/main/java/com/eactive/eai/common/inflow/InflowControlManager.java index 9c527fd..f200d3e 100644 --- a/src/main/java/com/eactive/eai/common/inflow/InflowControlManager.java +++ b/src/main/java/com/eactive/eai/common/inflow/InflowControlManager.java @@ -67,11 +67,9 @@ public class InflowControlManager implements Lifecycle, Bucket { */ public static Boolean isTargetOfInflowControl(EAIServerManager eaiServerManager, EAIMessage eaiMessage) { InterfaceMapper mapper = eaiMessage.getMapper(); - String inExDiv = MessageUtil.getInExDivision(mapper.getInExDivision(eaiMessage.getStandardMessage()), - eaiMessage.getInternalExternalDvcd()); // 1|2 String returnType = mapper.getSendRecvDivision(eaiMessage.getStandardMessage()); // S|R - if (STDMessageKeys.DIRECTION_IN.equals(inExDiv) && STDMessageKeys.SEND_RECV_CD_SEND.equals(returnType)) { + if (STDMessageKeys.SEND_RECV_CD_SEND.equals(returnType)) { return Boolean.valueOf(true); } diff --git a/src/main/java/com/eactive/eai/inbound/processor/RequestProcessor.java b/src/main/java/com/eactive/eai/inbound/processor/RequestProcessor.java index 7175d74..cff816c 100644 --- a/src/main/java/com/eactive/eai/inbound/processor/RequestProcessor.java +++ b/src/main/java/com/eactive/eai/inbound/processor/RequestProcessor.java @@ -1036,6 +1036,7 @@ public class RequestProcessor extends RequestProcessorSupport { } } + String inflowErrorMsg; if (blockedType.length() > 0) { InflowTargetVO inflowTargetVO = null; InflowGroupVO inflowGroupVO = null; @@ -1046,7 +1047,6 @@ public class RequestProcessor extends RequestProcessorSupport { } else { inflowTargetVO = bucket.getInterfaceInflowThreashold(vo.getEaiSvcCd()); } - String inflowErrorMsg; // 에러처리 vo.setRspErrorCode(EAIMessageKeys.EAI_INFLOW_BLOCKED_CODE); if (inflowGroupVO != null) { @@ -1161,7 +1161,8 @@ public class RequestProcessor extends RequestProcessorSupport { if (logger.isError()) logger.error(guidLogPrefix + " : 유량제어 비동기 에러응답송신 실패 - " + ee.toString()); } - return null; + throw new HttpStatusException(eaiMsg.getRspErrMsg(), eaiMsg.getRspErrCd(), + HttpStatus.TOO_MANY_REQUESTS.value()); } } } @@ -1273,7 +1274,7 @@ public class RequestProcessor extends RequestProcessorSupport { } //응답 전 표준 전문의 로직 처리 필요 한 경우를 위해 호출 - standardManager.getMessageCoordinator().coordinateBeforeResponse(standardMessage, vo, prop, inboundCharset); + standardManager.getMessageCoordinator().coordinateBeforeResponse(retEaiMsg.getStandardMessage(), vo, prop, inboundCharset); // 10. 응답 거래로그 Logging if(EAIMessageKeys.SYNC_SVC.equals(svcTsmtUsgTp) && From 0e2bdf5d9d6be7f40bc270f6ef1b457fac64263a Mon Sep 17 00:00:00 2001 From: "Yunsam.Eo" Date: Tue, 30 Dec 2025 11:05:36 +0900 Subject: [PATCH 068/159] =?UTF-8?q?pathVariable=20=EC=B2=98=EB=A6=AC?= =?UTF-8?q?=EB=A5=BC=20=EC=9C=84=ED=95=9C=20=20Action=20Calss=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80=EC=84=A4=EC=A0=95.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/com/eactive/eai/message/StandardMessageUtil.java | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/eactive/eai/message/StandardMessageUtil.java b/src/main/java/com/eactive/eai/message/StandardMessageUtil.java index ccb92b6..ea503a3 100644 --- a/src/main/java/com/eactive/eai/message/StandardMessageUtil.java +++ b/src/main/java/com/eactive/eai/message/StandardMessageUtil.java @@ -22,6 +22,7 @@ public class StandardMessageUtil { public static String requestProcessorClass = "com.eactive.eai.inbound.processor.RequestProcessor"; + public static String REST_URL_ACTION0 = "com.eactive.eai.inbound.action.RestAdapterMethodUrlRequestAction"; public static String REST_URL_ACTION1 = "com.eactive.eai.inbound.action.RestUrlAdapterGroupParseRequestAction"; public static String REST_URL_ACTION2 = "com.eactive.eai.inbound.action.RestUrlParseRequestAction"; @@ -49,7 +50,7 @@ public class StandardMessageUtil { if (standardMessage == null) { // API 서비스일경우 PathVariable 지원 추가 // ex) /api/account/{no} - if (StringUtils.equalsAny(vo.getActionName(), REST_URL_ACTION1, REST_URL_ACTION2)) { + if (StringUtils.equalsAny(vo.getActionName(), REST_URL_ACTION0, REST_URL_ACTION1, REST_URL_ACTION2)) { standardMessage = stdMessageManager.getSTDMessageForPathVariable(vo.getSelectedKey()); } @@ -79,7 +80,7 @@ public class StandardMessageUtil { } } - if (StringUtils.equalsAny(actionName, REST_URL_ACTION1, REST_URL_ACTION2)) { + if (StringUtils.equalsAny(actionName, REST_URL_ACTION0, REST_URL_ACTION1, REST_URL_ACTION2)) { return stdMessageManager.getMatchedPathVariable(key); } From c0f69ce4a25155d51db6b25a06e1091047a4167b Mon Sep 17 00:00:00 2001 From: yunjy-hp Date: Tue, 30 Dec 2025 14:32:38 +0900 Subject: [PATCH 069/159] =?UTF-8?q?[=EA=B8=B4=EA=B8=89!]=20retEaiMsg=20nul?= =?UTF-8?q?l=20=EC=98=A4=EB=A5=98=20FIX?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../eai/inbound/processor/RequestProcessor.java | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/eactive/eai/inbound/processor/RequestProcessor.java b/src/main/java/com/eactive/eai/inbound/processor/RequestProcessor.java index cff816c..9fa3073 100644 --- a/src/main/java/com/eactive/eai/inbound/processor/RequestProcessor.java +++ b/src/main/java/com/eactive/eai/inbound/processor/RequestProcessor.java @@ -1274,8 +1274,14 @@ public class RequestProcessor extends RequestProcessorSupport { } //응답 전 표준 전문의 로직 처리 필요 한 경우를 위해 호출 - standardManager.getMessageCoordinator().coordinateBeforeResponse(retEaiMsg.getStandardMessage(), vo, prop, inboundCharset); - + try{ + if(EAIMessageKeys.SYNC_SVC.equals(svcTsmtUsgTp) && retEaiMsg != null){ + standardManager.getMessageCoordinator().coordinateBeforeResponse(retEaiMsg.getStandardMessage(), vo, prop, inboundCharset); + } + }catch(Exception e){ + logger.error("coordinateBeforeResponse failed.", e); + } + // 10. 응답 거래로그 Logging if(EAIMessageKeys.SYNC_SVC.equals(svcTsmtUsgTp) && STDMessageKeys.SEND_RECV_CD_SEND.equals(returnType) ) { From 155ca9df8954a4884d84891d98b57361e27b843c Mon Sep 17 00:00:00 2001 From: "Yunsam.Eo" Date: Thu, 1 Jan 2026 17:20:22 +0900 Subject: [PATCH 070/159] =?UTF-8?q?=EC=98=A4=ED=83=88=EC=9E=90=20=EC=88=98?= =?UTF-8?q?=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../eai/adapter/http/dynamic/HttpDynamicInAdapterUri.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/com/eactive/eai/adapter/http/dynamic/HttpDynamicInAdapterUri.java b/src/main/java/com/eactive/eai/adapter/http/dynamic/HttpDynamicInAdapterUri.java index 91af6ce..2beda78 100644 --- a/src/main/java/com/eactive/eai/adapter/http/dynamic/HttpDynamicInAdapterUri.java +++ b/src/main/java/com/eactive/eai/adapter/http/dynamic/HttpDynamicInAdapterUri.java @@ -28,7 +28,7 @@ public class HttpDynamicInAdapterUri { return isEqualsAdpt(other.getAdptGrpName(), other.getAdptName()); } - public boolean isEqualsAdpt(String adptGrpName, String adptNamer) { + public boolean isEqualsAdpt(String adptGrpName, String adptName) { if ( adptGrpName != null && adptGrpName.equals(this.adptGrpName) && adptName != null && adptName.equals(this.adptName) ) { return true; From c3bf446877f974a082d79305c98636910d3938fc Mon Sep 17 00:00:00 2001 From: "Yunsam.Eo" Date: Fri, 2 Jan 2026 11:33:20 +0900 Subject: [PATCH 071/159] =?UTF-8?q?Path=20Variable=EC=B2=98=EB=A6=AC,=20AP?= =?UTF-8?q?I=EC=8B=9D=EB=B3=84=EB=B0=A9=EC=8B=9D=20=EB=B3=80=EA=B2=BD(DAO-?= =?UTF-8?q?>STDMessageManager)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../impl/HttpClient5AdapterServiceRest.java | 11 ++- .../eai/common/stdmessage/STDMessageDAO.java | 63 ++++++++++++++++ .../common/stdmessage/STDMessageManager.java | 73 +++++++++++++++++++ .../common/stdmessage/STDMsgInfoAddOnVO.java | 40 ++++++++++ 4 files changed, 184 insertions(+), 3 deletions(-) create mode 100644 src/main/java/com/eactive/eai/common/stdmessage/STDMsgInfoAddOnVO.java diff --git a/src/main/java/com/eactive/eai/adapter/http/client/impl/HttpClient5AdapterServiceRest.java b/src/main/java/com/eactive/eai/adapter/http/client/impl/HttpClient5AdapterServiceRest.java index 9d8a195..4ee9b4c 100644 --- a/src/main/java/com/eactive/eai/adapter/http/client/impl/HttpClient5AdapterServiceRest.java +++ b/src/main/java/com/eactive/eai/adapter/http/client/impl/HttpClient5AdapterServiceRest.java @@ -235,12 +235,14 @@ public class HttpClient5AdapterServiceRest extends HttpClient5AdapterServiceSupp logger.debug("HttpClientAdapterServiceRest] dataObject1 = [" + dataObject + "]"); + // Path Variable 처리를 위해 Inbound에서 전달한 Variable Map + Map inboundPathVariables = (Map) tempProp.get(HttpAdapterServiceKey.INBOUND_PATH_VARIABLES); // interface 에 설정된게 우선한다. String uri = null; if (dataObject == null) { - uri = changeUrl(messageType, vo.getUrl(), restOptionData, sendData); + uri = changeUrl(messageType, vo.getUrl(), restOptionData, sendData, inboundPathVariables); } else { - uri = changeUrl(messageType, vo.getUrl(), restOptionData, dataObject); + uri = changeUrl(messageType, vo.getUrl(), restOptionData, dataObject, inboundPathVariables); } logger.debug("HttpClientAdapterServiceRest] dataObject2 = [" + dataObject + "]"); @@ -1468,7 +1470,7 @@ public class HttpClient5AdapterServiceRest extends HttpClient5AdapterServiceSupp } @SuppressWarnings("deprecation") - private String changeUrl(String messageType, String url, String restOption, Object sendData) { + private String changeUrl(String messageType, String url, String restOption, Object sendData, Map inboundPathVariables) { if ((MessageType.JSON.equals(messageType) || MessageType.XML.equals(messageType))) { try { if (StringUtils.isBlank(restOption)) { @@ -1501,6 +1503,9 @@ public class HttpClient5AdapterServiceRest extends HttpClient5AdapterServiceSupp for (Object tempObject : uriVariables) { String urlVaribleId = (String) tempObject; String uriVariable = (String) jsonObject.get(urlVaribleId); + if (StringUtils.isBlank(uriVariable) && inboundPathVariables.containsKey(urlVaribleId)) { + uriVariable = inboundPathVariables.get(urlVaribleId); + } urlVariableList.add(uriVariable); jsonObject.remove(urlVaribleId); } diff --git a/src/main/java/com/eactive/eai/common/stdmessage/STDMessageDAO.java b/src/main/java/com/eactive/eai/common/stdmessage/STDMessageDAO.java index 447fe75..307845c 100644 --- a/src/main/java/com/eactive/eai/common/stdmessage/STDMessageDAO.java +++ b/src/main/java/com/eactive/eai/common/stdmessage/STDMessageDAO.java @@ -12,9 +12,13 @@ import org.springframework.transaction.annotation.Transactional; import com.eactive.eai.common.dao.BaseDAO; import com.eactive.eai.common.dao.DAOException; import com.eactive.eai.common.exception.ExceptionUtil; +import com.eactive.eai.common.message.EAIMessage; +import com.eactive.eai.common.message.EAIMessageDAO; +import com.eactive.eai.common.message.EAIMessageManager; import com.eactive.eai.common.stdmessage.loader.StandardMessageInfoLoader; import com.eactive.eai.common.stdmessage.loader.StandardMessageRestoreService; import com.eactive.eai.common.util.Logger; +import com.eactive.eai.data.entity.onl.message.EAIMessageEntity; import com.eactive.eai.data.entity.onl.stdmessage.StandardMessageInfo; import com.eactive.eai.data.entity.onl.stdmessage.StandardMessageItem; import com.eactive.eai.data.entity.onl.stdmessage.StandardMessageRestore; @@ -231,5 +235,64 @@ public class STDMessageDAO extends BaseDAO { return optional.orElseThrow(() -> new DAOException("해당 full path의 TSEAIHS04 에 데이터가 없습니다.")); } + // Path Variable 처리를 위한 Method/FullURL 베이스 처리. + public HashMap getAllStdMsgInfos() throws DAOException { + HashMap apiInfo = new HashMap<>(); + + EAIMessageManager eaiManager = EAIMessageManager.getInstance(); + EAIMessage eaiMsg = null; + STDMsgInfoAddOnVO vo = null; + try { + List list = standardMessageInfoLoader.findAll(); + for (StandardMessageInfo info : list) { + eaiMsg = eaiManager.getEAIMessage(info.getEaisvcname()); + vo = new STDMsgInfoAddOnVO(); + vo.setBzwksvckeyname(info.getBzwksvckeyname()); + vo.setEaiSvcCd(info.getEaisvcname()); + vo.setApiFullPath(info.getApifullpath()); + vo.setAdapterGroupName(eaiMsg.getSngSysItfTp()); + apiInfo.put(vo.getApiFullPath(), vo); + } + return apiInfo; + } catch (Exception e) { + throw new DAOException(ExceptionUtil.getErrorCode(e, "RECEAICKE102"), e); + } + } + public STDMsgInfoAddOnVO getUrlStdMsgInfo(String apiFullPath) throws DAOException { + EAIMessageManager eaiManager = EAIMessageManager.getInstance(); + EAIMessage eaiMsg = null; + STDMsgInfoAddOnVO vo = null; + try { + Optional optional = standardMessageInfoLoader.findByApiFullPath(apiFullPath); + if (optional.isPresent()) { + StandardMessageInfo info = optional.get(); + eaiMsg = eaiManager.getEAIMessage(info.getEaisvcname()); + vo.setBzwksvckeyname(info.getBzwksvckeyname()); + vo.setEaiSvcCd(info.getEaisvcname()); + vo.setApiFullPath(info.getApifullpath()); + vo.setAdapterGroupName(eaiMsg.getSngSysItfTp()); + } + return vo; + } catch (Exception e) { + throw new DAOException("RECEAICKE110"); + } + } + + public String getApiFullPath(String serviceKey) throws DAOException { + try { + Optional optional = standardMessageInfoLoader.findById(serviceKey); + if (optional.isPresent()) { + StandardMessageInfo info = optional.get(); + return info.getApifullpath(); + } else { + throw new DAOException("RECEAICKE110"); + } + } catch (DAOException e) { + throw e; + } catch(Exception e) { + throw new DAOException(ExceptionUtil.getErrorCode(e, "RECEAICKE111")); + } + } + } diff --git a/src/main/java/com/eactive/eai/common/stdmessage/STDMessageManager.java b/src/main/java/com/eactive/eai/common/stdmessage/STDMessageManager.java index 08d440d..ed14e24 100644 --- a/src/main/java/com/eactive/eai/common/stdmessage/STDMessageManager.java +++ b/src/main/java/com/eactive/eai/common/stdmessage/STDMessageManager.java @@ -30,6 +30,8 @@ public class STDMessageManager implements Lifecycle { private HashMap headers = new HashMap<>(); private HashMap headersForPathVariables = new HashMap<>(); + private HashMap headerUrls = new HashMap<>(); + private HashMap headerUrlsForPathVariables = new HashMap<>(); private boolean started; private LifecycleSupport lifecycle = new LifecycleSupport(this); @@ -60,6 +62,14 @@ public class STDMessageManager implements Lifecycle { headersForPathVariables.put(entry.getKey(), entry.getValue()); } } + // url base로 처리 추가. + headerUrls = sTDMessageDAO.getAllStdMsgInfos(); + headerUrlsForPathVariables.clear(); + for (Map.Entry entry : headerUrls.entrySet()) { + if (isPathVariable(entry.getKey())) { + headerUrlsForPathVariables.put(entry.getKey(), entry.getValue()); + } + } } public static boolean isPathVariable(String key) { @@ -86,6 +96,17 @@ public class STDMessageManager implements Lifecycle { } else { throw new Exception("STDMessage not found in Database : key[" + keyName + "]"); } + // url base로 처리 추가. + String apiFullPath = sTDMessageDAO.getApiFullPath(keyName); + STDMsgInfoAddOnVO msgUrl = sTDMessageDAO.getUrlStdMsgInfo(apiFullPath); + if (msgUrl != null) { + headerUrls.put(apiFullPath, msgUrl); + if (isPathVariable(apiFullPath)) { + headerUrlsForPathVariables.put(apiFullPath, msgUrl); + } + } else { + throw new Exception("STDMessage not found in Database : key[" + apiFullPath + "]"); + } } public void stop() throws LifecycleException { @@ -145,6 +166,41 @@ public class STDMessageManager implements Lifecycle { return null; } + // apiFullPath 기준 Path Variable 조회 + public StandardMessage getSTDMessageForUrlPathVariable(String apiFullPath) { + String matchedKey = getMatchedUrlPathVariable(apiFullPath); + if (matchedKey != null) { + return getSTDMessage(matchedKey); + } else { + return null; + } + } + + public String getMatchedUrlPathVariable(String apiFullPath) { + AntPathMatcher matcher = new AntPathMatcher(); + for (String key : headerUrlsForPathVariables.keySet()) { + if (matcher.match(key, apiFullPath)) { + return key; + } + } + return null; + } + + public STDMsgInfoAddOnVO getStdMsgInfoAddOn(String apiFullPath) { + for (Map.Entry entry : headerUrls.entrySet()) { + if (StringUtils.equals(entry.getKey(), apiFullPath) ) { + return entry.getValue(); + } + } + String apiPathVariable = getMatchedUrlPathVariable(apiFullPath); + for (Map.Entry entry : headerUrlsForPathVariables.entrySet()) { + if (StringUtils.equals(entry.getKey(), apiPathVariable) ) { + return entry.getValue(); + } + } + return null; + } + public String[] getAllSTDMessageKeys() { String[] ks = new String[this.headers.size()]; Iterator it = this.headers.keySet().iterator(); @@ -163,6 +219,19 @@ public class STDMessageManager implements Lifecycle { } return al; } + + // 업무서비스키로 기 동록된 apiFullPath 가져오기. + public String getApiFullPath(String serviceKey) { + String apiFullPath = ""; + for (Map.Entry entry : headerUrls.entrySet()) { + STDMsgInfoAddOnVO msgVO = entry.getValue(); + if (StringUtils.equals(serviceKey, msgVO.getBzwksvckeyname())) { + apiFullPath = msgVO.getApiFullPath(); + return apiFullPath; + } + } + return null; + } public void addSTDMessage(StandardMessage msg) { this.headers.put(msg.getServiceKey(), msg); @@ -175,5 +244,9 @@ public class STDMessageManager implements Lifecycle { public synchronized void removeSTDMessage(String bwkSvcKey) { this.headers.remove(bwkSvcKey); this.headersForPathVariables.remove(bwkSvcKey); + // apiFullPath 기준 등록정보 삭제. + String apiFullPath = getApiFullPath(bwkSvcKey); + this.headerUrls.remove(apiFullPath); + this.headerUrlsForPathVariables.remove(apiFullPath); } } diff --git a/src/main/java/com/eactive/eai/common/stdmessage/STDMsgInfoAddOnVO.java b/src/main/java/com/eactive/eai/common/stdmessage/STDMsgInfoAddOnVO.java new file mode 100644 index 0000000..cf9aa5a --- /dev/null +++ b/src/main/java/com/eactive/eai/common/stdmessage/STDMsgInfoAddOnVO.java @@ -0,0 +1,40 @@ +package com.eactive.eai.common.stdmessage; + +import org.json.simple.JSONObject; + +public class STDMsgInfoAddOnVO { + + private String bzwksvckeyname = null;// 업무서비스키 + private String eaiSvcCd = null;// EAI서비스코드 + private String apiFullPath = null;// Method/Url + private String adapterGroupName = null;// 인바운드 어댑터그룹 + + public String getBzwksvckeyname() { + return bzwksvckeyname; + } + public void setBzwksvckeyname(String bzwksvckeyname) { + this.bzwksvckeyname = bzwksvckeyname; + } + + public String getEaiSvcCd() { + return eaiSvcCd; + } + public void setEaiSvcCd(String eaiSvcCd) { + this.eaiSvcCd = eaiSvcCd; + } + + public String getApiFullPath() { + return apiFullPath; + } + public void setApiFullPath(String apiFullPath) { + this.apiFullPath = apiFullPath; + } + + public String gAdapterGroupName() { + return adapterGroupName; + } + public void setAdapterGroupName(String adapterGroupName) { + this.adapterGroupName = adapterGroupName; + } + +} From c2e62ad3ec61416831a8a4cabc87f75a888a5596 Mon Sep 17 00:00:00 2001 From: cho Date: Mon, 5 Jan 2026 18:53:53 +0900 Subject: [PATCH 072/159] =?UTF-8?q?http=20=EB=A0=88=EA=B1=B0=EC=8B=9C=20?= =?UTF-8?q?=ED=83=80=EC=9E=85=20Inbound=20=EB=A9=94=EC=84=B8=EC=A7=80=20?= =?UTF-8?q?=ED=83=80=EC=9E=85=20JSON=EC=9D=BC=EB=95=8C,?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit json 에러 메세지 나가도록 수정. --- .../impl/HttpAdapterServiceStandard.java | 52 ++++++++++++++----- 1 file changed, 40 insertions(+), 12 deletions(-) diff --git a/src/main/java/com/eactive/eai/adapter/http/dynamic/impl/HttpAdapterServiceStandard.java b/src/main/java/com/eactive/eai/adapter/http/dynamic/impl/HttpAdapterServiceStandard.java index d3e1287..78b3ba5 100644 --- a/src/main/java/com/eactive/eai/adapter/http/dynamic/impl/HttpAdapterServiceStandard.java +++ b/src/main/java/com/eactive/eai/adapter/http/dynamic/impl/HttpAdapterServiceStandard.java @@ -1,5 +1,6 @@ package com.eactive.eai.adapter.http.dynamic.impl; +import com.eactive.eai.adapter.AdapterGroupVO; import com.eactive.eai.adapter.AdapterManager; import com.eactive.eai.adapter.AdapterPropManager; import com.eactive.eai.adapter.AdapterVO; @@ -53,10 +54,13 @@ public class HttpAdapterServiceStandard extends HttpAdapterServiceSupport **/ public void service(String adptGrpName, String adptName, HttpServletRequest request, HttpServletResponse response) { int traceLevel = 0; + + AdapterGroupVO adapterGroupVo = null; + try { AdapterManager adapterManager = AdapterManager.getInstance(); AdapterVO adptVO = adapterManager.getAdapterVO(adptGrpName,adptName); - + adapterGroupVo = adptVO.getAdapterGroupVO(); AdapterPropManager manager = AdapterPropManager.getInstance(); if(adptVO == null) { @@ -257,25 +261,49 @@ public class HttpAdapterServiceStandard extends HttpAdapterServiceSupport } logger.warn("HttpAdapter] " + adptGrpName + "-" + adptName + ">>" + e.getMessage()); response.setStatus(e.getStatus()); - try { - String errorMsg = String.format("(%d) %s", e.getStatus(), e.getMessage()); - response.getWriter().println(errorMsg); - } catch (Exception ex) { - // IGNORE + + if( "JSN".equals( adapterGroupVo.getMessageType() ) ) { + try { + String errorMsg = MessageUtil.makeJsonErrorMessage( MessageUtil.ERROR_CODE_AP_ERROR, e.getMessage()); + response.getWriter().println(errorMsg); + } catch (Exception ex) { + // IGNORE + } + }else { + try { + String errorMsg = String.format("(%d) %s", e.getStatus(), e.getMessage()); + response.getWriter().println(errorMsg); + } catch (Exception ex) { + // IGNORE + } } + } catch (Exception e) { if (traceLevel >= 3){ HttpMemoryLogger.error(adptGrpName+adptName, e.toString(),e); } logger.error("HttpAdapter] "+adptGrpName+"-"+adptName, e); response.setStatus(500); - try { - response.getWriter().println(e.getMessage()); - String errCode = ExceptionUtil.getErrorCode(e, "RECEAIAHA003"); - throw new Exception(errCode); - } catch (Exception ex) { - logger.warn("error", ex); + + if( "JSN".equals( adapterGroupVo.getMessageType() ) ) { + try { + String errorMsg = MessageUtil.makeJsonErrorMessage( MessageUtil.ERROR_CODE_AP_ERROR, e.getMessage()); + response.getWriter().println(errorMsg); + throw new Exception(MessageUtil.ERROR_CODE_AP_ERROR); + } catch (Exception ex) { + logger.warn("error", ex); + } + }else { + try { + response.getWriter().println(e.getMessage()); + String errCode = ExceptionUtil.getErrorCode(e, "RECEAIAHA003"); + throw new Exception(errCode); + } catch (Exception ex) { + logger.warn("error", ex); + } } + + } } From e32fec635c2217e77e89e02a3d0e2447e0923f93 Mon Sep 17 00:00:00 2001 From: cho Date: Tue, 6 Jan 2026 10:53:50 +0900 Subject: [PATCH 073/159] =?UTF-8?q?async=EC=9D=BC=EC=8B=9C,=20guid=20?= =?UTF-8?q?=EB=A6=AC=ED=84=B4=ED=95=98=EB=8D=98=EA=B2=83=20=EC=9B=90?= =?UTF-8?q?=EB=B3=B5,=20null=20=EA=B0=92=EC=9C=BC=EB=A1=9C.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../eai/inbound/processor/RequestProcessor.java | 11 +---------- 1 file changed, 1 insertion(+), 10 deletions(-) diff --git a/src/main/java/com/eactive/eai/inbound/processor/RequestProcessor.java b/src/main/java/com/eactive/eai/inbound/processor/RequestProcessor.java index 9fa3073..66872e1 100644 --- a/src/main/java/com/eactive/eai/inbound/processor/RequestProcessor.java +++ b/src/main/java/com/eactive/eai/inbound/processor/RequestProcessor.java @@ -1360,16 +1360,7 @@ public class RequestProcessor extends RequestProcessorSupport { } } else { - // 비동기 거래, S-A의 응답거래시에는 NULL을 리턴 - //return null; // 원래 null return 인데 광주은행은 GUID를 Return 해 달라고 해서 수정함 jwhong - //map.put("guid", guid); - - Map map = new HashMap<>(); - map.put("uuid", vo.getUuid()); - JSONObject json = new JSONObject(map); - //return json.toJSONString(); - - return vo.getUuid(); + return null; } } From 8d21eba5e8dc25d11ad315aa4559566cd3623bba Mon Sep 17 00:00:00 2001 From: cho Date: Tue, 6 Jan 2026 13:32:45 +0900 Subject: [PATCH 074/159] =?UTF-8?q?=EB=B9=84=EB=8F=99=EA=B8=B0=20=EC=9D=BC?= =?UTF-8?q?=EB=95=8C=20=EB=8D=94=EB=AF=B8=EC=9D=91=EB=8B=B5=20=EC=B2=98?= =?UTF-8?q?=EB=A6=AC=20=EC=88=98=EC=A0=95.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../impl/HttpAdapterServiceStandard.java | 5 +- .../java/com/eactive/eai/env/ElinkConfig.java | 46 +++++++++++++++++++ 2 files changed, 50 insertions(+), 1 deletion(-) diff --git a/src/main/java/com/eactive/eai/adapter/http/dynamic/impl/HttpAdapterServiceStandard.java b/src/main/java/com/eactive/eai/adapter/http/dynamic/impl/HttpAdapterServiceStandard.java index 78b3ba5..002999f 100644 --- a/src/main/java/com/eactive/eai/adapter/http/dynamic/impl/HttpAdapterServiceStandard.java +++ b/src/main/java/com/eactive/eai/adapter/http/dynamic/impl/HttpAdapterServiceStandard.java @@ -198,12 +198,15 @@ public class HttpAdapterServiceStandard extends HttpAdapterServiceSupport } } - if (result == null) { + if ( result == null) { responseData = ElinkConfig.getAsyncDummyDataForAdapterGroup(adptGrpName); } else if (result instanceof byte[]) { responseData = new String((byte[]) result, encode); } else if (result instanceof String) { responseData = (String) result; + if ( StringUtils.isBlank( responseData ) ) { + responseData = ElinkConfig.getAsyncDummyDataForAdapterGroup(adptGrpName, adptName); + } } response.setCharacterEncoding(encode); diff --git a/src/main/java/com/eactive/eai/env/ElinkConfig.java b/src/main/java/com/eactive/eai/env/ElinkConfig.java index b3024f4..9346065 100644 --- a/src/main/java/com/eactive/eai/env/ElinkConfig.java +++ b/src/main/java/com/eactive/eai/env/ElinkConfig.java @@ -1,11 +1,14 @@ package com.eactive.eai.env; import java.util.Enumeration; +import java.util.HashMap; +import java.util.Map; import java.util.Properties; import java.util.concurrent.ConcurrentHashMap; import javax.annotation.PostConstruct; +import org.json.simple.JSONObject; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.PropertySource; import org.springframework.core.env.Environment; @@ -13,6 +16,8 @@ import org.springframework.stereotype.Component; import com.eactive.eai.adapter.AdapterGroupVO; import com.eactive.eai.adapter.AdapterManager; +import com.eactive.eai.adapter.AdapterPropManager; +import com.eactive.eai.adapter.AdapterVO; import com.eactive.eai.common.dao.DAOException; import com.eactive.eai.common.util.ContainerUtil; @@ -297,6 +302,47 @@ public class ElinkConfig implements ConfigKeys { } return getAsyncDummyData(adptrMsgPtrnCd); } + + public static String getAsyncDummyDataForAdapterGroup(String adapterGroupName, String adapterName) { + + Properties httpProp = null; + try { + + + AdapterVO adapterVO = AdapterManager.getInstance().getAdapterVO(adapterGroupName, adapterName); + + httpProp = AdapterPropManager.getInstance().getProperties(adapterVO.getPropGroupName()); + } catch (Exception e) { + return makeResponseBodyMsg(); + } + + String asyncMsgStyle = httpProp.getProperty("ASYNC_RTNMSG_TYPE", "").toUpperCase(); + String responseBody =""; + if (asyncMsgStyle == null || asyncMsgStyle.trim().isEmpty()) { + responseBody = makeResponseBodyMsg(); + } else { + responseBody = asyncMsgStyle; + } + + return responseBody; + } + + static private String makeResponseBodyMsg() { + + Map dataMap = new HashMap<>(); + dataMap.put("result", 1); + Map map = new HashMap<>(); + + map.put("code", "200"); + map.put("data", dataMap); + map.put("message", "정상 처리 되었습니다."); + + JSONObject json = new JSONObject(); + json.putAll(map); + + return json.toJSONString(); + } + public static String getHttpClientUrlReplaceName() { return httpClientUrlReplaceName; } From 7397a3266aca5dd5f910e3027e8e6e9951a31cf8 Mon Sep 17 00:00:00 2001 From: jaewohong Date: Tue, 6 Jan 2026 19:00:00 +0900 Subject: [PATCH 075/159] =?UTF-8?q?dummy=20adapter=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../impl/HttpClientAdapterServiceNoop.java | 21 +++++++++++++++++++ 1 file changed, 21 insertions(+) create mode 100644 src/main/java/com/eactive/eai/adapter/http/client/impl/HttpClientAdapterServiceNoop.java diff --git a/src/main/java/com/eactive/eai/adapter/http/client/impl/HttpClientAdapterServiceNoop.java b/src/main/java/com/eactive/eai/adapter/http/client/impl/HttpClientAdapterServiceNoop.java new file mode 100644 index 0000000..73ac941 --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/http/client/impl/HttpClientAdapterServiceNoop.java @@ -0,0 +1,21 @@ +package com.eactive.eai.adapter.http.client.impl; + +import com.eactive.eai.adapter.http.client.HttpClientAdapterService; +import com.eactive.eai.httpouttlsinfo.HttpOutTlsInfoVO; + +import java.util.Properties; + +public class HttpClientAdapterServiceNoop implements HttpClientAdapterService { + public Object execute(Properties prop, Object data, Properties tempProp) throws Exception { + return null; + } + + @Override + public void close() { + } + + @Override + public void init(String adapterName, boolean useMtls, HttpOutTlsInfoVO mtlsInfo, int maxTotalConnections, int maxHostConnections) { + } +} + From e2d3ad593dc9afd14a3325c2be90566c5ac25112 Mon Sep 17 00:00:00 2001 From: yunjy-hp Date: Wed, 7 Jan 2026 16:44:32 +0900 Subject: [PATCH 076/159] =?UTF-8?q?ElinkTransactionContext=20=EC=9E=91?= =?UTF-8?q?=EC=97=85(=EB=B3=80=ED=99=98=20=ED=95=A8=EC=88=98=EC=97=90=20?= =?UTF-8?q?=EA=B0=92=20=EC=A0=84=EB=8B=AC=20=EC=B2=B4=EA=B3=84=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../eai/common/message/EAIMessage.java | 41 +++++++++++++++++++ .../common/routing/ElinkESBProcessProxy.java | 40 +++++++++++++----- .../eai/common/routing/FlowRouter.java | 5 +++ 3 files changed, 76 insertions(+), 10 deletions(-) diff --git a/src/main/java/com/eactive/eai/common/message/EAIMessage.java b/src/main/java/com/eactive/eai/common/message/EAIMessage.java index 255e974..4a68991 100644 --- a/src/main/java/com/eactive/eai/common/message/EAIMessage.java +++ b/src/main/java/com/eactive/eai/common/message/EAIMessage.java @@ -3,7 +3,9 @@ package com.eactive.eai.common.message; import java.io.Serializable; import java.nio.charset.Charset; import java.util.ArrayList; +import java.util.HashMap; import java.util.List; +import java.util.Map; import com.eactive.eai.message.StandardMessage; import com.eactive.eai.message.manager.StandardMessageManager; @@ -107,6 +109,7 @@ public class EAIMessage implements EAIMessageKeys, Serializable, Comparable(); this.svcPssSeq = 1; @@ -624,6 +627,42 @@ public class EAIMessage implements EAIMessageKeys, Serializable, Comparable transactionContextTransfer; + + /** + * [비동기 전달 전용] 컨텍스트 전달용 Map 반환 + * @see #transactionContextTransfer + */ + public Map getTransactionContextTransfer() { + return transactionContextTransfer; + } + + /** + * [비동기 전달 전용] 컨텍스트 전달용 Map 설정 + * @see #transactionContextTransfer + */ + public void setTransactionContextTransfer(Map transactionContextTransfer) { + this.transactionContextTransfer = transactionContextTransfer; + } + @Override public Object clone() throws CloneNotSupportedException { EAIMessage cloned = (EAIMessage) super.clone(); @@ -636,6 +675,8 @@ public class EAIMessage implements EAIMessageKeys, Serializable, Comparable(transactionContextTransfer)); return cloned; } diff --git a/src/main/java/com/eactive/eai/common/routing/ElinkESBProcessProxy.java b/src/main/java/com/eactive/eai/common/routing/ElinkESBProcessProxy.java index 72e8e32..cf183ed 100644 --- a/src/main/java/com/eactive/eai/common/routing/ElinkESBProcessProxy.java +++ b/src/main/java/com/eactive/eai/common/routing/ElinkESBProcessProxy.java @@ -1,11 +1,13 @@ package com.eactive.eai.common.routing; -import com.eactive.eai.common.message.EAIMessage; -import com.eactive.eai.common.util.Logger; - import java.util.Properties; import java.util.concurrent.ConcurrentHashMap; +import com.eactive.eai.common.context.ElinkTransactionContext; +import com.eactive.eai.common.message.EAIMessage; +import com.eactive.eai.common.message.EAIMessageKeys; +import com.eactive.eai.common.util.Logger; + /** * 1. 기능 : ElinkESBProcess를 호출하는 공통 Class @@ -42,17 +44,30 @@ public class ElinkESBProcessProxy public static EAIMessage callElinkESBProcess(String serviceURI, EAIMessage eaiMessage, boolean isLocal, Properties prop) throws Exception { EAIMessage retMsg = null; + + // [ElinkTransactionContext] 비동기 거래 시 컨텍스트 초기화 여부 판단 + // - ASYNC 거래이고, outbound Process 호출이 아닌 경우에만 초기화 + boolean shouldManageContext = eaiMessage != null + && EAIMessageKeys.ASYNC_SVC.equals(eaiMessage.getSvcTsmtUsgTp()) + && (serviceURI == null || !serviceURI.startsWith("com.eactive.eai.outbound")); + try { - if (isLocal){ + // [ElinkTransactionContext] 비동기 거래 진입점 - 컨텍스트 복원 + if (shouldManageContext) { + ElinkTransactionContext.restore(eaiMessage.getTransactionContextTransfer()); + eaiMessage.setTransactionContextTransfer(null); // 복원 후 전달용 필드 초기화 + } + + if (isLocal){ Class cl = classLocalCache.get(serviceURI); - + if(cl == null) { cl = Class.forName(serviceURI); classLocalCache.put(serviceURI, cl); } Process proc = (Process)cl.newInstance(); proc.callService(eaiMessage, prop); - + retMsg = proc.clientReturn(); }else{ if(eaiMessage == null) { @@ -62,12 +77,17 @@ public class ElinkESBProcessProxy retMsg = RemoteProxyClient.callProxyBean(eaiMessage, prop); } } - } catch( ClassNotFoundException e) { + } catch( ClassNotFoundException e) { if (logger.isError()) logger.error("ElinkProcessProxy] callElinkESBProcess["+serviceURI+"] Class Not Found Exception : "); - throw new Exception(PROXY_ERROR_CODE); - } catch( Exception e) { + throw new Exception(PROXY_ERROR_CODE); + } catch( Exception e) { if (logger.isError()) logger.error("ElinkProcessProxy] callElinkESBProcess["+serviceURI+"] Exception : "+e.getMessage(),e); - throw new Exception(PROXY_ERROR_CODE); + throw new Exception(PROXY_ERROR_CODE); + } finally { + // [ElinkTransactionContext] 비동기 거래 - 해제 + if (shouldManageContext) { + ElinkTransactionContext.clear(); + } } return retMsg; } diff --git a/src/main/java/com/eactive/eai/common/routing/FlowRouter.java b/src/main/java/com/eactive/eai/common/routing/FlowRouter.java index 466c797..8c9158f 100644 --- a/src/main/java/com/eactive/eai/common/routing/FlowRouter.java +++ b/src/main/java/com/eactive/eai/common/routing/FlowRouter.java @@ -2,6 +2,7 @@ package com.eactive.eai.common.routing; import java.util.Properties; +import com.eactive.eai.common.context.ElinkTransactionContext; import com.eactive.eai.common.exception.ExceptionUtil; import com.eactive.eai.common.message.EAIMessage; import com.eactive.eai.common.property.PropManager; @@ -136,6 +137,8 @@ public class FlowRouter } try { + // [ElinkTransactionContext] 비동기 송신 전 컨텍스트 복사 + eaiMessage.setTransactionContextTransfer(ElinkTransactionContext.getAll()); JMSSender.sendToQueue(eaiMessage, queueConFactory, routeQueueName, prop); } catch(Exception e) { if (logger.isError()) logger.error(guidLogPrefix +" process.Queue Error. Queue Name[" + routeQueueName + "]- " + e.getMessage(), e); @@ -164,6 +167,8 @@ public class FlowRouter } try { + // [ElinkTransactionContext] 비동기 송신 전 컨텍스트 복사 + eaiMessage.setTransactionContextTransfer(ElinkTransactionContext.getAll()); if (ElinkConfig.isUseCacheTopic()) { SessionManager.getInstance().putTopic(traceKey, eaiMessage); } From 1965391ac74c49d10074436c47b3d57a77e2dea4 Mon Sep 17 00:00:00 2001 From: yunjy-hp Date: Wed, 7 Jan 2026 17:42:37 +0900 Subject: [PATCH 077/159] =?UTF-8?q?DefaultUserAgent,=20ContentCompression?= =?UTF-8?q?=20=EB=81=94?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../adapter/http/client/HttpClient5AdapterServiceSupport.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/main/java/com/eactive/eai/adapter/http/client/HttpClient5AdapterServiceSupport.java b/src/main/java/com/eactive/eai/adapter/http/client/HttpClient5AdapterServiceSupport.java index 80655b5..ab1dc80 100644 --- a/src/main/java/com/eactive/eai/adapter/http/client/HttpClient5AdapterServiceSupport.java +++ b/src/main/java/com/eactive/eai/adapter/http/client/HttpClient5AdapterServiceSupport.java @@ -418,6 +418,8 @@ public abstract class HttpClient5AdapterServiceSupport implements HttpClientAdap }; this.client = HttpClients.custom() + .disableDefaultUserAgent() + .disableContentCompression() .addRequestInterceptorLast(requestLogInterceptor) .addResponseInterceptorFirst(responseLogInterceptor) .setConnectionManager(connectionManager) From 87fccf4c2b1a4932b662a72c71a804a8c5ca3759 Mon Sep 17 00:00:00 2001 From: jaewohong Date: Thu, 8 Jan 2026 10:43:02 +0900 Subject: [PATCH 078/159] =?UTF-8?q?accept-encoding=20=EC=A0=9C=ED=9A=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../client/impl/HttpClientAccessTokenServiceWithParam.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/main/java/com/eactive/eai/authoutbound/client/impl/HttpClientAccessTokenServiceWithParam.java b/src/main/java/com/eactive/eai/authoutbound/client/impl/HttpClientAccessTokenServiceWithParam.java index 45e7c60..c2a6dd1 100644 --- a/src/main/java/com/eactive/eai/authoutbound/client/impl/HttpClientAccessTokenServiceWithParam.java +++ b/src/main/java/com/eactive/eai/authoutbound/client/impl/HttpClientAccessTokenServiceWithParam.java @@ -193,7 +193,8 @@ public class HttpClientAccessTokenServiceWithParam implements HttpClientAccessTo connectionManager.setMaxTotal(maxTotalConnections); connectionManager.setDefaultMaxPerRoute(maxHostConnections); - try (CloseableHttpClient httpClient = HttpClients.custom().setConnectionManager(connectionManager).build();) { + // http header에 zip 제외하려면 disableContentCompression() 추가해서 제외할것 + try (CloseableHttpClient httpClient = HttpClients.custom().setConnectionManager(connectionManager).disableContentCompression().disableDefaultUserAgent().build();) { HttpPost httpPost = new HttpPost(uri); httpPost.setEntity(new UrlEncodedFormEntity(formParams, charset)); httpPost.setHeader("Content-Type", "application/x-www-form-urlencoded; charset=" + encode); From 48eee97caaa1a0a12d653e2cb7d9f4968d879d45 Mon Sep 17 00:00:00 2001 From: cho Date: Thu, 8 Jan 2026 11:06:35 +0900 Subject: [PATCH 079/159] =?UTF-8?q?CA=20Gateway=20=ED=86=A0=ED=81=B0=20?= =?UTF-8?q?=EC=B2=98=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 1. 기존메모리에서 따로 관리하던것을 인터스끼리 공유 할수있도록 sessionManager에서 토큰을 관리.(CAToken 관리용 cache 추가 작업) 2. ApiAuthFilter.java 에 ca 방식 토큰 인증 로직 추가. 나머지는 CA토큰 발급(BearerTokenController)처리 및 BeareTokenInfo 는 어윤삼 부장 작업본 그대로 사용. --- .../http/dynamic/filter/ApiAuthFilter.java | 21 +++++- .../authserver/service/BearerTokenInfo.java | 49 +++++++++++++ .../service/BearerTokenService.java | 73 +++++++++++++++++++ .../eai/common/session/SessionManager.java | 10 +++ .../session/SessionManagerForEhcache.java | 16 ++++ .../session/SessionManagerForIgnite.java | 36 ++++++++- 6 files changed, 202 insertions(+), 3 deletions(-) create mode 100644 src/main/java/com/eactive/eai/authserver/service/BearerTokenInfo.java create mode 100644 src/main/java/com/eactive/eai/authserver/service/BearerTokenService.java diff --git a/src/main/java/com/eactive/eai/adapter/http/dynamic/filter/ApiAuthFilter.java b/src/main/java/com/eactive/eai/adapter/http/dynamic/filter/ApiAuthFilter.java index 2babcee..590da9b 100644 --- a/src/main/java/com/eactive/eai/adapter/http/dynamic/filter/ApiAuthFilter.java +++ b/src/main/java/com/eactive/eai/adapter/http/dynamic/filter/ApiAuthFilter.java @@ -1,6 +1,7 @@ package com.eactive.eai.adapter.http.dynamic.filter; import com.eactive.eai.adapter.http.dynamic.HttpAdapterServiceSupport; +import com.eactive.eai.authserver.service.BearerTokenInfo; //import com.eactive.eai.authserver.vo.BearerTokenInfo; //import com.eactive.eai.authserver.custom.BearerTokenService; import com.eactive.eai.authserver.service.OAuth2Manager; @@ -9,6 +10,7 @@ import com.eactive.eai.common.message.EAIMessage; import com.eactive.eai.common.message.EAIMessageManager; import com.eactive.eai.common.property.PropGroupVO; import com.eactive.eai.common.property.PropManager; +import com.eactive.eai.common.session.SessionManager; import com.eactive.eai.common.stdmessage.STDMessageManager; import com.eactive.eai.common.util.Logger; import com.eactive.eai.common.util.StringUtil; @@ -113,7 +115,7 @@ public class ApiAuthFilter implements HttpAdapterFilter { switch (eaiMessage.getAuthType()){ case "oauth": try { - String token = ApiAuthFilter.extractJWTToken(request); + String token = extractBearerToken(request); SignedJWT signedJWT = SignedJWT.parse(token); if (signedJWT.getJWTClaimsSet().getExpirationTime() == null) { @@ -169,6 +171,21 @@ public class ApiAuthFilter implements HttpAdapterFilter { prop.setProperty(HttpAdapterServiceSupport.PROPERTIES_NAME_CLIENT_ID, apiKey); isPassScope = true; break; + case "ca": + String token = extractBearerToken(request); + BearerTokenInfo bearerTokenInfo = SessionManager.getInstance().getCAToken(token); + if ( bearerTokenInfo != null ) { + if( bearerTokenInfo.isExpired() ) { + SessionManager.getInstance().removeCAToken(token); + throw new JwtAuthException(ERROR_AUTHENTICATION_FAIL, "expried API key \""+token+"\" in Http Authrozation Header"); + } + prop.setProperty(HttpAdapterServiceSupport.PROPERTIES_NAME_CLIENT_ID, bearerTokenInfo.getClientId()); + isPassScope = true; + } + else { + throw new JwtAuthException(ERROR_AUTHENTICATION_FAIL, "Invalid or missing API key \""+token+"\" in Http Authrozation Header"); + } + break; case "none": return message; } @@ -276,7 +293,7 @@ public class ApiAuthFilter implements HttpAdapterFilter { return false; } - public static String extractJWTToken(HttpServletRequest request) throws JwtAuthException { + public static String extractBearerToken(HttpServletRequest request) throws JwtAuthException { String authorization = request.getHeader("Authorization"); if (StringUtils.isBlank(authorization)) { throw new JwtAuthException(ERROR_AUTHENTICATION_FAIL, "No have header info: Authorization"); diff --git a/src/main/java/com/eactive/eai/authserver/service/BearerTokenInfo.java b/src/main/java/com/eactive/eai/authserver/service/BearerTokenInfo.java new file mode 100644 index 0000000..390ad6d --- /dev/null +++ b/src/main/java/com/eactive/eai/authserver/service/BearerTokenInfo.java @@ -0,0 +1,49 @@ +package com.eactive.eai.authserver.service; + +import java.util.Set; + +import com.fasterxml.jackson.annotation.JsonProperty; + +public class BearerTokenInfo { + @JsonProperty("client_id") + private String clientId; + private Long expiresIn; + private Long expiresAt; + private Set scopeSet; + + public String getClientId() { + return clientId; + } + + public void setClientId(String clientId) { + this.clientId = clientId; + } + + public Long getExpiresIn() { + return expiresIn; + } + + public void setExpiresIn(Long expiresIn) { + this.expiresIn = expiresIn; + } + + public Long getExpiresAt() { + return expiresAt; + } + + public void setExpiresAt(Long expiresIn) { + this.expiresAt = System.currentTimeMillis() + (expiresIn * 1000); + } + + public Set getScopeSet() { + return scopeSet; + } + + public void setScopeSet(Set scopeSet) { + this.scopeSet = scopeSet; + } + + public boolean isExpired() { + return System.currentTimeMillis() > expiresAt; + } +} diff --git a/src/main/java/com/eactive/eai/authserver/service/BearerTokenService.java b/src/main/java/com/eactive/eai/authserver/service/BearerTokenService.java new file mode 100644 index 0000000..f4b29d6 --- /dev/null +++ b/src/main/java/com/eactive/eai/authserver/service/BearerTokenService.java @@ -0,0 +1,73 @@ +package com.eactive.eai.authserver.service; + +import java.security.SecureRandom; +import java.util.Map; +import java.util.Set; +import java.util.UUID; +import java.util.concurrent.ConcurrentHashMap; +import java.util.stream.Collectors; +import java.util.stream.IntStream; + +import javax.annotation.PostConstruct; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import com.eactive.eai.common.session.SessionManager; +import com.eactive.eai.common.session.SessionManagerForIgnite; + +@Service +public class BearerTokenService { + + + + + public String generateCAToken(String clientId, Long expiresIn, Set scopeSet) { + + + + String token = UUID.randomUUID().toString(); + + BearerTokenInfo CATokenInfo = new BearerTokenInfo(); + CATokenInfo.setClientId(clientId); + CATokenInfo.setExpiresIn(expiresIn); + CATokenInfo.setExpiresAt(expiresIn); + CATokenInfo.setScopeSet(scopeSet); + + //CATokenStore.put(token, CATokenInfo); + + SessionManager.getInstance().putCAToken(token, CATokenInfo); + + return token; + } + + public boolean validateCA(String token) { + BearerTokenInfo CATokenInfo = SessionManager.getInstance().getCAToken(token); + if (CATokenInfo == null) return false; + + if (CATokenInfo.isExpired()) { + SessionManager.getInstance().removeCAToken(token); + return false; + }else { + return true; + } + } + + public String getClientIdFromCA(String token) { + BearerTokenInfo CATokenInfo = SessionManager.getInstance().getCAToken(token); + return CATokenInfo.getClientId(); + } + +// private static final String CHARACTERS = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"; +// private static final SecureRandom secureRandom = new SecureRandom(); +// +// public static String generateTokenString(int length) { +// // Java 8의 IntStream과 Collectors.joining을 사용한 효율적인 방법 +// return IntStream.range(0, length) +// .map(i -> secureRandom.nextInt(CHARACTERS.length())) +// .mapToObj(CHARACTERS::charAt) +// .map(String::valueOf) +// .collect(Collectors.joining()); +// } +} + diff --git a/src/main/java/com/eactive/eai/common/session/SessionManager.java b/src/main/java/com/eactive/eai/common/session/SessionManager.java index fcf007a..acfa0f1 100644 --- a/src/main/java/com/eactive/eai/common/session/SessionManager.java +++ b/src/main/java/com/eactive/eai/common/session/SessionManager.java @@ -1,5 +1,6 @@ package com.eactive.eai.common.session; +import com.eactive.eai.authserver.service.BearerTokenInfo; import com.eactive.eai.common.lifecycle.Lifecycle; import com.eactive.eai.common.lifecycle.LifecycleException; import com.eactive.eai.common.lifecycle.LifecycleListener; @@ -58,6 +59,7 @@ public abstract class SessionManager implements Lifecycle { public static final String USERID_CAHCE_NAME = "convertUserIdSession"; public static final String WEBSOCKER_CAHCE_NAME = "webSocketTimeout"; public static final String TERMINAL_CAHCE_NAME = "terminalSession"; + public static final String CAGATEWAY_TOKEN_CACHE_NAME = "CAGatewayToken"; public static final String SESSION_MANAGER_GROUPNAME = "RMIInfo"; public static final String SESSION_MANAGER_CACHETYPE = "cacheType"; @@ -193,6 +195,14 @@ public abstract class SessionManager implements Lifecycle { public abstract void putLogin(String key, SessionVO value); public abstract void removeLogin(String key); + + //CA Token Cache + public abstract BearerTokenInfo getCAToken(String key); + + public abstract void putCAToken(String key, BearerTokenInfo value); + + public abstract void removeCAToken(String key); + // HTTP Cache public abstract SessionVO getHttpLogin(String key); diff --git a/src/main/java/com/eactive/eai/common/session/SessionManagerForEhcache.java b/src/main/java/com/eactive/eai/common/session/SessionManagerForEhcache.java index 8c876c3..e23b465 100644 --- a/src/main/java/com/eactive/eai/common/session/SessionManagerForEhcache.java +++ b/src/main/java/com/eactive/eai/common/session/SessionManagerForEhcache.java @@ -3,6 +3,7 @@ package com.eactive.eai.common.session; import java.util.Properties; import java.util.concurrent.TimeUnit; +import com.eactive.eai.authserver.service.BearerTokenInfo; import com.eactive.eai.common.ehcache.CustomRMICacheReplicatorFactory; import com.eactive.eai.common.logger.EAIDBLogControl; import com.eactive.eai.common.message.EAIMessage; @@ -921,4 +922,19 @@ public class SessionManagerForEhcache extends SessionManager { sb.append(""); return sb.toString(); } + + @Override + public BearerTokenInfo getCAToken(String key) { + throw new UnsupportedOperationException(); + } + + @Override + public void putCAToken(String key, BearerTokenInfo value) { + throw new UnsupportedOperationException(); + } + + @Override + public void removeCAToken(String key) { + throw new UnsupportedOperationException(); + } } diff --git a/src/main/java/com/eactive/eai/common/session/SessionManagerForIgnite.java b/src/main/java/com/eactive/eai/common/session/SessionManagerForIgnite.java index fa397a5..55650a4 100644 --- a/src/main/java/com/eactive/eai/common/session/SessionManagerForIgnite.java +++ b/src/main/java/com/eactive/eai/common/session/SessionManagerForIgnite.java @@ -42,6 +42,7 @@ import org.apache.ignite.spi.discovery.tcp.ipfinder.multicast.TcpDiscoveryMultic import org.apache.ignite.spi.discovery.tcp.ipfinder.vm.TcpDiscoveryVmIpFinder; import com.eactive.eai.adapter.socket2.common.Env; +import com.eactive.eai.authserver.service.BearerTokenInfo; import com.eactive.eai.common.logger.EAIDBLogControl; import com.eactive.eai.common.message.EAIMessage; import com.eactive.eai.common.property.PropManager; @@ -63,6 +64,7 @@ import ch.qos.logback.classic.Level; // 에러내용 : Failed to execute the cache operation // (all partition owners have left the grid, partition data has been lost) //------------------------------------------------------------------------------------ + public class SessionManagerForIgnite extends SessionManager { // evictMaster Instance - single socket 관련 private static IgniteCache evictMasterCache = null; @@ -72,7 +74,8 @@ public class SessionManagerForIgnite extends SessionManager { private static IgniteCache cacheTopic = null; // 비동기 거래 복원용 private static IgniteCache cacheStore = null; - + // CA Gateway Token 관리용 + private static IgniteCache cacheCAToken = null; // webSocket Login cache 정보 private static IgniteCache cacheLogin = null; // key = loginId private static IgniteCache cacheConvertUserId = null; // 단말ID 를 userID로 변경 @@ -364,6 +367,7 @@ public class SessionManagerForIgnite extends SessionManager { caches.add(initCache(config, sessionTimeout, bootstrapAsynchronously, USERID_CAHCE_NAME, 20000, false)); caches.add(initCache(config, webSocketTimeout, bootstrapAsynchronously, WEBSOCKER_CAHCE_NAME, 20000, false)); caches.add(initCache(config, sessionTimeout, bootstrapAsynchronously, TERMINAL_CAHCE_NAME, 20000, false)); + caches.add(initCache(config, 0, bootstrapAsynchronously, CAGATEWAY_TOKEN_CACHE_NAME, 1000, false)); config.setCacheConfiguration(caches.stream().toArray(CacheConfiguration[]::new)); @@ -391,6 +395,7 @@ public class SessionManagerForIgnite extends SessionManager { cacheSocket = manager.cache(ADAPTER_CAHCE_NAME); cacheTopic = manager.cache(TOPIC_CAHCE_NAME); cacheStore = manager.cache(STORE_CAHCE_NAME); + cacheCAToken = manager.cache(CAGATEWAY_TOKEN_CACHE_NAME); cacheLogin = manager.cache(LOGIN_CAHCE_NAME); httpLogin = manager.cache(HTTP_CAHCE_NAME); @@ -810,4 +815,33 @@ public class SessionManagerForIgnite extends SessionManager { sb.append(""); return sb.toString(); } + + @Override + public BearerTokenInfo getCAToken(String key) { + try { + return cacheCAToken.get(key); + } catch (Exception e) { + logger.error("getCAToken null key=" + key, e); + return null; + } + } + + @Override + public void putCAToken(String key, BearerTokenInfo value) { + if (logger.isWarn()) { + logger.warn("Put CAToken key - " + key + ", CAToken - " + value.toString()); + } + cacheCAToken.put(key, value); + + } + + @Override + public void removeCAToken(String key) { + if (logger.isWarn()) { + logger.warn("Remove CAToken key - " + key); + } + cacheCAToken.remove(key); + + } + } From 31146886bd12922d648f02c06568686155155e07 Mon Sep 17 00:00:00 2001 From: yunjy-hp Date: Thu, 8 Jan 2026 15:07:58 +0900 Subject: [PATCH 080/159] =?UTF-8?q?ElinkTransactionContext=EC=97=90=20?= =?UTF-8?q?=EC=B5=9C=EC=B4=88=EC=9A=94=EC=B2=AD=EB=8D=B0=EC=9D=B4=ED=84=B0?= =?UTF-8?q?=20=EC=A0=80=EC=9E=A5=20=EB=B0=8F=20=EA=B0=80=EC=A0=B8=EB=8B=A4?= =?UTF-8?q?=20=EC=93=B0=EB=8A=94=20=ED=95=A8=EC=88=98=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../inbound/processor/RequestProcessor.java | 39 +++++++++++-------- 1 file changed, 22 insertions(+), 17 deletions(-) diff --git a/src/main/java/com/eactive/eai/inbound/processor/RequestProcessor.java b/src/main/java/com/eactive/eai/inbound/processor/RequestProcessor.java index 66872e1..f2f06be 100644 --- a/src/main/java/com/eactive/eai/inbound/processor/RequestProcessor.java +++ b/src/main/java/com/eactive/eai/inbound/processor/RequestProcessor.java @@ -5,6 +5,7 @@ import java.util.Properties; import java.util.Set; import com.eactive.eai.common.TransactionContextKeys; +import com.eactive.eai.common.context.ElinkTransactionContext; import com.eactive.eai.common.util.*; import org.apache.commons.lang3.StringUtils; import org.springframework.http.HttpStatus; @@ -59,7 +60,7 @@ import org.json.simple.JSONObject; import java.util.HashMap; import java.util.Map; //import org.apache.commons.lang3.StringUtils; -//import org.springframework.http.HttpStatus; +//import org.springframework.http.HttpStatus; //import java.util.Calendar; //import java.util.Properties; @@ -75,7 +76,7 @@ import java.util.Map; * - 응답 거래로깅 * 3. 주의사항 * - * @author : + * @author : * @version : v 1.0.0 * @see : * @since : @@ -176,7 +177,7 @@ public class RequestProcessor extends RequestProcessorSupport { * @param prop 호출시 전달할 Property 값(추후 확장을 위해) * @param msgRcvTm 메시지 수신시각 * @return Object - * @throws Exception + * @throws Exception **/ protected Object hookup(Object message, Properties prop, long msgRcvTm) throws Exception { EAIMessage retEaiMsg = null; @@ -184,7 +185,7 @@ public class RequestProcessor extends RequestProcessorSupport { ProcessVO vo = setVO(prop, msgRcvTm); prop.setProperty(TransactionContextKeys.TRANSACTION_UUID, vo.getUuid()); - String inboundCharset = prop.getProperty(Keys.CHARSET_KEY_IN); + String inboundCharset = prop.getProperty(Keys.CHARSET_KEY_IN); // Unknown Message 로깅시 표준메시지일 경우 원본 자체를 남기기 위해 변수로 저장한다. // logUnknownMessage 호출시 사용하도록 함 @@ -199,7 +200,7 @@ public class RequestProcessor extends RequestProcessorSupport { } catch (Exception e1) { logger.error("deep copy error : " + e1.getMessage(), e1); } - + // 2. StandardMessage 생성 EAIServerManager eaiServerManager = EAIServerManager.getInstance(); StandardMessage standardMessage = null; @@ -207,17 +208,17 @@ public class RequestProcessor extends RequestProcessorSupport { StandardReader reader = null; InterfaceMapper mapper = standardManager.getMapper(); StandardMessage subMessage = null; - + if(Keys.IF_STANDARD.equals(vo.getStdMsgTypeCode())) { if (logger.isDebug()) logger.debug("RequestProcessor] Get Message from INPUT MESSAGE"); try { - standardMessage = standardManager.getStandardMessage(); - reader = standardManager.getReader(vo.getAdptrMsgType()); + standardMessage = standardManager.getStandardMessage(); + reader = standardManager.getReader(vo.getAdptrMsgType()); reader.parse(standardMessage, message); // 표준전문 파싱 후 어댑터의 charset을 설정한다. standardMessage.setBizDataCharset(inboundCharset); standardManager.getMessageCoordinator().coordinateAfterParsing(standardMessage, vo, prop); - + } catch(Exception e) { vo.setRspErrorCode("RECEAIIRP008"); vo.setRspErrorMsg(ExceptionUtil.make(e, vo.getRspErrorCode(), new String[]{ e.getMessage()})); @@ -226,7 +227,7 @@ public class RequestProcessor extends RequestProcessorSupport { logUnknownMessage(vo,orgMessage); throw new RequestProcessorException(vo.getRspErrorMsg()); } - } + } else { try { if(eaiServerManager.isTASEnabledEAIServer() && Keys.TESTMASTER_TAS.equals(vo.getTestMasterYn())) { //비표준 시뮬레이터 @@ -269,7 +270,7 @@ public class RequestProcessor extends RequestProcessorSupport { else { throw ex; } - } + } } else { if (logger.isInfo()) logger.info("RequestProcessor] The RequestAction is null in Adapter properties. - "+vo.getAdapterName()); } @@ -290,7 +291,7 @@ public class RequestProcessor extends RequestProcessorSupport { } } } - + if(Keys.IF_SUBSTANDARD.equals(vo.getStdMsgTypeCode())) { if (logger.isDebug()) logger.debug("RequestProcessor] Mapping StandardMessage from INPUT MESSAGE - SUBSTANDARD"); try { @@ -301,7 +302,7 @@ public class RequestProcessor extends RequestProcessorSupport { subMessage = versionMapper.parseSub(vo.getAdptrMsgType(), message); subMessage.setBizDataCharset(inboundCharset); standardMessage = versionMapper.mapFromSub(subMessage, standardMessage); - + // 변경된 값이 있을 수 있으므로 재처리. standardManager.getMessageCoordinator().coordinateAfterParsing(standardMessage, vo, prop); if(logger.isDebug() && standardMessage !=null) { @@ -350,9 +351,9 @@ public class RequestProcessor extends RequestProcessorSupport { String guid = mapper.getGuid(standardMessage); String guidSeq = mapper.getGuidSeq(standardMessage); String returnType = mapper.getSendRecvDivision(standardMessage); // S|R - + String receivedBizData = standardMessage.getBizData(); - + vo.setEaiSvcCd(eaiSvcCd); if (StringUtils.isBlank(eaiSvcCd)) { vo.setRspErrorCode("RECEAIIRP009"); @@ -383,7 +384,7 @@ public class RequestProcessor extends RequestProcessorSupport { return getInboundErrorResponse(prop, standardMessage, mapper, vo.getRspErrorCode(), vo.getRspErrorMsg(), inboundCharset); } } - + // 채널분류코드별로 GUID 중복체크 if (eaiServerManager.isMCI() && STDMessageKeys.SEND_RECV_CD_SEND.equals(mapper.getSendRecvDivision(standardMessage)) && PropManager.getInstance().isContainProperties("DUPLICATION_GUID") ) { @@ -414,7 +415,11 @@ public class RequestProcessor extends RequestProcessorSupport { } } prop.setProperty(TransactionContextKeys.GUID, guid); - + + // INBOUND MESSAGE 스레드 로컬에 저장 + String bizData = standardMessage.getBizData(); + ElinkTransactionContext.setRequestBizData(bizData); + // INBOUND_HEADER 가 NULL인 경우는 HTTP가 아닌것으로 간주함. if(prop.get(HttpClientAdapterServiceKey.INBOUND_HEADER) != null) { HttpAdapterExtraLogUtil.insertHttpAdapterExtraLog(vo.getUuid(), 100, From 2e8d94b11051f44ed500a7e989aa8bb96c482122 Mon Sep 17 00:00:00 2001 From: pksup Date: Fri, 9 Jan 2026 10:09:06 +0900 Subject: [PATCH 081/159] =?UTF-8?q?:=20=ED=86=B5=EA=B3=84=EA=B1=B0?= =?UTF-8?q?=EB=9E=98=20=EB=8D=B0=EC=9D=B4=ED=84=B0=20=EC=A0=80=EC=9E=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Task-Url: --- .../eactive/eai/common/message/EAIMessage.java | 9 +++++++++ .../eai/common/monitor/EAIServiceMonitor.java | 17 ++++++++++++++++- .../eai/common/monitor/StatisticsMonitor.java | 9 +++++++++ 3 files changed, 34 insertions(+), 1 deletion(-) create mode 100644 src/main/java/com/eactive/eai/common/monitor/StatisticsMonitor.java diff --git a/src/main/java/com/eactive/eai/common/message/EAIMessage.java b/src/main/java/com/eactive/eai/common/message/EAIMessage.java index 255e974..cd58795 100644 --- a/src/main/java/com/eactive/eai/common/message/EAIMessage.java +++ b/src/main/java/com/eactive/eai/common/message/EAIMessage.java @@ -32,6 +32,7 @@ public class EAIMessage implements EAIMessageKeys, Serializable, Comparable bwkVO = bwkClss.get(bwkCls); @@ -391,7 +406,7 @@ public class EAIServiceMonitor implements Lifecycle { logger.error(ExceptionUtil.make("RECEAICMT204", errorText)); } } - + public void resetAll() { String[] keys = getAllMonitorVOKey(); MonitorVO vo = null; diff --git a/src/main/java/com/eactive/eai/common/monitor/StatisticsMonitor.java b/src/main/java/com/eactive/eai/common/monitor/StatisticsMonitor.java new file mode 100644 index 0000000..875f123 --- /dev/null +++ b/src/main/java/com/eactive/eai/common/monitor/StatisticsMonitor.java @@ -0,0 +1,9 @@ +package com.eactive.eai.common.monitor; + +import com.eactive.eai.common.message.EAIMessage; + +public interface StatisticsMonitor { + + public void recordStatistics(EAIMessage requestEaiMessage); + +} From 9155ad51ff978bbc6dfd942d93f4b1cd63cf789f Mon Sep 17 00:00:00 2001 From: "Yunsam.Eo" Date: Fri, 9 Jan 2026 14:41:24 +0900 Subject: [PATCH 082/159] =?UTF-8?q?Body=EA=B0=92=EC=9D=B4=20"",=20Null,=20?= =?UTF-8?q?"{}"=20=EC=9D=BC=20=EA=B2=BD=EC=9A=B0=EC=99=80=20Method?= =?UTF-8?q?=EA=B0=80=20GET/DELETE=EC=9D=BC=20=EA=B2=BD=EC=9A=B0=20signatur?= =?UTF-8?q?e-body=20=EA=B2=80=EC=A6=9D=20=EC=A0=9C=EC=99=B8(by=20=EC=9D=B4?= =?UTF-8?q?=EC=83=81=EC=9A=B1D)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../filter/HmacSha256VerifyFilterKjb.java | 21 +++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/src/main/java/com/eactive/eai/adapter/http/dynamic/filter/HmacSha256VerifyFilterKjb.java b/src/main/java/com/eactive/eai/adapter/http/dynamic/filter/HmacSha256VerifyFilterKjb.java index 4cd3bcf..4d73b4e 100644 --- a/src/main/java/com/eactive/eai/adapter/http/dynamic/filter/HmacSha256VerifyFilterKjb.java +++ b/src/main/java/com/eactive/eai/adapter/http/dynamic/filter/HmacSha256VerifyFilterKjb.java @@ -15,6 +15,7 @@ import javax.servlet.http.HttpServletResponse; import org.springframework.http.HttpStatus; import org.apache.commons.lang3.StringUtils; +import com.eactive.eai.adapter.http.HttpMethodType; import com.eactive.eai.adapter.http.dynamic.HttpAdapterServiceKey; import com.eactive.eai.adapter.http.dynamic.HttpAdapterServiceSupport; import com.eactive.eai.authserver.service.OAuth2Manager; @@ -43,8 +44,7 @@ public class HmacSha256VerifyFilterKjb implements HttpAdapterFilter { String xObpSignatureUrl = request.getHeader("x-obp-signature-url"); String xObpSignatureBody = request.getHeader("x-obp-signature-body"); if (StringUtils.isBlank(xObpPartnercode) - || StringUtils.isBlank(xObpSignatureUrl) - || StringUtils.isBlank(xObpSignatureBody)) { + || StringUtils.isBlank(xObpSignatureUrl)) { throw new JwtAuthException( String.valueOf(HttpStatus.UNAUTHORIZED.value()), "Can not find mandatory Http Header"); @@ -67,10 +67,19 @@ public class HmacSha256VerifyFilterKjb implements HttpAdapterFilter { "Signature verifying failed : x-obp-signature-url"); } - if (!StringUtils.equals(xObpSignatureBody, macBody)) { - throw new JwtAuthException( - String.valueOf(HttpStatus.UNAUTHORIZED.value()), - "Signature verifying failed : x-obp-signature-body"); + switch (HttpMethodType.getValue(request.getMethod())) { + case GET: + case DELETE: + break; + default: + if (StringUtils.isNotBlank(inboundBody) && !StringUtils.equals("{}", inboundBody)) { + if (!StringUtils.equals(xObpSignatureBody, macBody)) { + throw new JwtAuthException( + String.valueOf(HttpStatus.UNAUTHORIZED.value()), + "Signature verifying failed : x-obp-signature-body"); + } + break; + } } } catch (JwtAuthException e) { From acfe440310b72278edce55f688ae0f5d7e09529d Mon Sep 17 00:00:00 2001 From: jaewohong Date: Fri, 9 Jan 2026 15:44:14 +0900 Subject: [PATCH 083/159] =?UTF-8?q?http=20status=20=EC=97=90=EB=9F=AC?= =?UTF-8?q?=EC=BD=94=EB=93=9C=20=EC=A0=95=EC=83=81=EC=B2=98=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../impl/HttpClient5AdapterServiceRest.java | 35 ++++++++++++++++++- 1 file changed, 34 insertions(+), 1 deletion(-) diff --git a/src/main/java/com/eactive/eai/adapter/http/client/impl/HttpClient5AdapterServiceRest.java b/src/main/java/com/eactive/eai/adapter/http/client/impl/HttpClient5AdapterServiceRest.java index 4ee9b4c..f3e34ea 100644 --- a/src/main/java/com/eactive/eai/adapter/http/client/impl/HttpClient5AdapterServiceRest.java +++ b/src/main/java/com/eactive/eai/adapter/http/client/impl/HttpClient5AdapterServiceRest.java @@ -164,6 +164,9 @@ public class HttpClient5AdapterServiceRest extends HttpClient5AdapterServiceSupp //Outbound 요청에 대한 응답 메시지의 복호화 여부 결정위해 jwhong encryptResponseApply = StringUtils.equalsIgnoreCase(prop.getProperty("ENCRYPT_RESPONSE_APPLY", "N"), "Y"); + + //업체 300응답시 특정 http status code 경우 에러 아닌걸로 처리. 광주은행 + String errIgnore = prop.getProperty("ERROR_IGNORE_CODE", ""); /** * @formatter:off @@ -496,7 +499,10 @@ public class HttpClient5AdapterServiceRest extends HttpClient5AdapterServiceSupp map.put(HttpAdapterServiceKey.OUTBOUND_RESPONSE_MESSAGE, responseString); map.put(HttpAdapterServiceKey.OUTBOUND_RESPONSE_STATUS, status); - if (status >= 200 && status <= 207) { + + if (isStatusInIgnore(status,errIgnore )) { + // 이경우 정상임 + } else if (status >= 200 && status <= 207) { if (useAdapterToken && StringUtils.equals(tokenErrorHttpStatusCode, "200")) { needReissue = checkTokenRetry(responseMessage, tokenErrorCodeKey, tokenErrorCodeValues, vo.getEncode()); @@ -1563,4 +1569,31 @@ public class HttpClient5AdapterServiceRest extends HttpClient5AdapterServiceSupp logger.debug("HttpClientAdapterServiceRest] after concatenate url=[" + targetUrl + "] "); return targetUrl; } + + + private boolean isStatusInIgnore(int status, String errIgnore) { + if (errIgnore == null || errIgnore.isEmpty()) return false; + + String[] tokens = errIgnore.split(","); + for (String token : tokens) { + token = token.trim(); + if (token.contains("-")) { + // 범위 처리 + String[] range = token.split("-"); + int start = Integer.parseInt(range[0].trim()); + int end = Integer.parseInt(range[1].trim()); + if (status >= start && status <= end) { + return true; + } + } else { + // 단일 숫자 처리 + int code = Integer.parseInt(token); + if (status == code) { + return true; + } + } + } + return false; + } + } From 1a6fd332a7442994a95f24e57e74e49bdd188bef Mon Sep 17 00:00:00 2001 From: jaewohong Date: Fri, 9 Jan 2026 15:48:43 +0900 Subject: [PATCH 084/159] http status code check --- .../adapter/http/client/impl/HttpClient5AdapterServiceRest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/com/eactive/eai/adapter/http/client/impl/HttpClient5AdapterServiceRest.java b/src/main/java/com/eactive/eai/adapter/http/client/impl/HttpClient5AdapterServiceRest.java index f3e34ea..17e3579 100644 --- a/src/main/java/com/eactive/eai/adapter/http/client/impl/HttpClient5AdapterServiceRest.java +++ b/src/main/java/com/eactive/eai/adapter/http/client/impl/HttpClient5AdapterServiceRest.java @@ -93,7 +93,7 @@ import java.util.Date; * 기능을 제공한다.
* 2. 처리 개요 :
* * - 2020-09-25: Http Header 받아서 처리할 수 있게 기능 추가
- * 3. 주의사항
+ * 3. 주의사항
* * @author : * @version : v 1.0.0 From 27ebdb86730efbb9a55bc015e805832670640be1 Mon Sep 17 00:00:00 2001 From: jaewohong Date: Fri, 9 Jan 2026 16:33:05 +0900 Subject: [PATCH 085/159] =?UTF-8?q?http=20status=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../adapter/http/client/impl/HttpClient5AdapterServiceRest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/com/eactive/eai/adapter/http/client/impl/HttpClient5AdapterServiceRest.java b/src/main/java/com/eactive/eai/adapter/http/client/impl/HttpClient5AdapterServiceRest.java index 17e3579..b826016 100644 --- a/src/main/java/com/eactive/eai/adapter/http/client/impl/HttpClient5AdapterServiceRest.java +++ b/src/main/java/com/eactive/eai/adapter/http/client/impl/HttpClient5AdapterServiceRest.java @@ -501,7 +501,7 @@ public class HttpClient5AdapterServiceRest extends HttpClient5AdapterServiceSupp if (isStatusInIgnore(status,errIgnore )) { - // 이경우 정상임 + // 이경우 정상으로 처리함 } else if (status >= 200 && status <= 207) { if (useAdapterToken && StringUtils.equals(tokenErrorHttpStatusCode, "200")) { needReissue = checkTokenRetry(responseMessage, tokenErrorCodeKey, tokenErrorCodeValues, From daf33df5af9fd622d44b0b75fd84c6158daa3c6c Mon Sep 17 00:00:00 2001 From: cho Date: Sat, 10 Jan 2026 13:55:31 +0900 Subject: [PATCH 086/159] =?UTF-8?q?inbound=EC=97=90=20json=20=EC=A0=84?= =?UTF-8?q?=EB=AC=B8=EC=9D=BC=20=EB=95=8C,=20=EC=B5=9C=EC=83=81=EC=9C=84?= =?UTF-8?q?=EC=97=90=20Array('[]')=ED=83=80=EC=9E=85=EC=9D=B4=20=EB=B0=94?= =?UTF-8?q?=EB=A1=9C=20=EC=98=AC=EB=95=8C,=20=EB=B3=80=ED=99=98=EC=B2=98?= =?UTF-8?q?=EB=A6=AC=EB=A5=BC=20=EC=9C=84=ED=95=B4,=20KJB=5FROOTLESS=5FARR?= =?UTF-8?q?AY=20=EB=9D=BC=EB=8A=94=20=ED=82=A4=EC=9D=98=20Object=EB=A5=BC?= =?UTF-8?q?=20warraped=20=EC=B2=98=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../impl/HttpClient5AdapterServiceRest.java | 31 ++++++++++++++++--- .../impl/HttpAdapterServiceStandard.java | 31 ++++++++++++++++++- 2 files changed, 57 insertions(+), 5 deletions(-) diff --git a/src/main/java/com/eactive/eai/adapter/http/client/impl/HttpClient5AdapterServiceRest.java b/src/main/java/com/eactive/eai/adapter/http/client/impl/HttpClient5AdapterServiceRest.java index 4ee9b4c..a34e183 100644 --- a/src/main/java/com/eactive/eai/adapter/http/client/impl/HttpClient5AdapterServiceRest.java +++ b/src/main/java/com/eactive/eai/adapter/http/client/impl/HttpClient5AdapterServiceRest.java @@ -949,11 +949,23 @@ public class HttpClient5AdapterServiceRest extends HttpClient5AdapterServiceSupp if (eaiBody == null) { return; } + + if (eaiBody instanceof JSONObject) { + JSONObject jsonObject = (JSONObject) eaiBody; + if( jsonObject.containsKey("KJB_ROOTLESS_ARRAY") ) { + ContentType contentTypeObj = ContentType.create(contentType, charset); + JSONArray array = (JSONArray) jsonObject.get("KJB_ROOTLESS_ARRAY"); + StringEntity entity = new StringEntity(array.toJSONString(), contentTypeObj); + method.setEntity(entity); + return; + } + } if (StringUtils.contains(contentType, "application/x-www-form-urlencoded")) { if (eaiBody instanceof JSONObject) { List params = new ArrayList<>(); JSONObject jsonObject = (JSONObject) eaiBody; + for (Object key : jsonObject.keySet()) { //String encryptedValue = encrypt((String) jsonObject.get(key)); // encrypt by jwhong //params.add(new BasicNameValuePair((String) key, encryptedValue )); @@ -1456,11 +1468,22 @@ public class HttpClient5AdapterServiceRest extends HttpClient5AdapterServiceSupp @SuppressWarnings("deprecation") private JSONObject parseJson(String message) throws Exception { - if (message == null) { - return null; - } + if (message == null || message.trim().isEmpty()) { + return null; + } - return (JSONObject) JSONValue.parse(message); + Object obj = JSONValue.parse(message); + + if (obj instanceof JSONObject) { + return (JSONObject) obj; + } else if (obj instanceof JSONArray) { + // 배열일 경우 새로운 객체로 감싸서 반환 + JSONObject wrapper = new JSONObject(); + wrapper.put("KJB_ROOTLESS_ARRAY", obj); + return wrapper; + } + + return null; // 혹은 상황에 맞는 예외 처리 } private Document convertXmlDocument(String message) throws Exception { diff --git a/src/main/java/com/eactive/eai/adapter/http/dynamic/impl/HttpAdapterServiceStandard.java b/src/main/java/com/eactive/eai/adapter/http/dynamic/impl/HttpAdapterServiceStandard.java index 002999f..f50d367 100644 --- a/src/main/java/com/eactive/eai/adapter/http/dynamic/impl/HttpAdapterServiceStandard.java +++ b/src/main/java/com/eactive/eai/adapter/http/dynamic/impl/HttpAdapterServiceStandard.java @@ -19,6 +19,9 @@ import com.eactive.eai.inbound.processor.Processor; import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.time.StopWatch; import org.apache.mina.common.ByteBuffer; +import org.json.simple.JSONArray; +import org.json.simple.JSONObject; +import org.json.simple.JSONValue; import javax.servlet.ServletException; import javax.servlet.ServletInputStream; @@ -180,6 +183,21 @@ public class HttpAdapterServiceStandard extends HttpAdapterServiceSupport prop.put(PROPERTIES_NAME_HTTP_REQUEST_METHOD, request.getMethod()); prop.put(ALLOW_IP, httpProp.getProperty(ALLOW_IP, "")); + String body = new String ( requestBytes,encode); + + try { + Object root = JSONValue.parse(body); + if( root instanceof JSONArray ) { + JSONObject wrappedObject = new JSONObject(); + wrappedObject.put("KJB_ROOTLESS_ARRAY", root); + requestBytes = wrappedObject.toJSONString().getBytes(encode); + } + + }catch (Exception e) { + // ignore json이 아니기에 해줄것이 없음. + } + + // 로컬 서비스 호출 Object result = null; if (MessageUtil.isBytesMessage(messageType)) { @@ -208,7 +226,7 @@ public class HttpAdapterServiceStandard extends HttpAdapterServiceSupport responseData = ElinkConfig.getAsyncDummyDataForAdapterGroup(adptGrpName, adptName); } } - + response.setCharacterEncoding(encode); response.getWriter().print(responseData); if (traceLevel >= 3){ @@ -230,6 +248,17 @@ public class HttpAdapterServiceStandard extends HttpAdapterServiceSupport responseData = addData + responseData; } + + try { + Object root = JSONValue.parse(responseData); + if( root instanceof JSONObject ) { + JSONObject wrappedObject = (JSONObject) root; + responseData = wrappedObject.get("KJB_ROOTLESS_ARRAY").toString(); + } + + }catch (Exception e) { + // ignore json이 아니기에 해줄것이 없음. + } // 300응답에서 받은 Header정보 사용하기 위해 읽어옴. Map responsePropertyMap = new HashMap(); responsePropertyMap = (Map) prop.get(OUTBOUND_PROPERTY_MAP); From a61ced84c5a24eae4aeb95211c0ab9dff8f53a55 Mon Sep 17 00:00:00 2001 From: cho Date: Sat, 10 Jan 2026 15:13:11 +0900 Subject: [PATCH 087/159] =?UTF-8?q?fixedToken=ED=83=80=EC=9E=85=EC=9D=84?= =?UTF-8?q?=20=EB=A7=8C=EB=93=A4=EB=A0=A4=EA=B3=A0=20=ED=96=88=EC=9C=BC?= =?UTF-8?q?=EB=82=98,=20=EC=9D=B4=EB=AF=B8=20HttpClient5AdapterServiceRest?= =?UTF-8?q?.java=EC=97=90=EC=84=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 인터페이스타입(AccessTokenVO)를 사용하지않고 구현체인, OAuth2AccessTokenVO를 캐스팅해서 써버림. 테스트중이고, 영향도가 높아보여 fixed토큰이지만 OAuth2AccessTokenVO를 사용함. --- ...lientAccessTokenServiceWithFixedToken.java | 27 +++++++++++++++++++ 1 file changed, 27 insertions(+) create mode 100644 src/main/java/com/eactive/eai/authoutbound/client/impl/HttpClientAccessTokenServiceWithFixedToken.java diff --git a/src/main/java/com/eactive/eai/authoutbound/client/impl/HttpClientAccessTokenServiceWithFixedToken.java b/src/main/java/com/eactive/eai/authoutbound/client/impl/HttpClientAccessTokenServiceWithFixedToken.java new file mode 100644 index 0000000..aae9f06 --- /dev/null +++ b/src/main/java/com/eactive/eai/authoutbound/client/impl/HttpClientAccessTokenServiceWithFixedToken.java @@ -0,0 +1,27 @@ +package com.eactive.eai.authoutbound.client.impl; + +import java.util.Properties; + +import com.eactive.eai.authoutbound.OutboundOAuthCredentialVo; +import com.eactive.eai.authoutbound.client.HttpClientAccessTokenServiceByDB; +import com.openbanking.eai.common.token.OAuth2AccessTokenVO; + +public class HttpClientAccessTokenServiceWithFixedToken implements HttpClientAccessTokenServiceByDB { + + @Override + public Object execute(String adapterGroupName, Properties adapterProp, OutboundOAuthCredentialVo oAuthCredentialVo) + throws Exception { + + OAuth2AccessTokenVO fixedAccessToken = new OAuth2AccessTokenVO(); + + fixedAccessToken.setAccessToken(oAuthCredentialVo.getClientSecret()); + fixedAccessToken.setClientId("none"); + fixedAccessToken.setClientUseCode("anyone"); + fixedAccessToken.setExpiresIn(60 * 60 * 24 * 365); //1년 + fixedAccessToken.setScope("none"); + fixedAccessToken.setTokenType("fixed"); + + return fixedAccessToken; + } + +} From 8957b763ffa3c9118b1d0e2563d698e7137266da Mon Sep 17 00:00:00 2001 From: cho Date: Sat, 10 Jan 2026 16:02:28 +0900 Subject: [PATCH 088/159] =?UTF-8?q?=EC=96=B4=EB=8C=91=ED=84=B0=20=ED=97=A4?= =?UTF-8?q?=EB=8D=94=EC=85=8B=ED=8C=85=20=ED=94=84=EB=A1=9C=ED=8D=BC?= =?UTF-8?q?=ED=8B=B0=20=EC=B2=98=EB=A6=AC=20=EC=B6=94=EA=B0=80.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../impl/HttpClient5AdapterServiceRest.java | 78 ++++++++++++------- .../HttpClientAccessTokenServiceByDB.java | 2 +- 2 files changed, 51 insertions(+), 29 deletions(-) diff --git a/src/main/java/com/eactive/eai/adapter/http/client/impl/HttpClient5AdapterServiceRest.java b/src/main/java/com/eactive/eai/adapter/http/client/impl/HttpClient5AdapterServiceRest.java index 10524af..0f076cf 100644 --- a/src/main/java/com/eactive/eai/adapter/http/client/impl/HttpClient5AdapterServiceRest.java +++ b/src/main/java/com/eactive/eai/adapter/http/client/impl/HttpClient5AdapterServiceRest.java @@ -9,15 +9,22 @@ import java.net.URI; import java.nio.charset.StandardCharsets; import java.text.SimpleDateFormat; import java.util.ArrayList; +import java.util.Base64; +import java.util.Date; import java.util.HashMap; +import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Map.Entry; import java.util.Properties; +import java.util.Set; import java.util.regex.Matcher; import java.util.regex.Pattern; -import com.eactive.eai.common.property.PropManager; +// encrypt test by jwhong +import javax.crypto.Cipher; +import javax.crypto.spec.SecretKeySpec; + import org.apache.commons.lang3.ArrayUtils; import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.time.StopWatch; @@ -60,34 +67,26 @@ import com.eactive.eai.adapter.http.client.HttpClient5AdapterServiceSupport; import com.eactive.eai.adapter.http.client.HttpClientAdapterServiceKey; import com.eactive.eai.adapter.http.client.HttpClientAdapterVO; import com.eactive.eai.adapter.http.dynamic.HttpAdapterServiceKey; +import com.eactive.eai.authserver.service.OAuth2Manager; import com.eactive.eai.common.TransactionContextKeys; import com.eactive.eai.common.authoutbound.AccessTokenManagerByDB; import com.eactive.eai.common.exception.ExceptionUtil; import com.eactive.eai.common.message.MessageType; +import com.eactive.eai.common.property.PropManager; import com.eactive.eai.common.util.CommonLib; import com.jayway.jsonpath.DocumentContext; import com.jayway.jsonpath.JsonPath; +import com.kjbank.encrypt.exchange.crypto.AES256Cipher; +import com.kjbank.encrypt.exchange.crypto.AES256GCMCipher; +import com.kjbank.encrypt.exchange.crypto.AESCipher; +import com.kjbank.encrypt.exchange.crypto.ECDHESA256Cipher; +import com.nimbusds.jwt.SignedJWT; import com.openbanking.eai.common.token.AccessTokenManager; import com.openbanking.eai.common.token.AccessTokenVO; import com.openbanking.eai.common.token.OAuth2AccessTokenVO; import edu.emory.mathcs.backport.java.util.Arrays; -// encrypt test by jwhong -import javax.crypto.Cipher; -import javax.crypto.spec.SecretKeySpec; -import java.nio.charset.StandardCharsets; -import java.util.Base64; -import com.kjbank.encrypt.exchange.crypto.AES256Cipher; -import com.kjbank.encrypt.exchange.crypto.AESCipher; -import com.nimbusds.jwt.SignedJWT; -import com.kjbank.encrypt.exchange.crypto.AES256GCMCipher; -import com.kjbank.encrypt.exchange.crypto.ECDHESA256Cipher; -import com.eactive.eai.authserver.service.OAuth2Manager; -import java.util.Set; -import java.util.HashSet; -import java.util.Date; - /** * 1. 기능 : EAI HTTP OutBound 용 어댑터로 수동 시스템의 HTTP 웹 컴포넌트를 GET/POST 방식으로 호출할 수 있는 * 기능을 제공한다.
@@ -112,11 +111,13 @@ public class HttpClient5AdapterServiceRest extends HttpClient5AdapterServiceSupp public static final String HTTP_STATUS = "HTTP_STATUS"; public static final String HEADER_KEYS = "HEADER_KEYS"; public static final String AUTH_TOKEN = "AUTH_TOKEN"; + public static final String HTTP_HEADER_SETTING = "HTTP_HEADER_SETTING"; public static final String PAYLOAD_PARAM_NAME_CLIENT_ID = "client_id"; // jwhong private boolean useAdapterToken; private boolean encryptResponseApply; + private String httpHeaderSettingByAdapter = "{}"; /** * 1. 기능 : REST API 통신에 사용
@@ -393,7 +394,7 @@ public class HttpClient5AdapterServiceRest extends HttpClient5AdapterServiceSupp // 전달 header 셋팅 // Adapter 레벨 header 보다 data로 넘어온 httpHeader를 우선 적용(header명이 같다면 덮어씀) - assignRequestHeaders(method, httpHeader); + assignRequestHeaders(method, httpHeader, prop); // KJBank API 추적정보를 Header에 제공. jwhong //assignRequestKJHeaders(method, prop, tempProp ); @@ -790,27 +791,48 @@ public class HttpClient5AdapterServiceRest extends HttpClient5AdapterServiceSupp return false; } - private void assignRequestHeaders(HttpUriRequestBase method, Object httpHeader) { - if (httpHeader == null) { - return; - } + private void assignRequestHeaders(HttpUriRequestBase method, Object httpHeader, Properties prop) { + if (httpHeader != null) { + if (httpHeader instanceof JSONObject) { + JSONObject jsonObject = (JSONObject) httpHeader; + for (Object key : jsonObject.keySet()) { + Object obj = jsonObject.get(key); + if ((obj instanceof JSONObject) || (obj instanceof JSONArray)) { + continue; + } - if (httpHeader instanceof JSONObject) { - JSONObject jsonObject = (JSONObject) httpHeader; - for (Object key : jsonObject.keySet()) { - Object obj = jsonObject.get(key); + method.setHeader((String) key, (String) obj); + + if (logger.isDebugEnabled()) { + logger.debug("Request Header :" + (String) key + "=[" + (String) obj + "]"); + } + + } + } + } + //전문에서 추출한 httpHeader값 외 어댑터에서 최종적으로 적용되도록, + String httpSettingJsonStr = prop.getProperty( HTTP_HEADER_SETTING , "{}"); + try { + JSONObject httpValues = (JSONObject) JSONValue.parse(httpSettingJsonStr); + + for (Object key : httpValues.keySet()) { + Object obj = httpValues.get(key); if ((obj instanceof JSONObject) || (obj instanceof JSONArray)) { continue; } - - method.setHeader((String) key, (String) obj); - + + method.setHeader((String) key, obj); + if (logger.isDebugEnabled()) { logger.debug("Request Header :" + (String) key + "=[" + (String) obj + "]"); } } + + }catch (Exception e) { + logger.error("HTTP_HEADER_SETTING value is not JSONObject Type, skip.", e); } + } private void assignFilterHeaders(HttpUriRequestBase method, Properties tempProp) { diff --git a/src/main/java/com/eactive/eai/authoutbound/client/HttpClientAccessTokenServiceByDB.java b/src/main/java/com/eactive/eai/authoutbound/client/HttpClientAccessTokenServiceByDB.java index 40ac62a..fd589d1 100644 --- a/src/main/java/com/eactive/eai/authoutbound/client/HttpClientAccessTokenServiceByDB.java +++ b/src/main/java/com/eactive/eai/authoutbound/client/HttpClientAccessTokenServiceByDB.java @@ -31,6 +31,6 @@ public interface HttpClientAccessTokenServiceByDB { * @return 반환 된 AccessTokenVO * @exception Exception 수동 시스템 간 통신 중 발생 **/ - public Object execute(String name, Properties adapterProp, OutboundOAuthCredentialVo oAuthCredentialVo) throws Exception ; + public Object execute(String adapterGroupName, Properties adapterProp, OutboundOAuthCredentialVo oAuthCredentialVo) throws Exception ; } From 6c43443faf5f5e3c00ffaad0f47a61823505ef59 Mon Sep 17 00:00:00 2001 From: cho Date: Sat, 10 Jan 2026 18:58:30 +0900 Subject: [PATCH 089/159] KJB_ROOTLESS_ARRAY -> kjbrootlessarray --- .../http/client/impl/HttpClient5AdapterServiceRest.java | 6 +++--- .../http/dynamic/impl/HttpAdapterServiceStandard.java | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/main/java/com/eactive/eai/adapter/http/client/impl/HttpClient5AdapterServiceRest.java b/src/main/java/com/eactive/eai/adapter/http/client/impl/HttpClient5AdapterServiceRest.java index 0f076cf..595e8c3 100644 --- a/src/main/java/com/eactive/eai/adapter/http/client/impl/HttpClient5AdapterServiceRest.java +++ b/src/main/java/com/eactive/eai/adapter/http/client/impl/HttpClient5AdapterServiceRest.java @@ -980,9 +980,9 @@ public class HttpClient5AdapterServiceRest extends HttpClient5AdapterServiceSupp if (eaiBody instanceof JSONObject) { JSONObject jsonObject = (JSONObject) eaiBody; - if( jsonObject.containsKey("KJB_ROOTLESS_ARRAY") ) { + if( jsonObject.containsKey("kjbrootlessarray") ) { ContentType contentTypeObj = ContentType.create(contentType, charset); - JSONArray array = (JSONArray) jsonObject.get("KJB_ROOTLESS_ARRAY"); + JSONArray array = (JSONArray) jsonObject.get("kjbrootlessarray"); StringEntity entity = new StringEntity(array.toJSONString(), contentTypeObj); method.setEntity(entity); return; @@ -1507,7 +1507,7 @@ public class HttpClient5AdapterServiceRest extends HttpClient5AdapterServiceSupp } else if (obj instanceof JSONArray) { // 배열일 경우 새로운 객체로 감싸서 반환 JSONObject wrapper = new JSONObject(); - wrapper.put("KJB_ROOTLESS_ARRAY", obj); + wrapper.put("kjbrootlessarray", obj); return wrapper; } diff --git a/src/main/java/com/eactive/eai/adapter/http/dynamic/impl/HttpAdapterServiceStandard.java b/src/main/java/com/eactive/eai/adapter/http/dynamic/impl/HttpAdapterServiceStandard.java index f50d367..ec008c4 100644 --- a/src/main/java/com/eactive/eai/adapter/http/dynamic/impl/HttpAdapterServiceStandard.java +++ b/src/main/java/com/eactive/eai/adapter/http/dynamic/impl/HttpAdapterServiceStandard.java @@ -189,7 +189,7 @@ public class HttpAdapterServiceStandard extends HttpAdapterServiceSupport Object root = JSONValue.parse(body); if( root instanceof JSONArray ) { JSONObject wrappedObject = new JSONObject(); - wrappedObject.put("KJB_ROOTLESS_ARRAY", root); + wrappedObject.put("kjbrootlessarray", root); requestBytes = wrappedObject.toJSONString().getBytes(encode); } @@ -253,7 +253,7 @@ public class HttpAdapterServiceStandard extends HttpAdapterServiceSupport Object root = JSONValue.parse(responseData); if( root instanceof JSONObject ) { JSONObject wrappedObject = (JSONObject) root; - responseData = wrappedObject.get("KJB_ROOTLESS_ARRAY").toString(); + responseData = wrappedObject.get("kjbrootlessarray").toString(); } }catch (Exception e) { From 6d60bd2dd1660d552575f661eb05c0b374120108 Mon Sep 17 00:00:00 2001 From: cho Date: Sat, 10 Jan 2026 19:34:47 +0900 Subject: [PATCH 090/159] =?UTF-8?q?ROOTLESSARRAY=20=EC=9B=90=EB=B3=B5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../impl/HttpClient5AdapterServiceRest.java | 23 +---------------- .../impl/HttpAdapterServiceStandard.java | 25 +------------------ 2 files changed, 2 insertions(+), 46 deletions(-) diff --git a/src/main/java/com/eactive/eai/adapter/http/client/impl/HttpClient5AdapterServiceRest.java b/src/main/java/com/eactive/eai/adapter/http/client/impl/HttpClient5AdapterServiceRest.java index 595e8c3..1cce281 100644 --- a/src/main/java/com/eactive/eai/adapter/http/client/impl/HttpClient5AdapterServiceRest.java +++ b/src/main/java/com/eactive/eai/adapter/http/client/impl/HttpClient5AdapterServiceRest.java @@ -978,16 +978,6 @@ public class HttpClient5AdapterServiceRest extends HttpClient5AdapterServiceSupp return; } - if (eaiBody instanceof JSONObject) { - JSONObject jsonObject = (JSONObject) eaiBody; - if( jsonObject.containsKey("kjbrootlessarray") ) { - ContentType contentTypeObj = ContentType.create(contentType, charset); - JSONArray array = (JSONArray) jsonObject.get("kjbrootlessarray"); - StringEntity entity = new StringEntity(array.toJSONString(), contentTypeObj); - method.setEntity(entity); - return; - } - } if (StringUtils.contains(contentType, "application/x-www-form-urlencoded")) { if (eaiBody instanceof JSONObject) { @@ -1500,18 +1490,7 @@ public class HttpClient5AdapterServiceRest extends HttpClient5AdapterServiceSupp return null; } - Object obj = JSONValue.parse(message); - - if (obj instanceof JSONObject) { - return (JSONObject) obj; - } else if (obj instanceof JSONArray) { - // 배열일 경우 새로운 객체로 감싸서 반환 - JSONObject wrapper = new JSONObject(); - wrapper.put("kjbrootlessarray", obj); - return wrapper; - } - - return null; // 혹은 상황에 맞는 예외 처리 + return (JSONObject) JSONValue.parse(message); } private Document convertXmlDocument(String message) throws Exception { diff --git a/src/main/java/com/eactive/eai/adapter/http/dynamic/impl/HttpAdapterServiceStandard.java b/src/main/java/com/eactive/eai/adapter/http/dynamic/impl/HttpAdapterServiceStandard.java index ec008c4..8bcd3f4 100644 --- a/src/main/java/com/eactive/eai/adapter/http/dynamic/impl/HttpAdapterServiceStandard.java +++ b/src/main/java/com/eactive/eai/adapter/http/dynamic/impl/HttpAdapterServiceStandard.java @@ -185,18 +185,6 @@ public class HttpAdapterServiceStandard extends HttpAdapterServiceSupport String body = new String ( requestBytes,encode); - try { - Object root = JSONValue.parse(body); - if( root instanceof JSONArray ) { - JSONObject wrappedObject = new JSONObject(); - wrappedObject.put("kjbrootlessarray", root); - requestBytes = wrappedObject.toJSONString().getBytes(encode); - } - - }catch (Exception e) { - // ignore json이 아니기에 해줄것이 없음. - } - // 로컬 서비스 호출 Object result = null; @@ -247,18 +235,7 @@ public class HttpAdapterServiceStandard extends HttpAdapterServiceSupport if (addData.length() > 0){ responseData = addData + responseData; } - - - try { - Object root = JSONValue.parse(responseData); - if( root instanceof JSONObject ) { - JSONObject wrappedObject = (JSONObject) root; - responseData = wrappedObject.get("kjbrootlessarray").toString(); - } - - }catch (Exception e) { - // ignore json이 아니기에 해줄것이 없음. - } + // 300응답에서 받은 Header정보 사용하기 위해 읽어옴. Map responsePropertyMap = new HashMap(); responsePropertyMap = (Map) prop.get(OUTBOUND_PROPERTY_MAP); From e158393cce93f477ae8b30f2efd455f49ee583b2 Mon Sep 17 00:00:00 2001 From: cho Date: Mon, 12 Jan 2026 14:00:06 +0900 Subject: [PATCH 091/159] =?UTF-8?q?=ED=99=94=EB=A9=B4=20=EC=85=8B=ED=8C=85?= =?UTF-8?q?=EA=B0=92=20blank=20=EC=98=88=EC=99=B8=EC=B2=98=EB=A6=AC.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../client/impl/HttpClient5AdapterServiceRest.java | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/src/main/java/com/eactive/eai/adapter/http/client/impl/HttpClient5AdapterServiceRest.java b/src/main/java/com/eactive/eai/adapter/http/client/impl/HttpClient5AdapterServiceRest.java index 1cce281..846d66e 100644 --- a/src/main/java/com/eactive/eai/adapter/http/client/impl/HttpClient5AdapterServiceRest.java +++ b/src/main/java/com/eactive/eai/adapter/http/client/impl/HttpClient5AdapterServiceRest.java @@ -811,7 +811,17 @@ public class HttpClient5AdapterServiceRest extends HttpClient5AdapterServiceSupp } } //전문에서 추출한 httpHeader값 외 어댑터에서 최종적으로 적용되도록, - String httpSettingJsonStr = prop.getProperty( HTTP_HEADER_SETTING , "{}"); + String httpSettingJsonStr = prop.getProperty( HTTP_HEADER_SETTING ); + + if( StringUtils.isBlank(httpSettingJsonStr) ) + { + if( logger.isInfoEnabled() ) { + logger.info("HTTP_HEADER_SETTING value is not JSONObject Type, skip."); + } + + return; + } + try { JSONObject httpValues = (JSONObject) JSONValue.parse(httpSettingJsonStr); From 51db6c88cfc2d827f90141ceeef0d798b7d2abf3 Mon Sep 17 00:00:00 2001 From: cho Date: Mon, 12 Jan 2026 15:20:30 +0900 Subject: [PATCH 092/159] =?UTF-8?q?RootlessArray=20=EC=B2=98=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../impl/HttpClient5AdapterServiceRest.java | 23 +++++++++++++++++- .../impl/HttpAdapterServiceStandard.java | 24 ++++++++++++++++++- 2 files changed, 45 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/eactive/eai/adapter/http/client/impl/HttpClient5AdapterServiceRest.java b/src/main/java/com/eactive/eai/adapter/http/client/impl/HttpClient5AdapterServiceRest.java index 846d66e..ad296ca 100644 --- a/src/main/java/com/eactive/eai/adapter/http/client/impl/HttpClient5AdapterServiceRest.java +++ b/src/main/java/com/eactive/eai/adapter/http/client/impl/HttpClient5AdapterServiceRest.java @@ -988,6 +988,16 @@ public class HttpClient5AdapterServiceRest extends HttpClient5AdapterServiceSupp return; } + if (eaiBody instanceof JSONObject) { + JSONObject jsonObject = (JSONObject) eaiBody; + if( jsonObject.containsKey("KJB_ROOTLESS_ARRAY") ) { + ContentType contentTypeObj = ContentType.create(contentType, charset); + JSONArray array = (JSONArray) jsonObject.get("KJB_ROOTLESS_ARRAY"); + StringEntity entity = new StringEntity(array.toJSONString(), contentTypeObj); + method.setEntity(entity); + return; + } + } if (StringUtils.contains(contentType, "application/x-www-form-urlencoded")) { if (eaiBody instanceof JSONObject) { @@ -1500,7 +1510,18 @@ public class HttpClient5AdapterServiceRest extends HttpClient5AdapterServiceSupp return null; } - return (JSONObject) JSONValue.parse(message); + Object obj = JSONValue.parse(message); + + if (obj instanceof JSONObject) { + return (JSONObject) obj; + } else if (obj instanceof JSONArray) { + // 배열일 경우 새로운 객체로 감싸서 반환 + JSONObject wrapper = new JSONObject(); + wrapper.put("KJB_ROOTLESS_ARRAY", obj); + return wrapper; + } + + return null; // 혹은 상황에 맞는 예외 처리 } private Document convertXmlDocument(String message) throws Exception { diff --git a/src/main/java/com/eactive/eai/adapter/http/dynamic/impl/HttpAdapterServiceStandard.java b/src/main/java/com/eactive/eai/adapter/http/dynamic/impl/HttpAdapterServiceStandard.java index 8bcd3f4..f41e532 100644 --- a/src/main/java/com/eactive/eai/adapter/http/dynamic/impl/HttpAdapterServiceStandard.java +++ b/src/main/java/com/eactive/eai/adapter/http/dynamic/impl/HttpAdapterServiceStandard.java @@ -184,7 +184,18 @@ public class HttpAdapterServiceStandard extends HttpAdapterServiceSupport prop.put(ALLOW_IP, httpProp.getProperty(ALLOW_IP, "")); String body = new String ( requestBytes,encode); - + + try { + Object root = JSONValue.parse(body); + if( root instanceof JSONArray ) { + JSONObject wrappedObject = new JSONObject(); + wrappedObject.put("KJB_ROOTLESS_ARRAY", root); + requestBytes = wrappedObject.toJSONString().getBytes(encode); + } + + }catch (Exception e) { + // ignore json이 아니기에 해줄것이 없음. + } // 로컬 서비스 호출 Object result = null; @@ -235,6 +246,17 @@ public class HttpAdapterServiceStandard extends HttpAdapterServiceSupport if (addData.length() > 0){ responseData = addData + responseData; } + + try { + Object root = JSONValue.parse(responseData); + if( root instanceof JSONObject ) { + JSONObject wrappedObject = (JSONObject) root; + responseData = wrappedObject.get("KJB_ROOTLESS_ARRAY").toString(); + } + + }catch (Exception e) { + // ignore json이 아니기에 해줄것이 없음. + } // 300응답에서 받은 Header정보 사용하기 위해 읽어옴. Map responsePropertyMap = new HashMap(); From bc27d706958b599fea8853c81c86ba673569e8f6 Mon Sep 17 00:00:00 2001 From: jaewohong Date: Mon, 12 Jan 2026 15:23:50 +0900 Subject: [PATCH 093/159] merge --- .../impl/HttpClient5AdapterServiceRest.java | 35 +++++++++++++++++-- 1 file changed, 33 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/eactive/eai/adapter/http/client/impl/HttpClient5AdapterServiceRest.java b/src/main/java/com/eactive/eai/adapter/http/client/impl/HttpClient5AdapterServiceRest.java index 1cce281..ad296ca 100644 --- a/src/main/java/com/eactive/eai/adapter/http/client/impl/HttpClient5AdapterServiceRest.java +++ b/src/main/java/com/eactive/eai/adapter/http/client/impl/HttpClient5AdapterServiceRest.java @@ -811,7 +811,17 @@ public class HttpClient5AdapterServiceRest extends HttpClient5AdapterServiceSupp } } //전문에서 추출한 httpHeader값 외 어댑터에서 최종적으로 적용되도록, - String httpSettingJsonStr = prop.getProperty( HTTP_HEADER_SETTING , "{}"); + String httpSettingJsonStr = prop.getProperty( HTTP_HEADER_SETTING ); + + if( StringUtils.isBlank(httpSettingJsonStr) ) + { + if( logger.isInfoEnabled() ) { + logger.info("HTTP_HEADER_SETTING value is not JSONObject Type, skip."); + } + + return; + } + try { JSONObject httpValues = (JSONObject) JSONValue.parse(httpSettingJsonStr); @@ -978,6 +988,16 @@ public class HttpClient5AdapterServiceRest extends HttpClient5AdapterServiceSupp return; } + if (eaiBody instanceof JSONObject) { + JSONObject jsonObject = (JSONObject) eaiBody; + if( jsonObject.containsKey("KJB_ROOTLESS_ARRAY") ) { + ContentType contentTypeObj = ContentType.create(contentType, charset); + JSONArray array = (JSONArray) jsonObject.get("KJB_ROOTLESS_ARRAY"); + StringEntity entity = new StringEntity(array.toJSONString(), contentTypeObj); + method.setEntity(entity); + return; + } + } if (StringUtils.contains(contentType, "application/x-www-form-urlencoded")) { if (eaiBody instanceof JSONObject) { @@ -1490,7 +1510,18 @@ public class HttpClient5AdapterServiceRest extends HttpClient5AdapterServiceSupp return null; } - return (JSONObject) JSONValue.parse(message); + Object obj = JSONValue.parse(message); + + if (obj instanceof JSONObject) { + return (JSONObject) obj; + } else if (obj instanceof JSONArray) { + // 배열일 경우 새로운 객체로 감싸서 반환 + JSONObject wrapper = new JSONObject(); + wrapper.put("KJB_ROOTLESS_ARRAY", obj); + return wrapper; + } + + return null; // 혹은 상황에 맞는 예외 처리 } private Document convertXmlDocument(String message) throws Exception { From 6b3d8bb4d73426fff17d707f68c767c0f15497a5 Mon Sep 17 00:00:00 2001 From: pksup Date: Tue, 13 Jan 2026 11:05:59 +0900 Subject: [PATCH 094/159] =?UTF-8?q?=EC=97=90=EB=9F=AC=20=EA=B2=80=EC=B6=9C?= =?UTF-8?q?=20=EB=A1=9C=EC=A7=81=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/eactive/eai/common/monitor/EAIServiceMonitor.java | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/src/main/java/com/eactive/eai/common/monitor/EAIServiceMonitor.java b/src/main/java/com/eactive/eai/common/monitor/EAIServiceMonitor.java index 1f0b834..baa1c70 100644 --- a/src/main/java/com/eactive/eai/common/monitor/EAIServiceMonitor.java +++ b/src/main/java/com/eactive/eai/common/monitor/EAIServiceMonitor.java @@ -382,11 +382,8 @@ public class EAIServiceMonitor implements Lifecycle { } //////////////////////////////////////////////////////////////////////////////////////////////////////////// - if (logPssSno == 400) { - statisticsMonitor.recordStatistics(msg); - } else if (logPssSno == 900) { - - } + // 실시간 통계 로직 추가 + statisticsMonitor.recordStatistics(msg); //////////////////////////////////////////////////////////////////////////////////////////////////////////// From 67719a68c4b55a512615198d276d149f388a666b Mon Sep 17 00:00:00 2001 From: cho Date: Tue, 13 Jan 2026 14:05:51 +0900 Subject: [PATCH 095/159] =?UTF-8?q?rootless=EC=A0=9C=EA=B1=B0=EB=A1=9C?= =?UTF-8?q?=EC=A7=81=20=EC=95=94=ED=98=B8=ED=99=94=EC=95=88=EB=90=98?= =?UTF-8?q?=EB=8D=98=20bugfix,?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../http/client/impl/HttpClient5AdapterServiceRest.java | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/src/main/java/com/eactive/eai/adapter/http/client/impl/HttpClient5AdapterServiceRest.java b/src/main/java/com/eactive/eai/adapter/http/client/impl/HttpClient5AdapterServiceRest.java index ad296ca..fd3d012 100644 --- a/src/main/java/com/eactive/eai/adapter/http/client/impl/HttpClient5AdapterServiceRest.java +++ b/src/main/java/com/eactive/eai/adapter/http/client/impl/HttpClient5AdapterServiceRest.java @@ -991,11 +991,7 @@ public class HttpClient5AdapterServiceRest extends HttpClient5AdapterServiceSupp if (eaiBody instanceof JSONObject) { JSONObject jsonObject = (JSONObject) eaiBody; if( jsonObject.containsKey("KJB_ROOTLESS_ARRAY") ) { - ContentType contentTypeObj = ContentType.create(contentType, charset); - JSONArray array = (JSONArray) jsonObject.get("KJB_ROOTLESS_ARRAY"); - StringEntity entity = new StringEntity(array.toJSONString(), contentTypeObj); - method.setEntity(entity); - return; + eaiBody = jsonObject.get("KJB_ROOTLESS_ARRAY"); } } From c6b3dc93c9d762af959e1d67c16af75e53fac107 Mon Sep 17 00:00:00 2001 From: jaewohong Date: Tue, 13 Jan 2026 14:08:19 +0900 Subject: [PATCH 096/159] merge --- .../http/client/impl/HttpClient5AdapterServiceRest.java | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/src/main/java/com/eactive/eai/adapter/http/client/impl/HttpClient5AdapterServiceRest.java b/src/main/java/com/eactive/eai/adapter/http/client/impl/HttpClient5AdapterServiceRest.java index ad296ca..fd3d012 100644 --- a/src/main/java/com/eactive/eai/adapter/http/client/impl/HttpClient5AdapterServiceRest.java +++ b/src/main/java/com/eactive/eai/adapter/http/client/impl/HttpClient5AdapterServiceRest.java @@ -991,11 +991,7 @@ public class HttpClient5AdapterServiceRest extends HttpClient5AdapterServiceSupp if (eaiBody instanceof JSONObject) { JSONObject jsonObject = (JSONObject) eaiBody; if( jsonObject.containsKey("KJB_ROOTLESS_ARRAY") ) { - ContentType contentTypeObj = ContentType.create(contentType, charset); - JSONArray array = (JSONArray) jsonObject.get("KJB_ROOTLESS_ARRAY"); - StringEntity entity = new StringEntity(array.toJSONString(), contentTypeObj); - method.setEntity(entity); - return; + eaiBody = jsonObject.get("KJB_ROOTLESS_ARRAY"); } } From 6d1e76ad50931d2b8c604d1ae58d28f4ae968d60 Mon Sep 17 00:00:00 2001 From: yunjy-hp Date: Wed, 14 Jan 2026 09:32:47 +0900 Subject: [PATCH 097/159] =?UTF-8?q?=ED=91=9C=EC=A4=80=EC=A0=84=EB=AC=B8=20?= =?UTF-8?q?=EC=98=A4=EB=A5=98=20=EC=B2=98=EB=A6=AC=20=EA=B4=80=EB=A0=A8=20?= =?UTF-8?q?=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../impl/HttpAdapterServiceStandard.java | 21 ++++++++++--------- .../eai/common/message/EAIMessage.java | 9 ++++---- .../eactive/eai/outbound/DefaultProcess.java | 4 ++++ 3 files changed, 20 insertions(+), 14 deletions(-) diff --git a/src/main/java/com/eactive/eai/adapter/http/dynamic/impl/HttpAdapterServiceStandard.java b/src/main/java/com/eactive/eai/adapter/http/dynamic/impl/HttpAdapterServiceStandard.java index f41e532..fa92a25 100644 --- a/src/main/java/com/eactive/eai/adapter/http/dynamic/impl/HttpAdapterServiceStandard.java +++ b/src/main/java/com/eactive/eai/adapter/http/dynamic/impl/HttpAdapterServiceStandard.java @@ -259,18 +259,19 @@ public class HttpAdapterServiceStandard extends HttpAdapterServiceSupport } // 300응답에서 받은 Header정보 사용하기 위해 읽어옴. - Map responsePropertyMap = new HashMap(); - responsePropertyMap = (Map) prop.get(OUTBOUND_PROPERTY_MAP); - Properties responseHeaders = (Properties)responsePropertyMap.get(OUTBOUND_RESPONSE_HEADERS); - Map responseHeaderMap = new TreeMap<>(String.CASE_INSENSITIVE_ORDER); - // Properties 내용을 모두 복사 - for (String name : responseHeaders.stringPropertyNames()) { - responseHeaderMap.put(name, responseHeaders.getProperty(name)); - } - String contentTytpe = responseHeaderMap.get("Content-Type"); + Map responsePropertyMap = (Map) prop.get(OUTBOUND_PROPERTY_MAP); + if(responsePropertyMap != null){ + Properties responseHeaders = (Properties)responsePropertyMap.get(OUTBOUND_RESPONSE_HEADERS); + Map responseHeaderMap = new TreeMap<>(String.CASE_INSENSITIVE_ORDER); + // Properties 내용을 모두 복사 + for (String name : responseHeaders.stringPropertyNames()) { + responseHeaderMap.put(name, responseHeaders.getProperty(name)); + } + String contentTytpe = responseHeaderMap.get("Content-Type"); + response.setContentType(contentTytpe); // 300응답에서 받은 Content-Type을 그대로 적용. + } // UI와 통신시(UTF-8) 변환오류로 ENCODE 제거 - response.setContentType(contentTytpe); // 300응답에서 받은 Content-Type을 그대로 적용. response.setCharacterEncoding(encode); response.getWriter().print(responseData); if (logger.isDebug()){ diff --git a/src/main/java/com/eactive/eai/common/message/EAIMessage.java b/src/main/java/com/eactive/eai/common/message/EAIMessage.java index dc25eed..b8345e0 100644 --- a/src/main/java/com/eactive/eai/common/message/EAIMessage.java +++ b/src/main/java/com/eactive/eai/common/message/EAIMessage.java @@ -185,6 +185,10 @@ public class EAIMessage implements EAIMessageKeys, Serializable, Comparable Date: Wed, 14 Jan 2026 13:34:16 +0900 Subject: [PATCH 098/159] =?UTF-8?q?=ED=91=9C=EC=A4=80=EC=A0=84=EB=AC=B8=20?= =?UTF-8?q?=EC=A1=B0=EA=B1=B4=20=EC=B2=98=EB=A6=AC=20=EA=B8=B0=EB=8A=A5=20?= =?UTF-8?q?OR=20=EC=B2=98=EB=A6=AC=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../eai/message/parser/FlatReader.java | 56 +++++++++++-------- 1 file changed, 34 insertions(+), 22 deletions(-) diff --git a/src/main/java/com/eactive/eai/message/parser/FlatReader.java b/src/main/java/com/eactive/eai/message/parser/FlatReader.java index ef2d2a6..7bcb93b 100644 --- a/src/main/java/com/eactive/eai/message/parser/FlatReader.java +++ b/src/main/java/com/eactive/eai/message/parser/FlatReader.java @@ -124,31 +124,28 @@ public class FlatReader implements StandardReader { if(refItemValue != null) refItemValue = refItemValue.trim(); /* - * 값의 경우의수 NR,ER,""(blank) - * ER이 아닐경우 표현하고 싶어서 ! 를 추가했음 - * 원칙으로는 NR을 넣었을경우에는 NR 이 있을경우에만 해당됨 - * !ER일경우에는 blank와 NR일 경우에 해당됨 + * 값의 경우의수 NM,EM,""(blank) + * ! : NOT 조건 (예: !EM → EM이 아닌 경우) + * | : OR 조건 (예: NM|EM → NM 또는 EM인 경우) + * !와 | 조합 가능 (예: !NM|EM → NM도 아니고 EM도 아닌 경우) */ String refValue = currentItem.getRefValue(); - if (refValue.startsWith("!")) { // 느낌표가 들어가면 다음에 나오는게 아닌경우 + boolean isNot = refValue.startsWith("!"); + if (isNot) { refValue = refValue.substring(1); - if (refValue.equals(refItemValue)) { - logger.warn("@GROUP name={} SKIPPED.", currentItem.getName()); - currentItem.setHidden(true); - break; - } else { - currentItem.setHidden(false); - } + } + boolean matched = matchRefValue(refValue, refItemValue); + if (isNot) { + matched = !matched; + } + + if (!matched) { + logger.warn("@GROUP name={} SKIPPED.", currentItem.getName()); + currentItem.setHidden(true); + break; } else { - if (!currentItem.getRefValue().equals(refItemValue)) { - logger.warn("@GROUP name={} SKIPPED.", currentItem.getName()); - currentItem.setHidden(true); - break; - } else { - currentItem.setHidden(false); - } - + currentItem.setHidden(false); } } childList = currentItem.getChildsList(); @@ -310,6 +307,21 @@ public class FlatReader implements StandardReader { } return refItemValue; } -// public static void main(String[] args) { -// } + + /** + * refValue와 refItemValue를 비교하여 일치 여부를 반환 + * | 구분자로 OR 조건 지원 (예: "NM|EM" → "NM" 또는 "EM"과 일치하면 true) + */ + private boolean matchRefValue(String refValue, String refItemValue) { + if (refValue.contains("|")) { + String[] values = refValue.split("\\|"); + for (String val : values) { + if (val.equals(refItemValue)) { + return true; + } + } + return false; + } + return refValue.equals(refItemValue); + } } \ No newline at end of file From aeca8c5a99ba9fae4734141388df26b468e8bc8c Mon Sep 17 00:00:00 2001 From: yunjy-hp Date: Wed, 14 Jan 2026 13:54:51 +0900 Subject: [PATCH 099/159] =?UTF-8?q?=ED=91=9C=EC=A4=80=EC=A0=84=EB=AC=B8=20?= =?UTF-8?q?=EC=98=A4=EB=A5=98=20=EC=9D=91=EB=8B=B5=20=EC=9C=A0=ED=98=95=20?= =?UTF-8?q?=EB=B3=80=EA=B2=BD=20[=EA=B4=91=EC=A3=BC=EC=9D=80=ED=96=89?= =?UTF-8?q?=EC=98=A4=EB=A5=98=EC=BD=94=EB=93=9C]=20=EC=98=A4=EB=A5=98?= =?UTF-8?q?=EB=A9=94=EC=8B=9C=EC=A7=80=20(=EC=98=A4=EB=A5=98=EC=84=A4?= =?UTF-8?q?=EB=AA=85)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/com/eactive/eai/outbound/DefaultProcess.java | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/main/java/com/eactive/eai/outbound/DefaultProcess.java b/src/main/java/com/eactive/eai/outbound/DefaultProcess.java index eb1342e..79005e1 100644 --- a/src/main/java/com/eactive/eai/outbound/DefaultProcess.java +++ b/src/main/java/com/eactive/eai/outbound/DefaultProcess.java @@ -676,9 +676,10 @@ public abstract class DefaultProcess extends Process { String errorResponseHandlerClass = AdapterPropManager.getInstance().getProperty(inboundAdapterVO.getPropGroupName(), "ERR_MSG_HANDLER"); if(StringUtils.isBlank(errorResponseHandlerClass)) { this.resEaiMsg.setRspErrCd("RECEAIINA001", false); -// String errorCode = mapper.getErrorCode(resStandardMessage); - String errorMsg = mapper.getErrorMsg(resStandardMessage); - this.resEaiMsg.setRspErrMsg(errorMsg); + String errorCode = mapper.getErrorCode(resStandardMessage); + String errorMsg = StringUtils.trim(mapper.getErrorMsg(resStandardMessage)); + String errorDesc = StringUtils.trim(resStandardMessage.findItemValue("Message.Msg_Body.OUTPUT_MSG_DESC")); + this.resEaiMsg.setRspErrMsg(String.format("[%s] %s (%s)", errorCode, errorMsg, errorDesc)); return; } From cafebb528f29bdeb2c3c6d4739b3935a38d41a04 Mon Sep 17 00:00:00 2001 From: jaewohong Date: Thu, 15 Jan 2026 09:10:42 +0900 Subject: [PATCH 100/159] =?UTF-8?q?=EA=B8=B0=EB=B3=B8=20format=20=EC=88=98?= =?UTF-8?q?=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/com/eactive/eai/common/util/MessageUtil.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/main/java/com/eactive/eai/common/util/MessageUtil.java b/src/main/java/com/eactive/eai/common/util/MessageUtil.java index 4304ff1..82e3980 100644 --- a/src/main/java/com/eactive/eai/common/util/MessageUtil.java +++ b/src/main/java/com/eactive/eai/common/util/MessageUtil.java @@ -34,7 +34,8 @@ import com.solab.iso8583.IsoMessage; public final class MessageUtil { static Logger logger = LoggerFactory.getLogger(MessageUtil.class); - public static final String ERROR_MESSAGE_DEFAULT_FORMAT = "{\"error\":{\"code\":\"%s\",\"message\":\"%s\"}}"; + //public static final String ERROR_MESSAGE_DEFAULT_FORMAT = "{\"error\":{\"code\":\"%s\",\"message\":\"%s\"}}"; + public static final String ERROR_MESSAGE_DEFAULT_FORMAT = "{\"code\":\"%s\",\"message\":\"%s\"}"; public static final String ERROR_CODE_AP_ERROR = "E.GW.AP_ERROR"; public static final String ERROR_CODE_AUTH_FAIL = "E.GW.AUTH_FAIL"; From ec6c5a8b34fd5c540d3f0bb2a2d5d3d2fb314259 Mon Sep 17 00:00:00 2001 From: cho Date: Thu, 15 Jan 2026 15:01:51 +0900 Subject: [PATCH 101/159] =?UTF-8?q?HMAC=ED=95=84=ED=84=B0=EB=A5=BC=20?= =?UTF-8?q?=EC=9C=84=ED=95=9C=20=EC=B2=98=EB=A6=AC=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../impl/HttpClient5AdapterServiceRest.java | 29 +++++++++---------- .../filter/HmacSha256VerifyFilterKjb.java | 22 ++++++++++++++ 2 files changed, 35 insertions(+), 16 deletions(-) diff --git a/src/main/java/com/eactive/eai/adapter/http/client/impl/HttpClient5AdapterServiceRest.java b/src/main/java/com/eactive/eai/adapter/http/client/impl/HttpClient5AdapterServiceRest.java index fd3d012..8bff18d 100644 --- a/src/main/java/com/eactive/eai/adapter/http/client/impl/HttpClient5AdapterServiceRest.java +++ b/src/main/java/com/eactive/eai/adapter/http/client/impl/HttpClient5AdapterServiceRest.java @@ -114,6 +114,8 @@ public class HttpClient5AdapterServiceRest extends HttpClient5AdapterServiceSupp public static final String HTTP_HEADER_SETTING = "HTTP_HEADER_SETTING"; public static final String PAYLOAD_PARAM_NAME_CLIENT_ID = "client_id"; // jwhong + + static final String KJB_ROOTLESS_ARRAY = "{ \"KJB_ROOTLESS_ARRAY\" : "; private boolean useAdapterToken; private boolean encryptResponseApply; @@ -612,7 +614,13 @@ public class HttpClient5AdapterServiceRest extends HttpClient5AdapterServiceSupp "RECV [" + new String(responseMessage, vo.getEncode()) + "]" + CommonLib.getDumpMessage(responseMessage)); } - + + String jsonStr = new String(responseMessage, vo.getEncode()); + + if ( jsonStr.trim().startsWith("[") ) { + jsonStr = KJB_ROOTLESS_ARRAY + jsonStr + "}"; + responseMessage = jsonStr.getBytes(vo.getEncode()); + } return assignResponseHeaders(method, responseMessage, headerGroupName, vo.getEncode(), messageType, relayResponseHeaderKeys, status, responseHeaderProp); @@ -1502,22 +1510,11 @@ public class HttpClient5AdapterServiceRest extends HttpClient5AdapterServiceSupp @SuppressWarnings("deprecation") private JSONObject parseJson(String message) throws Exception { - if (message == null || message.trim().isEmpty()) { - return null; - } + if (message == null) { + return null; + } - Object obj = JSONValue.parse(message); - - if (obj instanceof JSONObject) { - return (JSONObject) obj; - } else if (obj instanceof JSONArray) { - // 배열일 경우 새로운 객체로 감싸서 반환 - JSONObject wrapper = new JSONObject(); - wrapper.put("KJB_ROOTLESS_ARRAY", obj); - return wrapper; - } - - return null; // 혹은 상황에 맞는 예외 처리 + return (JSONObject) JSONValue.parse(message); } private Document convertXmlDocument(String message) throws Exception { diff --git a/src/main/java/com/eactive/eai/adapter/http/dynamic/filter/HmacSha256VerifyFilterKjb.java b/src/main/java/com/eactive/eai/adapter/http/dynamic/filter/HmacSha256VerifyFilterKjb.java index 4d73b4e..92bed3d 100644 --- a/src/main/java/com/eactive/eai/adapter/http/dynamic/filter/HmacSha256VerifyFilterKjb.java +++ b/src/main/java/com/eactive/eai/adapter/http/dynamic/filter/HmacSha256VerifyFilterKjb.java @@ -14,6 +14,8 @@ import javax.servlet.http.HttpServletResponse; //import org.apache.commons.net.util.Base64; import org.springframework.http.HttpStatus; import org.apache.commons.lang3.StringUtils; +import org.json.simple.JSONObject; +import org.json.simple.JSONValue; import com.eactive.eai.adapter.http.HttpMethodType; import com.eactive.eai.adapter.http.dynamic.HttpAdapterServiceKey; @@ -24,6 +26,8 @@ import com.eactive.eai.common.TransactionContextKeys; import com.eactive.eai.common.util.Logger; public class HmacSha256VerifyFilterKjb implements HttpAdapterFilter { + + static final String KJB_ROOTLESS_ARRAY = "{ \"KJB_ROOTLESS_ARRAY\" : "; static Logger logger = Logger.getLogger(Logger.LOGGER_ADAPTER); @@ -58,6 +62,14 @@ public class HmacSha256VerifyFilterKjb implements HttpAdapterFilter { String chkBody = inboundBody; String clientSecret = assignClientSecret(prop, request); + if (chkBody.startsWith(KJB_ROOTLESS_ARRAY)) { + chkBody = chkBody.substring(KJB_ROOTLESS_ARRAY.length()); + + if (chkBody.endsWith("}")) { + chkBody = chkBody.substring(0, chkBody.length() - 1); + } + } + String macUrl = calculateHMAC(chkUrl, clientSecret); String macBody = calculateHMAC(chkBody, clientSecret); @@ -145,6 +157,15 @@ public class HmacSha256VerifyFilterKjb implements HttpAdapterFilter { String outboundBody = (String) resultMessage; try { + + if (outboundBody.startsWith(KJB_ROOTLESS_ARRAY)) { + outboundBody = outboundBody.substring(KJB_ROOTLESS_ARRAY.length()); + + if (outboundBody.endsWith("}")) { + outboundBody = outboundBody.substring(0, outboundBody.length() - 1); + } + } + String clientSecret = assignClientSecret(prop, request); String macBody = calculateHMAC(outboundBody, clientSecret); @@ -157,5 +178,6 @@ public class HmacSha256VerifyFilterKjb implements HttpAdapterFilter { return resultMessage; } + } From d9543fa160f648cbf93114c2cd71c5d1c6e55367 Mon Sep 17 00:00:00 2001 From: jaewohong Date: Thu, 15 Jan 2026 15:08:09 +0900 Subject: [PATCH 102/159] merge --- .../impl/HttpClient5AdapterServiceRest.java | 95 ++++++------------- 1 file changed, 27 insertions(+), 68 deletions(-) diff --git a/src/main/java/com/eactive/eai/adapter/http/client/impl/HttpClient5AdapterServiceRest.java b/src/main/java/com/eactive/eai/adapter/http/client/impl/HttpClient5AdapterServiceRest.java index fd3d012..8cd4cf4 100644 --- a/src/main/java/com/eactive/eai/adapter/http/client/impl/HttpClient5AdapterServiceRest.java +++ b/src/main/java/com/eactive/eai/adapter/http/client/impl/HttpClient5AdapterServiceRest.java @@ -114,6 +114,8 @@ public class HttpClient5AdapterServiceRest extends HttpClient5AdapterServiceSupp public static final String HTTP_HEADER_SETTING = "HTTP_HEADER_SETTING"; public static final String PAYLOAD_PARAM_NAME_CLIENT_ID = "client_id"; // jwhong + + static final String KJB_ROOTLESS_ARRAY = "{ \"KJB_ROOTLESS_ARRAY\" : "; private boolean useAdapterToken; private boolean encryptResponseApply; @@ -161,7 +163,7 @@ public class HttpClient5AdapterServiceRest extends HttpClient5AdapterServiceSupp // 레이아웃 메시지 타입 REST URL 추출 시 활용. Default JSON String messageType = prop.getProperty("MESSAGE_TYPE", MessageType.JSON); String inboundMethod = tempProp.getProperty(HttpAdapterServiceKey.INBOUND_METHOD, "POST"); - String inboundToken = tempProp.getProperty(HttpAdapterServiceKey.INBOUND_TOKEN, ""); + //String inboundToken = tempProp.getProperty(HttpAdapterServiceKey.INBOUND_TOKEN, ""); //Outbound 요청에 대한 응답 메시지의 복호화 여부 결정위해 jwhong encryptResponseApply = StringUtils.equalsIgnoreCase(prop.getProperty("ENCRYPT_RESPONSE_APPLY", "N"), "Y"); @@ -378,7 +380,7 @@ public class HttpClient5AdapterServiceRest extends HttpClient5AdapterServiceSupp // assignPostBody(dataObject, contentType, vo.getEncode(), method); //assignPostBody(dataContent, contentType, vo.getEncode(), method); // jwhong commnet // KJBank API 추적정보를 Header에 제공. jwhong -// String inboundToken= assignRequestKJHeaders(method, prop, tempProp ); + String inboundToken= assignRequestKJHeaders(method, prop, tempProp ); assignPostBody(dataContent, contentType, vo.getEncode(), method, vo.getAdapterName(), auth, inboundToken, currentDate); break; default: @@ -396,9 +398,6 @@ public class HttpClient5AdapterServiceRest extends HttpClient5AdapterServiceSupp // Adapter 레벨 header 보다 data로 넘어온 httpHeader를 우선 적용(header명이 같다면 덮어씀) assignRequestHeaders(method, httpHeader, prop); - // KJBank API 추적정보를 Header에 제공. jwhong - //assignRequestKJHeaders(method, prop, tempProp ); - int status = -1; try { @@ -612,6 +611,13 @@ public class HttpClient5AdapterServiceRest extends HttpClient5AdapterServiceSupp "RECV [" + new String(responseMessage, vo.getEncode()) + "]" + CommonLib.getDumpMessage(responseMessage)); } + + String jsonStr = new String(responseMessage, vo.getEncode()); + + if ( jsonStr.trim().startsWith("[") ) { + jsonStr = KJB_ROOTLESS_ARRAY + jsonStr + "}"; + responseMessage = jsonStr.getBytes(vo.getEncode()); + } return assignResponseHeaders(method, responseMessage, headerGroupName, vo.getEncode(), messageType, @@ -866,6 +872,7 @@ public class HttpClient5AdapterServiceRest extends HttpClient5AdapterServiceSupp /* * KJBank Target System으로 요청 보낼때 header에 clientId(업체정보), APIM거래추적자(UUID), 최초 요청시간, guid 추가해서 보낸다. jwhong + * token 만 return 하는것으로 수정함 */ private String assignRequestKJHeaders(HttpUriRequestBase method, Properties prop, Properties tempProp){ @@ -912,51 +919,6 @@ public class HttpClient5AdapterServiceRest extends HttpClient5AdapterServiceSupp if (authorization != null && authorization.startsWith("Bearer ")) { jwtToken = authorization.substring(7); // "Bearer " 이후의 JWT만 추출 } - - - String headerRelay = PropManager.getInstance().getProperty("HEADER_RELAY_ADAPTER","adapter.name"); - Set values = new HashSet<>(Arrays.asList(headerRelay.split(","))); - String inputAdapter = tempProp.getProperty(HttpAdapterServiceKey.OUT_ADAPTER_GROUP_NAME, ""); - - String[] parts = inputAdapter.split("_"); - String target = parts[1]; // adapter name의 앞의 3자리 - String adapterName = target.substring(0, 3); - - if (values.contains(adapterName)) { - - /* 업체정보 */ - String clientId = JwtClientIdExtractor(jwtToken); - method.setHeader("clientId", clientId); - - /* APIM 거래추적자 */ - String uuid = tempProp.getProperty(TransactionContextKeys.TRANSACTION_UUID, ""); - method.setHeader("traceId", uuid); - - /* GUID */ - String guid = tempProp.getProperty(TransactionContextKeys.GUID, ""); - method.setHeader("guid", guid); - - /* 최초요청시간 */ - String receivedTimestamp = tempProp.getProperty(HttpAdapterServiceKey.INBOUND_REQUESTED_TIME, ""); - method.setHeader("receivedTimestamp", receivedTimestamp); - } - - - /* 업체정보 */ - //String clientId = JwtClientIdExtractor(jwtToken); - //method.setHeader("clientId", clientId); - - /* APIM 거래추적자 */ - //String uuid = tempProp.getProperty(TransactionContextKeys.TRANSACTION_UUID, ""); - //method.setHeader("traceId", uuid); - - /* GUID */ - //String guid = tempProp.getProperty(TransactionContextKeys.GUID, ""); - //method.setHeader("guid", guid); - - /* 최초요청시간 */ - //String receivedTimestamp = tempProp.getProperty(HttpAdapterServiceKey.INBOUND_REQUESTED_TIME, ""); - //method.setHeader("receivedTimestamp", receivedTimestamp); return jwtToken; } @@ -983,7 +945,7 @@ public class HttpClient5AdapterServiceRest extends HttpClient5AdapterServiceSupp } @SuppressWarnings("deprecation") - private void assignPostBody(Object eaiBody, String contentType, String charset, HttpUriRequestBase method, String adapterName, String niceAuth, String inboundToken, Date currentDate) { + private void assignPostBody(Object eaiBody, String contentType, String charset, HttpUriRequestBase method, String adapterName, String niceAuth, String inboundToken, Date currentDate) throws Exception { if (eaiBody == null) { return; } @@ -1023,7 +985,7 @@ public class HttpClient5AdapterServiceRest extends HttpClient5AdapterServiceSupp } // from here by jwhong - private String doOutboundPreFilter(Object eaiBody, String adapterName, String niceAuth, String inboundToken, Date currentDate) { + private String doOutboundPreFilter(Object eaiBody, String adapterName, String niceAuth, String inboundToken, Date currentDate) throws Exception { Properties properties = AdapterPropManager.getInstance().getProperties(adapterName); // jwhong String encryptAlgorithm = properties.getProperty("ENCRYPT_ALGORITHM",""); // jwhong @@ -1063,7 +1025,7 @@ public class HttpClient5AdapterServiceRest extends HttpClient5AdapterServiceSupp return responseMessage; } - private String doOutboundPreEncrypt(Object eaiBody, String encryptAlgorithm, String clientSecretKey, String encryptAES256Iv, String encryptAES256Key, String certPath, Date currentDate) { + private String doOutboundPreEncrypt(Object eaiBody, String encryptAlgorithm, String clientSecretKey, String encryptAES256Iv, String encryptAES256Key, String certPath, Date currentDate) throws Exception { String encryptedMessage = ""; String encryptedJsonKey = ""; @@ -1082,6 +1044,7 @@ public class HttpClient5AdapterServiceRest extends HttpClient5AdapterServiceSupp } catch (Exception e) { e.printStackTrace(); logger.error("HttpClientAdapterServiceRest] AES128 Encryption error=" + e.getMessage()); + throw new Exception("[HttpClient5AdapterServiceRest] Pre Encrypt Error : Encrypted Error, AES128 Key Invalid"); } break; case "AES128-TOGETHER": @@ -1091,6 +1054,7 @@ public class HttpClient5AdapterServiceRest extends HttpClient5AdapterServiceSupp } catch (Exception e) { e.printStackTrace(); logger.error("HttpClientAdapterServiceRest] AES128 Encryption error=" + e.getMessage()); + throw new Exception("[HttpClient5AdapterServiceRest] Pre Encrypt Error : Encrypted Error, AES128 Key Invalid"); } break; case "AES256": @@ -1100,6 +1064,7 @@ public class HttpClient5AdapterServiceRest extends HttpClient5AdapterServiceSupp } catch (Exception e) { e.printStackTrace(); logger.error("HttpClientAdapterServiceRest] AES256 Encryption error=" + e.getMessage()); + throw new Exception("[HttpClient5AdapterServiceRest] Pre Encrypt Error : Encrypted Error, AES256 Key Invalid"); } break; case "AES256-KAKAO": @@ -1108,6 +1073,7 @@ public class HttpClient5AdapterServiceRest extends HttpClient5AdapterServiceSupp } catch (Exception e) { e.printStackTrace(); logger.error("HttpClientAdapterServiceRest] AES256 Encryption error=" + e.getMessage()); + throw new Exception("[HttpClient5AdapterServiceRest] Pre Encrypt Error : Encrypted Error, AES256 Key Invalid"); } break; case "AES256-TOSS": @@ -1116,6 +1082,7 @@ public class HttpClient5AdapterServiceRest extends HttpClient5AdapterServiceSupp } catch (Exception e) { e.printStackTrace(); logger.error("HttpClientAdapterServiceRest] AES256 Encryption error=" + e.getMessage()); + throw new Exception("[HttpClient5AdapterServiceRest] Pre Encrypt Error : Encrypted Error, AES256 Key Invalid"); } break; case "AES256-NICEON": @@ -1127,6 +1094,7 @@ public class HttpClient5AdapterServiceRest extends HttpClient5AdapterServiceSupp } catch (Exception e) { e.printStackTrace(); logger.error("HttpClientAdapterServiceRest] AES256 Encryption error=" + e.getMessage()); + throw new Exception("[HttpClient5AdapterServiceRest] Pre Encrypt Error : Encrypted Error, AES256 Key Invalid"); } break; case "AES256GCM": @@ -1139,6 +1107,7 @@ public class HttpClient5AdapterServiceRest extends HttpClient5AdapterServiceSupp } catch (Exception e) { e.printStackTrace(); logger.error("HttpClientAdapterServiceRest] AES256GCM Encryption error=" + e.getMessage()); + throw new Exception("[HttpClient5AdapterServiceRest] Pre Encrypt Error : Encrypted Error, AES256GCM Key Invalid"); } break; case "ECDHESA256": @@ -1160,6 +1129,7 @@ public class HttpClient5AdapterServiceRest extends HttpClient5AdapterServiceSupp } catch (Exception e) { e.printStackTrace(); logger.error("HttpClientAdapterServiceRest] AES256GCM Encryption error=" + e.getMessage()); + throw new Exception("[HttpClient5AdapterServiceRest] Pre Encrypt Error : Encrypted Error, ECDHESA256 Key Invalid"); } break; default: @@ -1502,22 +1472,11 @@ public class HttpClient5AdapterServiceRest extends HttpClient5AdapterServiceSupp @SuppressWarnings("deprecation") private JSONObject parseJson(String message) throws Exception { - if (message == null || message.trim().isEmpty()) { - return null; - } + if (message == null) { + return null; + } - Object obj = JSONValue.parse(message); - - if (obj instanceof JSONObject) { - return (JSONObject) obj; - } else if (obj instanceof JSONArray) { - // 배열일 경우 새로운 객체로 감싸서 반환 - JSONObject wrapper = new JSONObject(); - wrapper.put("KJB_ROOTLESS_ARRAY", obj); - return wrapper; - } - - return null; // 혹은 상황에 맞는 예외 처리 + return (JSONObject) JSONValue.parse(message); } private Document convertXmlDocument(String message) throws Exception { From bf89cd34515445f4a38f67b87c134b9c20c4bbea Mon Sep 17 00:00:00 2001 From: jaewohong Date: Thu, 15 Jan 2026 15:17:15 +0900 Subject: [PATCH 103/159] =?UTF-8?q?=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../http/client/impl/HttpClient5AdapterServiceRest.java | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/main/java/com/eactive/eai/adapter/http/client/impl/HttpClient5AdapterServiceRest.java b/src/main/java/com/eactive/eai/adapter/http/client/impl/HttpClient5AdapterServiceRest.java index d2d2361..8cd4cf4 100644 --- a/src/main/java/com/eactive/eai/adapter/http/client/impl/HttpClient5AdapterServiceRest.java +++ b/src/main/java/com/eactive/eai/adapter/http/client/impl/HttpClient5AdapterServiceRest.java @@ -618,10 +618,7 @@ public class HttpClient5AdapterServiceRest extends HttpClient5AdapterServiceSupp jsonStr = KJB_ROOTLESS_ARRAY + jsonStr + "}"; responseMessage = jsonStr.getBytes(vo.getEncode()); } -<<<<<<< HEAD -======= ->>>>>>> branch 'jenkins_with_weblogic' of ssh://git@192.168.240.178:18081/eapim/elink-online-common.git return assignResponseHeaders(method, responseMessage, headerGroupName, vo.getEncode(), messageType, relayResponseHeaderKeys, status, responseHeaderProp); From 92f8e1500c635478cc0f57a751ab52c38d966ef4 Mon Sep 17 00:00:00 2001 From: cho Date: Thu, 15 Jan 2026 15:49:05 +0900 Subject: [PATCH 104/159] =?UTF-8?q?=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../filter/HmacSha256VerifyFilterKjb.java | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/src/main/java/com/eactive/eai/adapter/http/dynamic/filter/HmacSha256VerifyFilterKjb.java b/src/main/java/com/eactive/eai/adapter/http/dynamic/filter/HmacSha256VerifyFilterKjb.java index 92bed3d..182e48c 100644 --- a/src/main/java/com/eactive/eai/adapter/http/dynamic/filter/HmacSha256VerifyFilterKjb.java +++ b/src/main/java/com/eactive/eai/adapter/http/dynamic/filter/HmacSha256VerifyFilterKjb.java @@ -14,6 +14,7 @@ import javax.servlet.http.HttpServletResponse; //import org.apache.commons.net.util.Base64; import org.springframework.http.HttpStatus; import org.apache.commons.lang3.StringUtils; +import org.json.simple.JSONArray; import org.json.simple.JSONObject; import org.json.simple.JSONValue; @@ -157,18 +158,17 @@ public class HmacSha256VerifyFilterKjb implements HttpAdapterFilter { String outboundBody = (String) resultMessage; try { - - if (outboundBody.startsWith(KJB_ROOTLESS_ARRAY)) { - outboundBody = outboundBody.substring(KJB_ROOTLESS_ARRAY.length()); - - if (outboundBody.endsWith("}")) { - outboundBody = outboundBody.substring(0, outboundBody.length() - 1); - } + + Object root = JSONValue.parse(outboundBody); + + if (root instanceof JSONObject && ((JSONObject) root).containsKey("KJB_ROOTLESS_ARRAY")) { + JSONArray jsonArray = (JSONArray) ((JSONObject) root).get("KJB_ROOTLESS_ARRAY"); + outboundBody = jsonArray.toJSONString(); } - + String clientSecret = assignClientSecret(prop, request); String macBody = calculateHMAC(outboundBody, clientSecret); - + response.addHeader("x-obp-signature-body", macBody); response.addHeader("x-obp-partnercode", request.getHeader("x-obp-partnercode")); response.addHeader("x-obp-txid", prop.getProperty(TransactionContextKeys.TRANSACTION_UUID,"")); From 1c0501e8104d78066ba1d81b8c75f241f5efa6a8 Mon Sep 17 00:00:00 2001 From: jaewohong Date: Thu, 15 Jan 2026 16:00:04 +0900 Subject: [PATCH 105/159] =?UTF-8?q?=EB=A1=9C=EA=B7=B8=EB=A0=88=EB=B2=A8=20?= =?UTF-8?q?=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../adapter/http/client/impl/HttpClient5AdapterServiceRest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/com/eactive/eai/adapter/http/client/impl/HttpClient5AdapterServiceRest.java b/src/main/java/com/eactive/eai/adapter/http/client/impl/HttpClient5AdapterServiceRest.java index 8cd4cf4..bba2579 100644 --- a/src/main/java/com/eactive/eai/adapter/http/client/impl/HttpClient5AdapterServiceRest.java +++ b/src/main/java/com/eactive/eai/adapter/http/client/impl/HttpClient5AdapterServiceRest.java @@ -1021,7 +1021,7 @@ public class HttpClient5AdapterServiceRest extends HttpClient5AdapterServiceSupp // 여기서 SECRETY인지 nice-auth 인지 check 하여 clientSecret 값을 정하는 logic 추가하여 넘겨야한다. String responseMessage = doOutboundPreEncrypt(eaiBody, encryptAlgorithm, clientSecret, encryptAES256Iv, encryptAES256Key, certPath, currentDate); - logger.debug("outbound pre encrypte value is :"+responseMessage); + logger.info("outbound pre encrypte value is :"+responseMessage); return responseMessage; } From a3143a2d45264911b75618b75b09fe493effee9a Mon Sep 17 00:00:00 2001 From: cho Date: Fri, 16 Jan 2026 12:57:19 +0900 Subject: [PATCH 106/159] =?UTF-8?q?=ED=91=9C=EC=A4=80=EB=A9=94=EC=84=B8?= =?UTF-8?q?=EC=A7=80=20=EC=A0=81=EC=9A=A9.(=EC=9C=A4=EC=A4=80=EC=98=81?= =?UTF-8?q?=EC=B0=A8=EC=9E=A5=20=EB=B0=98=EC=98=81=EB=B3=B8)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../eactive/eai/outbound/SocketProcess.java | 25 +++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/src/main/java/com/eactive/eai/outbound/SocketProcess.java b/src/main/java/com/eactive/eai/outbound/SocketProcess.java index cb08133..8b360e0 100644 --- a/src/main/java/com/eactive/eai/outbound/SocketProcess.java +++ b/src/main/java/com/eactive/eai/outbound/SocketProcess.java @@ -36,6 +36,10 @@ import com.eactive.eai.message.StandardMessage; import com.eactive.eai.message.manager.StandardMessageManager; import com.eactive.eai.message.parser.StandardReader; import com.ext.eai.common.stdmessage.STDMessageKeys; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.ObjectMapper; +import org.apache.commons.lang3.StringUtils; public class SocketProcess extends DefaultProcess { static final long serialVersionUID = 1L; @@ -426,6 +430,8 @@ public class SocketProcess extends DefaultProcess { } if (com.eactive.eai.adapter.Keys.IF_STANDARD.equals(this.adptrMsgPtrnCd)) { + String restOption = this.reqEaiMsg.getCurrentSvcMsg().getRestOption(); + setStandardRouteInfo(restOption); AdapterManager adapterManager = AdapterManager.getInstance(); AdapterGroupVO adptGrpVO = adapterManager.getAdapterGroupVO(adapterGroupName); AdapterVO adptVO = null; @@ -680,6 +686,25 @@ public class SocketProcess extends DefaultProcess { } } + + protected void setStandardRouteInfo(String routeOption) throws JsonProcessingException { + if(StringUtils.isBlank(routeOption)) { + return ; + } + JsonNode rootNode = new ObjectMapper().readTree(routeOption); + JsonNode standardCommonFields = rootNode.get("standardCommonFields"); + + if (standardCommonFields != null && standardCommonFields.isObject()) { + standardCommonFields.fields().forEachRemaining(field -> { + String key = field.getKey(); + String value = field.getValue().asText(); + + StandardMessage standardMessage = this.reqEaiMsg.getStandardMessage(); + standardMessage.setData(key, value); + }); + } + } + @Override public void transControlHeaderTrnsformSinglesRes() throws Exception { From 8a641530a31c7df6e3db60ac4b7daa374e8667ec Mon Sep 17 00:00:00 2001 From: cho Date: Fri, 16 Jan 2026 13:47:08 +0900 Subject: [PATCH 107/159] =?UTF-8?q?null=20=EA=B0=92=20=EB=93=A4=EC=96=B4?= =?UTF-8?q?=EA=B0=80=EC=84=9C=20=EC=97=90=EB=9F=AC=EA=B0=80=EB=82=A8.=20?= =?UTF-8?q?=EC=9D=BC=EB=8B=A8=20=EA=B3=B5=EB=B0=B1=EC=B2=98=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/com/eactive/eai/common/monitor/MonitorChecker.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/com/eactive/eai/common/monitor/MonitorChecker.java b/src/main/java/com/eactive/eai/common/monitor/MonitorChecker.java index 486ef4f..54d76c2 100644 --- a/src/main/java/com/eactive/eai/common/monitor/MonitorChecker.java +++ b/src/main/java/com/eactive/eai/common/monitor/MonitorChecker.java @@ -310,7 +310,7 @@ public class MonitorChecker extends TimerTask logVo.setPrcssTtmVal((statVo.getSumOfprocessTime() - statVo.getPsvSumOfPssTime())); logVo.setPsvPrcssTtmVal(statVo.getPsvSumOfPssTime()); logVo.setTotalPrcssTtmVal(statVo.getSumOfprocessTime()); - + logVo.setKey(" "); if(IFType.AA.equals(ifType)) { if( rType == 'S') { totCnt = statVo.getCnt100() + statVo.getErr100(); From ce4f97fcc35e9252baba82edfe9c8ed086af2fd9 Mon Sep 17 00:00:00 2001 From: cho Date: Fri, 16 Jan 2026 17:32:28 +0900 Subject: [PATCH 108/159] =?UTF-8?q?=EC=A4=91=EB=B3=B5=EB=90=9C=20=EA=B0=92?= =?UTF-8?q?=EC=9D=84=20insert=20=EC=8B=9C=EB=8F=84=ED=95=A8,=20=EC=98=88?= =?UTF-8?q?=EC=99=B8=20=EB=A1=9C=EA=B9=85=20=EC=A0=9C=EA=B1=B0,=20?= =?UTF-8?q?=EC=B6=94=ED=9B=84=20=EC=9B=90=EC=9D=B8=20=ED=8C=8C=EC=95=85.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/com/eactive/eai/common/monitor/MonitorChecker.java | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/main/java/com/eactive/eai/common/monitor/MonitorChecker.java b/src/main/java/com/eactive/eai/common/monitor/MonitorChecker.java index 54d76c2..32cbde9 100644 --- a/src/main/java/com/eactive/eai/common/monitor/MonitorChecker.java +++ b/src/main/java/com/eactive/eai/common/monitor/MonitorChecker.java @@ -280,8 +280,7 @@ public class MonitorChecker extends TimerTask try { dao.addStaticTranCdLog(tmpLogVo); } catch(Exception e) { - if (logger.isError()) logger.error("MonitorVO.insertStaticCount TRANCODE ERROR. - " - + tmpLogVo.toString() + "\n" + e.getMessage(),e); + } } @@ -294,8 +293,7 @@ public class MonitorChecker extends TimerTask try { dao.addStaticAdapterLog(tmpLogVo); } catch(Exception e) { - if (logger.isError()) logger.error("MonitorVO.insertStaticCount ADAPTER ERROR. - " - + tmpLogVo.toString() + "\n" + e.getMessage(),e); + } } } From b51053c086429f4a32f1fccf4048a0901faa5c7a Mon Sep 17 00:00:00 2001 From: cho Date: Fri, 16 Jan 2026 17:35:34 +0900 Subject: [PATCH 109/159] =?UTF-8?q?=EC=98=88=EC=99=B8=EB=A1=9C=EA=B7=B8=20?= =?UTF-8?q?=EC=A0=9C=EA=B1=B0.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/com/eactive/eai/common/monitor/MonitorChecker.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/com/eactive/eai/common/monitor/MonitorChecker.java b/src/main/java/com/eactive/eai/common/monitor/MonitorChecker.java index 32cbde9..48acba6 100644 --- a/src/main/java/com/eactive/eai/common/monitor/MonitorChecker.java +++ b/src/main/java/com/eactive/eai/common/monitor/MonitorChecker.java @@ -246,7 +246,7 @@ public class MonitorChecker extends TimerTask try { dao.addStaticLog(logVo); } catch(Exception e) { - if (logger.isError()) logger.error("MonitorVO.insertStaticCount ERROR. - " + e.getMessage(),e); + //if (logger.isError()) logger.error("MonitorVO.insertStaticCount ERROR. - " + e.getMessage(),e); } } From b3e7cec3793b9dfa2f740a58befc4afd5b0b082c Mon Sep 17 00:00:00 2001 From: cho Date: Fri, 16 Jan 2026 17:46:05 +0900 Subject: [PATCH 110/159] =?UTF-8?q?=EC=97=90=EB=9F=AC=EB=A1=9C=EA=B7=B8=20?= =?UTF-8?q?=EC=A0=9C=EA=B1=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/com/eactive/eai/common/logger/EAILogDAO.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/main/java/com/eactive/eai/common/logger/EAILogDAO.java b/src/main/java/com/eactive/eai/common/logger/EAILogDAO.java index 08cc9b3..87fc0da 100644 --- a/src/main/java/com/eactive/eai/common/logger/EAILogDAO.java +++ b/src/main/java/com/eactive/eai/common/logger/EAILogDAO.java @@ -813,7 +813,7 @@ public class EAILogDAO { StatLog statLog = statLogMapper.toEntity(vo); statLogLogger.save(statLog); } catch (Exception e) { - logger.error("DB Logging[STATIC_LOG] Failed - " + vo.toString(), e); + //logger.error("DB Logging[STATIC_LOG] Failed - " + vo.toString(), e); throw new DAOException(ExceptionUtil.getErrorCode(e, "RECEAICLG003")); } } @@ -823,7 +823,7 @@ public class EAILogDAO { StatTranLog statTranLog = statTranLogMapper.toEntity(vo); statTranLogLogger.save(statTranLog); } catch (Exception e) { - logger.error("DB Logging[STATIC_TRANCD_LOG] Failed - " + vo.toString(), e); + //logger.error("DB Logging[STATIC_TRANCD_LOG] Failed - " + vo.toString(), e); throw new DAOException(ExceptionUtil.getErrorCode(e, "RECEAICLG003")); } } @@ -833,7 +833,7 @@ public class EAILogDAO { StatAdapterLog statAdapterLog = statAdapterLogMapper.toEntity(vo); statAdapterLogLogger.save(statAdapterLog); } catch (Exception e) { - logger.error("DB Logging[STATIC_ADAPTER_LOG] Failed - " + vo.toString(), e); + //logger.error("DB Logging[STATIC_ADAPTER_LOG] Failed - " + vo.toString(), e); throw new DAOException(ExceptionUtil.getErrorCode(e, "RECEAICLG003")); } } From a85c035e6d7e60cc9350185fc7739d675d5fe663 Mon Sep 17 00:00:00 2001 From: jaewohong Date: Mon, 19 Jan 2026 08:28:57 +0900 Subject: [PATCH 111/159] =?UTF-8?q?Async=EC=9B=90=EB=9E=98=EC=B2=98?= =?UTF-8?q?=EB=9F=BC=20return=20null=EB=A1=9C=20=EC=88=98=EC=A0=95?= =?UTF-8?q?=ED=95=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/eactive/eai/inbound/processor/RequestProcessor.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/main/java/com/eactive/eai/inbound/processor/RequestProcessor.java b/src/main/java/com/eactive/eai/inbound/processor/RequestProcessor.java index f2f06be..db60802 100644 --- a/src/main/java/com/eactive/eai/inbound/processor/RequestProcessor.java +++ b/src/main/java/com/eactive/eai/inbound/processor/RequestProcessor.java @@ -1365,7 +1365,10 @@ public class RequestProcessor extends RequestProcessorSupport { } } else { + // 비동기 거래, S-A의 응답거래시에는 NULL을 리턴 return null; + // S-A 에서 Sync 100에 대한 ack 응답시 http header 에 traceId 에 uuid를 넣어달라고 해서.. + //return vo.getUuid(); } } From 0b5033daa355af98e70803dcea9599a542855ded Mon Sep 17 00:00:00 2001 From: jaewohong Date: Mon, 19 Jan 2026 12:03:55 +0900 Subject: [PATCH 112/159] =?UTF-8?q?exception=20message=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../eactive/eai/adapter/http/dynamic/filter/ApiAuthFilter.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/com/eactive/eai/adapter/http/dynamic/filter/ApiAuthFilter.java b/src/main/java/com/eactive/eai/adapter/http/dynamic/filter/ApiAuthFilter.java index 590da9b..7358ba4 100644 --- a/src/main/java/com/eactive/eai/adapter/http/dynamic/filter/ApiAuthFilter.java +++ b/src/main/java/com/eactive/eai/adapter/http/dynamic/filter/ApiAuthFilter.java @@ -159,7 +159,7 @@ public class ApiAuthFilter implements HttpAdapterFilter { throw e; } catch (Exception e) { logger.error(e.getMessage()); - throw new JwtAuthException(ERROR_AUTHENTICATION_FAIL, "Token invalid"); + throw new JwtAuthException(ERROR_AUTHENTICATION_FAIL, "Token unknown Error", e); } break; case "api_key": From 7bebc5725c67abdfe4e171bce64e367f38bb255b Mon Sep 17 00:00:00 2001 From: jaewohong Date: Mon, 19 Jan 2026 16:42:26 +0900 Subject: [PATCH 113/159] =?UTF-8?q?x-loan-token=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/com/eactive/eai/common/TransactionContextKeys.java | 1 + src/main/java/com/eactive/eai/outbound/RESTProcess.java | 3 ++- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/src/main/java/com/eactive/eai/common/TransactionContextKeys.java b/src/main/java/com/eactive/eai/common/TransactionContextKeys.java index 89c19d7..2b6d870 100644 --- a/src/main/java/com/eactive/eai/common/TransactionContextKeys.java +++ b/src/main/java/com/eactive/eai/common/TransactionContextKeys.java @@ -8,4 +8,5 @@ public interface TransactionContextKeys { public static final String GUID = "GUID"; public static final String INTERFACE_ID = "INTERFACE_ID"; public static final String TRANSACTION_UUID = "TRANSACTION_UUID"; + public static final String X_LOAN_TOKEN = "X-LOAN-TOKEN"; } diff --git a/src/main/java/com/eactive/eai/outbound/RESTProcess.java b/src/main/java/com/eactive/eai/outbound/RESTProcess.java index 5d364ee..f943a57 100644 --- a/src/main/java/com/eactive/eai/outbound/RESTProcess.java +++ b/src/main/java/com/eactive/eai/outbound/RESTProcess.java @@ -444,7 +444,8 @@ public class RESTProcess extends HTTPProcess { PropertiesUtil.copyPropertyIfPresent(this.callProp, this.tempProp, HttpAdapterServiceKey.GUID); // jwhong PropertiesUtil.copyPropertyIfPresent(this.callProp, this.tempProp, HttpAdapterServiceKey.INBOUND_TOKEN); // jwhong PropertiesUtil.copyPropertyIfPresent(this.callProp, this.tempProp, HttpAdapterServiceSupport.PROPERTIES_NAME_CLIENT_ID); // jwhong - + PropertiesUtil.copyPropertyIfPresent(this.callProp, this.tempProp, TransactionContextKeys.X_LOAN_TOKEN); + String svcName = getServiceId(this.reqEaiMsg); if (svcName == null) { svcName = ""; From 65860f78d1bca512727c4a72e613c558bf7e8272 Mon Sep 17 00:00:00 2001 From: cho Date: Tue, 20 Jan 2026 10:49:10 +0900 Subject: [PATCH 114/159] =?UTF-8?q?httpTimeout=20=EA=B8=B0=EB=B3=B8?= =?UTF-8?q?=EA=B0=92=20-1=20->=2010000=20(10sec)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../adapter/http/client/HttpClient5AdapterServiceSupport.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/com/eactive/eai/adapter/http/client/HttpClient5AdapterServiceSupport.java b/src/main/java/com/eactive/eai/adapter/http/client/HttpClient5AdapterServiceSupport.java index ab1dc80..a212277 100644 --- a/src/main/java/com/eactive/eai/adapter/http/client/HttpClient5AdapterServiceSupport.java +++ b/src/main/java/com/eactive/eai/adapter/http/client/HttpClient5AdapterServiceSupport.java @@ -78,7 +78,7 @@ public abstract class HttpClient5AdapterServiceSupport implements HttpClientAdap String trustStorePassword = null; int connectionTimeout = 0; - int timeout = -1; + int timeout = 10000; // 기존값 -1 인데, 의미가 없음, -1로 설정될경우 client에서 에러남. int traceLevel = 0; long slowTranTime = 2000L; From 333f145537b6230150e8c413918450193b59e935 Mon Sep 17 00:00:00 2001 From: cho Date: Tue, 20 Jan 2026 15:10:23 +0900 Subject: [PATCH 115/159] =?UTF-8?q?Async=20=EC=9D=91=EB=8B=B5=EC=8B=9C,=20?= =?UTF-8?q?500.=20=EB=B3=B4=EB=82=B4=EA=B8=B0=EC=A0=84=20=EC=98=88?= =?UTF-8?q?=EC=99=B8=EC=8B=9C=20900=EC=9C=BC=EB=A1=9C=20=EB=A1=9C=EA=B9=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/com/eactive/eai/outbound/DefaultProcess.java | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/main/java/com/eactive/eai/outbound/DefaultProcess.java b/src/main/java/com/eactive/eai/outbound/DefaultProcess.java index 79005e1..a3f5cb9 100644 --- a/src/main/java/com/eactive/eai/outbound/DefaultProcess.java +++ b/src/main/java/com/eactive/eai/outbound/DefaultProcess.java @@ -257,7 +257,11 @@ public abstract class DefaultProcess extends Process { if(isAsyncSyncPattern()){ StandardMessage standardMessage = this.resEaiMsg.getStandardMessage(); standardMessage.setBizData(this.resObject, this.outboundCharset); - this.logPssSno = 500; + if ( StringUtils.isNotBlank(resEaiMsg.getRspErrCd()) ) { + this.logPssSno = 900; + } else { + this.logPssSno = 500; + } logSenderCtrlSendRes(); } // SA From 4b64cfab139687c7a5612a8e0f47313cc734ef63 Mon Sep 17 00:00:00 2001 From: cho Date: Tue, 20 Jan 2026 15:53:30 +0900 Subject: [PATCH 116/159] =?UTF-8?q?headers.length=20=3D=200=20=EC=9D=BC?= =?UTF-8?q?=EB=95=8C,=20NullpointException=20=EC=98=88=EC=99=B8=20?= =?UTF-8?q?=EC=B2=98=EB=A6=AC.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../eactive/eai/common/util/HttpAdapterExtraLogUtil.java | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/main/java/com/eactive/eai/common/util/HttpAdapterExtraLogUtil.java b/src/main/java/com/eactive/eai/common/util/HttpAdapterExtraLogUtil.java index 75f405c..40913c5 100644 --- a/src/main/java/com/eactive/eai/common/util/HttpAdapterExtraLogUtil.java +++ b/src/main/java/com/eactive/eai/common/util/HttpAdapterExtraLogUtil.java @@ -1,5 +1,6 @@ package com.eactive.eai.common.util; +import java.util.ArrayList; import java.util.Arrays; import java.util.HashSet; import java.util.List; @@ -34,7 +35,13 @@ public class HttpAdapterExtraLogUtil { } public static void insertHttpAdapterExtraLog(String guid, int serviceProcessNumber, String adapterGroupName, String adapterName, Header[] headers, String url, String httpMethod, int httpStatus){ - List headerVoList = convertHeaderToListOfHttpAdapterExtraHeaderVo(headers); + + List headerVoList = new ArrayList(); + + if ( headers != null && headers.length != 0 ) { + headerVoList = convertHeaderToListOfHttpAdapterExtraHeaderVo(headers); + } + insertHttpAdapterExtraLog(guid, serviceProcessNumber, adapterGroupName, adapterName, headerVoList, url, httpMethod, httpStatus); } From bb91b986fe72a15df3edc0899362901cb8464988 Mon Sep 17 00:00:00 2001 From: cho Date: Wed, 21 Jan 2026 16:26:21 +0900 Subject: [PATCH 117/159] =?UTF-8?q?=EC=97=90=EB=9F=AC=EC=B2=98=EB=A6=AC=20?= =?UTF-8?q?=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/com/eactive/eai/outbound/DefaultProcess.java | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/eactive/eai/outbound/DefaultProcess.java b/src/main/java/com/eactive/eai/outbound/DefaultProcess.java index a3f5cb9..71693d3 100644 --- a/src/main/java/com/eactive/eai/outbound/DefaultProcess.java +++ b/src/main/java/com/eactive/eai/outbound/DefaultProcess.java @@ -257,7 +257,9 @@ public abstract class DefaultProcess extends Process { if(isAsyncSyncPattern()){ StandardMessage standardMessage = this.resEaiMsg.getStandardMessage(); standardMessage.setBizData(this.resObject, this.outboundCharset); - if ( StringUtils.isNotBlank(resEaiMsg.getRspErrCd()) ) { + + if ("E".equals(resEaiMsg.getRspErrCd().substring(1, 2)) + || "F".equals(resEaiMsg.getRspErrCd().substring(1, 2))) { this.logPssSno = 900; } else { this.logPssSno = 500; @@ -493,7 +495,8 @@ public abstract class DefaultProcess extends Process { ServiceMessage secondService = this.reqEaiMsg.getSvcMsg(1); if (EAIMessageKeys.ASYNC_SVC.equals(this.reqEaiMsg.getSvcTsmtUsgTp()) && EAIMessageKeys.SYNC_SVC.equals(firstService.getPsvItfTp()) - && EAIMessageKeys.ASYNC_SVC.equals(secondService.getPsvItfTp())){ + && EAIMessageKeys.ASYNC_SVC.equals(secondService.getPsvItfTp()) + && this.reqEaiMsg.getCurrentSvcMsg() == secondService){ return true; } return false; From c898b54cde3d7b4d4bc3e419e78b6ced06014f2f Mon Sep 17 00:00:00 2001 From: cho Date: Thu, 22 Jan 2026 17:26:46 +0900 Subject: [PATCH 118/159] =?UTF-8?q?JWT=ED=86=A0=ED=81=B0=20verify=20?= =?UTF-8?q?=EC=A4=91=EC=97=90=20Unsupported=20JWS=20algorithm=20=EC=97=90?= =?UTF-8?q?=EB=9F=AC=EC=8B=9C,=20=EC=9E=98=EB=AA=BB=EB=90=9C=20=ED=86=A0?= =?UTF-8?q?=ED=81=B0=EC=9D=B4=EB=AF=80=EB=A1=9C=20=EB=98=91=EA=B0=99?= =?UTF-8?q?=EC=9D=B4=20invaild=20=EC=98=88=EC=99=B8=EC=B2=98=EB=A6=AC.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../eai/adapter/http/dynamic/filter/ApiAuthFilter.java | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/main/java/com/eactive/eai/adapter/http/dynamic/filter/ApiAuthFilter.java b/src/main/java/com/eactive/eai/adapter/http/dynamic/filter/ApiAuthFilter.java index 7358ba4..c41ee8a 100644 --- a/src/main/java/com/eactive/eai/adapter/http/dynamic/filter/ApiAuthFilter.java +++ b/src/main/java/com/eactive/eai/adapter/http/dynamic/filter/ApiAuthFilter.java @@ -123,10 +123,14 @@ public class ApiAuthFilter implements HttpAdapterFilter { } else if (new Date().after(signedJWT.getJWTClaimsSet().getExpirationTime())) { throw new JwtAuthException(ERROR_TOKEN_EXPIRED, "Access token expired"); } - - if (!signedJWT.verify(jwsVerifier)) { - throw new JwtAuthException(ERROR_AUTHENTICATION_FAIL, "Token invalid"); + try { + if (!signedJWT.verify(jwsVerifier)) { + throw new JwtAuthException(ERROR_AUTHENTICATION_FAIL, "Token invalid"); + } + }catch (Exception e) { + throw new JwtAuthException(ERROR_AUTHENTICATION_FAIL, "Token invalid", e); } + OAuth2Manager manager = OAuth2Manager.getInstance(); HashSet scopeSet = manager.getApiScopeMap().get(apiId); From 1c139be54eccc9379a2fb984bfdeed7b8fb75fa9 Mon Sep 17 00:00:00 2001 From: cho Date: Tue, 27 Jan 2026 14:52:50 +0900 Subject: [PATCH 119/159] =?UTF-8?q?=EA=B3=A0=EA=B0=9D=EC=9A=94=EA=B5=AC?= =?UTF-8?q?=EC=82=AC=ED=95=AD=20=EC=9D=B8=ED=84=B0=ED=8E=98=EC=9D=B4?= =?UTF-8?q?=EC=8A=A4=20TIMEOUT=EB=A7=8C=20=EC=82=AC=EC=9A=A9=ED=95=98?= =?UTF-8?q?=EB=8F=84=EB=A1=9D=20=EC=88=98=EC=A0=95=20(HTTP=5FTIMEOUT=20?= =?UTF-8?q?=EB=AF=B8=EC=82=AC=EC=9A=A9.=20=EB=8B=A8,=20token=EA=B1=B0?= =?UTF-8?q?=EB=9E=98(=EC=9D=B8=ED=84=B0=ED=8E=98=EC=9D=B4=EC=8A=A4=20?= =?UTF-8?q?=EC=A1=B4=EC=9E=AC=ED=95=98=EC=A7=80=EC=95=8A=EC=9D=8C)=20?= =?UTF-8?q?=EB=B0=9C=EA=B8=89=EC=9D=80=20=EC=96=B4=EB=8C=91=ED=84=B0=20?= =?UTF-8?q?=ED=94=84=EB=A1=9C=ED=8D=BC=ED=8B=B0=EA=B0=92=20=EC=82=AC?= =?UTF-8?q?=EC=9A=A9.)=20=ED=83=80=EC=9E=84=EC=95=84=EC=9B=83=20=EA=B8=B0?= =?UTF-8?q?=EC=A4=80=EC=9D=84=20=EB=8B=A8=EC=9D=BC=ED=99=94=ED=95=98?= =?UTF-8?q?=EC=97=AC=20=EC=9A=B4=EC=98=81=20=ED=98=BC=EB=9E=80=20=EB=B0=A9?= =?UTF-8?q?=EC=A7=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../http/client/HttpClient5AdapterServiceSupport.java | 8 +------- .../http/client/HttpClientAdapterServiceSupport.java | 3 ++- src/main/java/com/eactive/eai/outbound/HTTPProcess.java | 5 ++++- src/main/java/com/eactive/eai/outbound/RESTProcess.java | 5 ++++- src/main/java/com/eactive/eai/outbound/SocketProcess.java | 7 ++++--- 5 files changed, 15 insertions(+), 13 deletions(-) diff --git a/src/main/java/com/eactive/eai/adapter/http/client/HttpClient5AdapterServiceSupport.java b/src/main/java/com/eactive/eai/adapter/http/client/HttpClient5AdapterServiceSupport.java index a212277..b81600f 100644 --- a/src/main/java/com/eactive/eai/adapter/http/client/HttpClient5AdapterServiceSupport.java +++ b/src/main/java/com/eactive/eai/adapter/http/client/HttpClient5AdapterServiceSupport.java @@ -99,7 +99,7 @@ public abstract class HttpClient5AdapterServiceSupport implements HttpClientAdap adapterHeader = prop.getProperty(ADAPTER_HEADER, ""); String traceLevelTemp = prop.getProperty(TRACE_LEVEL, "0"); - String timeoutTemp = prop.getProperty(HTTP_TIME_OUT, "0"); + String timeoutTemp = "10000"; // 타임아웃 기준이 불명확해 운영 혼란 발생 → 인터페이스 TIMEOUT으로 단일화 useMtls = StringUtils.equalsIgnoreCase(prop.getProperty(HttpClientAdapterServiceKey.USE_MTLS),"Y"); keyStorePath = prop.getProperty(HttpClientAdapterServiceKey.KEYSTORE_PATH); @@ -509,12 +509,6 @@ public abstract class HttpClient5AdapterServiceSupport implements HttpClientAdap requestConfigBuilder.setResponseTimeout(vo.getTimeout(), TimeUnit.MILLISECONDS); } - /* - if (HTTP_VERSION_1_1.equals(vo.getHttpVersion())) { - method.addHeader("Connection", "close"); - } - */ - org.apache.hc.core5.http.HttpVersion httpVersion ; if (HTTP_VERSION_1_0.equals(vo.getHttpVersion())) { httpVersion = org.apache.hc.core5.http.HttpVersion.HTTP_1_0; diff --git a/src/main/java/com/eactive/eai/adapter/http/client/HttpClientAdapterServiceSupport.java b/src/main/java/com/eactive/eai/adapter/http/client/HttpClientAdapterServiceSupport.java index 941a92b..5829cb0 100644 --- a/src/main/java/com/eactive/eai/adapter/http/client/HttpClientAdapterServiceSupport.java +++ b/src/main/java/com/eactive/eai/adapter/http/client/HttpClientAdapterServiceSupport.java @@ -83,7 +83,7 @@ public abstract class HttpClientAdapterServiceSupport implements HttpClientAdapt adapterHeader = prop.getProperty(ADAPTER_HEADER, ""); String traceLevelTemp = prop.getProperty(TRACE_LEVEL, "0"); - String timeoutTemp = prop.getProperty(HTTP_TIME_OUT); + String timeoutTemp = "10000";// 타임아웃 기준이 불명확해 운영 혼란 발생 → 인터페이스 TIMEOUT으로 단일화 useMtls = StringUtils.equalsIgnoreCase(prop.getProperty(HttpClientAdapterServiceKey.USE_MTLS), "Y"); keyStorePath = prop.getProperty(HttpClientAdapterServiceKey.KEYSTORE_PATH); @@ -116,6 +116,7 @@ public abstract class HttpClientAdapterServiceSupport implements HttpClientAdapt try { connectionTimeout = Integer.parseInt(connectionTimeoutTemp); } catch (Exception e) { + connectionTimeout = 3000; logger.debug("HttpClientAdapterSupport] connectionTimeoutTemp not int"); } try { diff --git a/src/main/java/com/eactive/eai/outbound/HTTPProcess.java b/src/main/java/com/eactive/eai/outbound/HTTPProcess.java index dd2c8ac..da67208 100644 --- a/src/main/java/com/eactive/eai/outbound/HTTPProcess.java +++ b/src/main/java/com/eactive/eai/outbound/HTTPProcess.java @@ -54,7 +54,10 @@ public class HTTPProcess extends DefaultProcess { protected final ObjectMapper objectMapper = new ObjectMapper().setSerializationInclusion(JsonInclude.Include.NON_NULL); public void outboundCtrlCallServiceAsync() throws Exception { - // async에서는 인터페이스 값을 설정하지 않고 Adapter의 타임아웃을 쓰기위해서 설정하지 않음 + // 인터페이스에 셋팅된 타임아웃설정 + int iTimeoutValue = getTimeoutCodeToValue(); + this.timeout = iTimeoutValue * 1000; + this.tempProp.put(INTERFACE_TIME_OUT, "" + this.timeout); try { this.tempProp.put(HttpClientAdapterServiceKey.LOG_PROCESS_NO, this.logPssSno); this.resObject = HttpSender.callService(this.adapterGroupName, this.outboundProp, this.reqObject, this.tempProp); diff --git a/src/main/java/com/eactive/eai/outbound/RESTProcess.java b/src/main/java/com/eactive/eai/outbound/RESTProcess.java index f943a57..29bb60a 100644 --- a/src/main/java/com/eactive/eai/outbound/RESTProcess.java +++ b/src/main/java/com/eactive/eai/outbound/RESTProcess.java @@ -50,7 +50,10 @@ public class RESTProcess extends HTTPProcess { static final long serialVersionUID = 1L; public void outboundCtrlCallServiceAsync() throws Exception { - // async에서는 인터페이스 값을 설정하지 않고 Adapter의 타임아웃을 쓰기위해서 설정하지 않음 + // 인터페이스에 셋팅된 타임아웃설정 + int iTimeoutValue = getTimeoutCodeToValue(); + this.timeout = iTimeoutValue * 1000; + this.tempProp.put(INTERFACE_TIME_OUT, "" + this.timeout); try { this.tempProp.put(HttpClientAdapterServiceKey.LOG_PROCESS_NO, this.logPssSno); this.resObject = HttpSender.callService(this.adapterGroupName, this.outboundProp, this.reqObject, diff --git a/src/main/java/com/eactive/eai/outbound/SocketProcess.java b/src/main/java/com/eactive/eai/outbound/SocketProcess.java index 8b360e0..d3912f7 100644 --- a/src/main/java/com/eactive/eai/outbound/SocketProcess.java +++ b/src/main/java/com/eactive/eai/outbound/SocketProcess.java @@ -126,9 +126,10 @@ public class SocketProcess extends DefaultProcess { } public void outboundCtrlCallServiceAsync() throws Exception { - /** - * async에서는 인터페이스 값을 설정하지 않고 Adapter의 타임아웃을 쓰기위해서 설정하지 않음 - */ + // 인터페이스에 셋팅된 타임아웃설정 + int iTimeoutValue = getTimeoutCodeToValue(); + this.timeout = iTimeoutValue * 1000; + this.tempProp.put(INTERFACE_TIME_OUT, "" + this.timeout); try { this.resObject = SocketSender.callService(this.adapterGroupName, this.outboundProp, this.reqObject, this.tempProp); From fdd9d576f02616d2cc1fd21f3691bcee6ffca225 Mon Sep 17 00:00:00 2001 From: cho Date: Wed, 28 Jan 2026 14:16:45 +0900 Subject: [PATCH 120/159] =?UTF-8?q?=EC=9D=91=EB=8B=B5=20=ED=91=9C=EC=A4=80?= =?UTF-8?q?=EB=A9=94=EC=84=B8=EC=A7=80(400)=20=EB=A9=94=EC=84=B8=EC=A7=80?= =?UTF-8?q?=EB=B6=80=20=EC=A0=9C=EA=B1=B0=ED=95=98=EA=B3=A0=20=EB=82=98?= =?UTF-8?q?=EA=B0=80=EB=8F=84=EB=A1=9D,=20=EC=9E=84=EC=8B=9C=EC=BD=94?= =?UTF-8?q?=EB=93=9C=20=EA=B3=84=EC=A0=95=EA=B3=84=EC=AA=BD=20=ED=85=8C?= =?UTF-8?q?=EC=8A=A4=ED=8A=B8=EC=9A=94=EC=B2=AD.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../eactive/eai/outbound/SocketProcess.java | 26 ++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) diff --git a/src/main/java/com/eactive/eai/outbound/SocketProcess.java b/src/main/java/com/eactive/eai/outbound/SocketProcess.java index d3912f7..08c8af5 100644 --- a/src/main/java/com/eactive/eai/outbound/SocketProcess.java +++ b/src/main/java/com/eactive/eai/outbound/SocketProcess.java @@ -9,7 +9,6 @@ import com.eactive.eai.adapter.AdapterVO; import com.eactive.eai.adapter.socket2.EAIConnectException; import com.eactive.eai.adapter.socket2.EAINoAvailableConnectionException; import com.eactive.eai.adapter.socket2.EAITimeoutException; -import com.eactive.eai.adapter.socket2.SocketAdapterFacade; import com.eactive.eai.common.EAIKeys; import com.eactive.eai.common.exception.ExceptionUtil; import com.eactive.eai.common.header.HeaderAction; @@ -32,6 +31,7 @@ import com.eactive.eai.control.SocketSender; import com.eactive.eai.control.Transform; import com.eactive.eai.env.ElinkConfig; import com.eactive.eai.inbound.processor.Processor; +import com.eactive.eai.message.StandardItem; import com.eactive.eai.message.StandardMessage; import com.eactive.eai.message.manager.StandardMessageManager; import com.eactive.eai.message.parser.StandardReader; @@ -481,6 +481,30 @@ public class SocketProcess extends DefaultProcess { } } } + + @Override + protected void setRcvLogInfoExtend() throws Exception { + + super.setRcvLogInfoExtend(); + + final String MESSAGE_PART = "Message"; + final String MESSAGE_PART_HEADER_PART = "Message.Msg_Header"; + final String MESSAGE_PART_BODY_PART = "Message.Msg_Body"; + + if (!com.eactive.eai.adapter.Keys.IF_STANDARD.equals(this.adptrMsgPtrnCd)) { + + StandardMessage standardMessage = this.resEaiMsg.getStandardMessage(); + + StandardItem messagePart = standardMessage.findItem(MESSAGE_PART); + messagePart.setHidden(true); + messagePart.setSize(0); + + StandardItem messageHeaderPart = standardMessage.findItem(MESSAGE_PART_HEADER_PART); + messageHeaderPart.setSize(0); + StandardItem messageBodyPart = standardMessage.findItem(MESSAGE_PART_BODY_PART); + messageBodyPart.setSize(0); + } + } public void getTopicProperty() throws Exception { PropManager propManager = PropManager.getInstance(); From a85f1279d266a0a16271ce2b27603f08eaaa3c46 Mon Sep 17 00:00:00 2001 From: cho Date: Wed, 28 Jan 2026 14:24:50 +0900 Subject: [PATCH 121/159] =?UTF-8?q?Revert=20"=EC=9D=91=EB=8B=B5=20?= =?UTF-8?q?=ED=91=9C=EC=A4=80=EB=A9=94=EC=84=B8=EC=A7=80(400)=20=EB=A9=94?= =?UTF-8?q?=EC=84=B8=EC=A7=80=EB=B6=80=20=EC=A0=9C=EA=B1=B0=ED=95=98?= =?UTF-8?q?=EA=B3=A0=20=EB=82=98=EA=B0=80=EB=8F=84=EB=A1=9D,=20=EC=9E=84?= =?UTF-8?q?=EC=8B=9C=EC=BD=94=EB=93=9C=20=EA=B3=84=EC=A0=95=EA=B3=84?= =?UTF-8?q?=EC=AA=BD=20=ED=85=8C=EC=8A=A4=ED=8A=B8=EC=9A=94=EC=B2=AD."?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This reverts commit fdd9d576f02616d2cc1fd21f3691bcee6ffca225. --- .../eactive/eai/outbound/SocketProcess.java | 26 +------------------ 1 file changed, 1 insertion(+), 25 deletions(-) diff --git a/src/main/java/com/eactive/eai/outbound/SocketProcess.java b/src/main/java/com/eactive/eai/outbound/SocketProcess.java index 08c8af5..d3912f7 100644 --- a/src/main/java/com/eactive/eai/outbound/SocketProcess.java +++ b/src/main/java/com/eactive/eai/outbound/SocketProcess.java @@ -9,6 +9,7 @@ import com.eactive.eai.adapter.AdapterVO; import com.eactive.eai.adapter.socket2.EAIConnectException; import com.eactive.eai.adapter.socket2.EAINoAvailableConnectionException; import com.eactive.eai.adapter.socket2.EAITimeoutException; +import com.eactive.eai.adapter.socket2.SocketAdapterFacade; import com.eactive.eai.common.EAIKeys; import com.eactive.eai.common.exception.ExceptionUtil; import com.eactive.eai.common.header.HeaderAction; @@ -31,7 +32,6 @@ import com.eactive.eai.control.SocketSender; import com.eactive.eai.control.Transform; import com.eactive.eai.env.ElinkConfig; import com.eactive.eai.inbound.processor.Processor; -import com.eactive.eai.message.StandardItem; import com.eactive.eai.message.StandardMessage; import com.eactive.eai.message.manager.StandardMessageManager; import com.eactive.eai.message.parser.StandardReader; @@ -481,30 +481,6 @@ public class SocketProcess extends DefaultProcess { } } } - - @Override - protected void setRcvLogInfoExtend() throws Exception { - - super.setRcvLogInfoExtend(); - - final String MESSAGE_PART = "Message"; - final String MESSAGE_PART_HEADER_PART = "Message.Msg_Header"; - final String MESSAGE_PART_BODY_PART = "Message.Msg_Body"; - - if (!com.eactive.eai.adapter.Keys.IF_STANDARD.equals(this.adptrMsgPtrnCd)) { - - StandardMessage standardMessage = this.resEaiMsg.getStandardMessage(); - - StandardItem messagePart = standardMessage.findItem(MESSAGE_PART); - messagePart.setHidden(true); - messagePart.setSize(0); - - StandardItem messageHeaderPart = standardMessage.findItem(MESSAGE_PART_HEADER_PART); - messageHeaderPart.setSize(0); - StandardItem messageBodyPart = standardMessage.findItem(MESSAGE_PART_BODY_PART); - messageBodyPart.setSize(0); - } - } public void getTopicProperty() throws Exception { PropManager propManager = PropManager.getInstance(); From 52da4abb97963002ec40184393eb995e7d3e2208 Mon Sep 17 00:00:00 2001 From: cho Date: Wed, 28 Jan 2026 14:51:55 +0900 Subject: [PATCH 122/159] =?UTF-8?q?=EA=B3=84=EC=A0=95=EA=B3=84=20=EA=B3=B5?= =?UTF-8?q?=ED=86=B5=ED=8C=80=20=EC=9A=94=EC=B2=AD,=20=EC=9D=91=EB=8B=B5?= =?UTF-8?q?=20=ED=91=9C=EC=A4=80=EB=A9=94=EC=84=B8=EC=A7=80=EC=97=90=20?= =?UTF-8?q?=EB=A9=94=EC=84=B8=EC=A7=80=EB=B6=80=20=EC=A0=9C=EA=B1=B0.=20(A?= =?UTF-8?q?-S=20=EC=9D=91=EB=8B=B5=EC=9D=BC=EB=95=8C=EB=A7=8C)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../eactive/eai/outbound/SocketProcess.java | 25 +++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/src/main/java/com/eactive/eai/outbound/SocketProcess.java b/src/main/java/com/eactive/eai/outbound/SocketProcess.java index d3912f7..e7e8d9b 100644 --- a/src/main/java/com/eactive/eai/outbound/SocketProcess.java +++ b/src/main/java/com/eactive/eai/outbound/SocketProcess.java @@ -32,9 +32,11 @@ import com.eactive.eai.control.SocketSender; import com.eactive.eai.control.Transform; import com.eactive.eai.env.ElinkConfig; import com.eactive.eai.inbound.processor.Processor; +import com.eactive.eai.message.StandardItem; import com.eactive.eai.message.StandardMessage; import com.eactive.eai.message.manager.StandardMessageManager; import com.eactive.eai.message.parser.StandardReader; +import com.eactive.eai.message.service.InterfaceMapper; import com.ext.eai.common.stdmessage.STDMessageKeys; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.JsonNode; @@ -458,8 +460,31 @@ public class SocketProcess extends DefaultProcess { String txTmotTktm = prop.getProperty("timeout", "50"); setTimeout(this.reqEaiMsg, StringUtil.stringFormat(txTmotTktm, true, '0', 3)); + String returnType = getReturnType(this.reqEaiMsg); + + if( STDMessageKeys.SEND_RECV_CD_RECV.equals(returnType) ) { //소켓이고 비동기Outbound인데, 표준메세지 요청구분가 R은 A-S 패턴의 응답 일떄만, 아래 로직(메세지부를 제거하고 보냄.) + + StandardMessage standardMessage = this.reqEaiMsg.getStandardMessage(); + + final String MESSAGE_PART = "Message"; + final String MESSAGE_PART_HEADER_PART = "Message.Msg_Header"; + final String MESSAGE_PART_BODY_PART = "Message.Msg_Body"; + + if (!com.eactive.eai.adapter.Keys.IF_STANDARD.equals(this.adptrMsgPtrnCd)) { + + StandardItem messagePart = standardMessage.findItem(MESSAGE_PART); + messagePart.setHidden(true); + messagePart.setSize(0); + + StandardItem messageHeaderPart = standardMessage.findItem(MESSAGE_PART_HEADER_PART); + messageHeaderPart.setSize(0); + StandardItem messageBodyPart = standardMessage.findItem(MESSAGE_PART_BODY_PART); + messageBodyPart.setSize(0); + } + } this.reqObject = makeStandardMessageData(this.reqEaiMsg, this.adptrMsgType, this.reqObject, this.outboundCharset); + if(this.reqObject instanceof String) { this.reqObject = ((String) this.reqObject).getBytes(this.outboundCharset); } From f2697abaa1ae88e0de343931d8310bc0b7f10fd1 Mon Sep 17 00:00:00 2001 From: cho Date: Wed, 28 Jan 2026 15:40:38 +0900 Subject: [PATCH 123/159] =?UTF-8?q?=EC=98=A4=ED=83=80=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/com/eactive/eai/outbound/SocketProcess.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/com/eactive/eai/outbound/SocketProcess.java b/src/main/java/com/eactive/eai/outbound/SocketProcess.java index e7e8d9b..0074916 100644 --- a/src/main/java/com/eactive/eai/outbound/SocketProcess.java +++ b/src/main/java/com/eactive/eai/outbound/SocketProcess.java @@ -470,7 +470,7 @@ public class SocketProcess extends DefaultProcess { final String MESSAGE_PART_HEADER_PART = "Message.Msg_Header"; final String MESSAGE_PART_BODY_PART = "Message.Msg_Body"; - if (!com.eactive.eai.adapter.Keys.IF_STANDARD.equals(this.adptrMsgPtrnCd)) { + if (com.eactive.eai.adapter.Keys.IF_STANDARD.equals(this.adptrMsgPtrnCd)) { StandardItem messagePart = standardMessage.findItem(MESSAGE_PART); messagePart.setHidden(true); From 4adad4f2e037840b7131376d0de8acda1d95ac9c Mon Sep 17 00:00:00 2001 From: cho Date: Wed, 28 Jan 2026 15:45:01 +0900 Subject: [PATCH 124/159] =?UTF-8?q?=EB=B6=88=ED=95=84=EC=9A=94=20=EC=A1=B0?= =?UTF-8?q?=EA=B1=B4=EB=AC=B8=20=EC=A0=9C=EA=B1=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../eactive/eai/outbound/SocketProcess.java | 26 +++++++++---------- 1 file changed, 12 insertions(+), 14 deletions(-) diff --git a/src/main/java/com/eactive/eai/outbound/SocketProcess.java b/src/main/java/com/eactive/eai/outbound/SocketProcess.java index 0074916..c4fdd29 100644 --- a/src/main/java/com/eactive/eai/outbound/SocketProcess.java +++ b/src/main/java/com/eactive/eai/outbound/SocketProcess.java @@ -462,25 +462,23 @@ public class SocketProcess extends DefaultProcess { String returnType = getReturnType(this.reqEaiMsg); - if( STDMessageKeys.SEND_RECV_CD_RECV.equals(returnType) ) { //소켓이고 비동기Outbound인데, 표준메세지 요청구분가 R은 A-S 패턴의 응답 일떄만, 아래 로직(메세지부를 제거하고 보냄.) - + if (STDMessageKeys.SEND_RECV_CD_RECV.equals(returnType)) { // 소켓이고 비동기Outbound인데, 표준메세지 요청구분가 R은 A-S 패턴의 응답 + // 일떄만, 아래 로직(메세지부를 제거하고 보냄.) + StandardMessage standardMessage = this.reqEaiMsg.getStandardMessage(); - + final String MESSAGE_PART = "Message"; final String MESSAGE_PART_HEADER_PART = "Message.Msg_Header"; final String MESSAGE_PART_BODY_PART = "Message.Msg_Body"; - - if (com.eactive.eai.adapter.Keys.IF_STANDARD.equals(this.adptrMsgPtrnCd)) { - - StandardItem messagePart = standardMessage.findItem(MESSAGE_PART); - messagePart.setHidden(true); - messagePart.setSize(0); - StandardItem messageHeaderPart = standardMessage.findItem(MESSAGE_PART_HEADER_PART); - messageHeaderPart.setSize(0); - StandardItem messageBodyPart = standardMessage.findItem(MESSAGE_PART_BODY_PART); - messageBodyPart.setSize(0); - } + StandardItem messagePart = standardMessage.findItem(MESSAGE_PART); + messagePart.setHidden(true); + messagePart.setSize(0); + + StandardItem messageHeaderPart = standardMessage.findItem(MESSAGE_PART_HEADER_PART); + messageHeaderPart.setSize(0); + StandardItem messageBodyPart = standardMessage.findItem(MESSAGE_PART_BODY_PART); + messageBodyPart.setSize(0); } this.reqObject = makeStandardMessageData(this.reqEaiMsg, this.adptrMsgType, this.reqObject, this.outboundCharset); From 77c4451718657c90184fa1fdc1aad1f2cff8d02d Mon Sep 17 00:00:00 2001 From: jaewohong Date: Wed, 28 Jan 2026 17:15:01 +0900 Subject: [PATCH 125/159] =?UTF-8?q?Outbound=20method=20type=EC=97=90=20PAT?= =?UTF-8?q?CH=20=EC=B6=94=EA=B0=80=ED=95=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/com/eactive/eai/adapter/http/HttpMethodType.java | 1 + .../http/client/impl/HttpClient5AdapterServiceRest.java | 4 ++++ 2 files changed, 5 insertions(+) diff --git a/src/main/java/com/eactive/eai/adapter/http/HttpMethodType.java b/src/main/java/com/eactive/eai/adapter/http/HttpMethodType.java index 5631af6..8d14662 100644 --- a/src/main/java/com/eactive/eai/adapter/http/HttpMethodType.java +++ b/src/main/java/com/eactive/eai/adapter/http/HttpMethodType.java @@ -5,6 +5,7 @@ public enum HttpMethodType { PUT, DELETE, GET, + PATCH, UNKNOWN; public static HttpMethodType getValue(String value) { try { diff --git a/src/main/java/com/eactive/eai/adapter/http/client/impl/HttpClient5AdapterServiceRest.java b/src/main/java/com/eactive/eai/adapter/http/client/impl/HttpClient5AdapterServiceRest.java index bba2579..9fb8702 100644 --- a/src/main/java/com/eactive/eai/adapter/http/client/impl/HttpClient5AdapterServiceRest.java +++ b/src/main/java/com/eactive/eai/adapter/http/client/impl/HttpClient5AdapterServiceRest.java @@ -33,6 +33,7 @@ import org.apache.hc.client5.http.classic.methods.HttpDelete; import org.apache.hc.client5.http.classic.methods.HttpGet; import org.apache.hc.client5.http.classic.methods.HttpPost; import org.apache.hc.client5.http.classic.methods.HttpPut; +import org.apache.hc.client5.http.classic.methods.HttpPatch; import org.apache.hc.client5.http.classic.methods.HttpUriRequestBase; import org.apache.hc.client5.http.config.RequestConfig; import org.apache.hc.client5.http.entity.UrlEncodedFormEntity; @@ -284,6 +285,9 @@ public class HttpClient5AdapterServiceRest extends HttpClient5AdapterServiceSupp case PUT: method = new HttpPut(uri); break; + case PATCH: + method = new HttpPatch(uri); + break; default: method = new HttpGet(uri); break; From 5002ab6af70bcbac76b3244408aff3f922cdb4e6 Mon Sep 17 00:00:00 2001 From: cho Date: Wed, 28 Jan 2026 18:23:05 +0900 Subject: [PATCH 126/159] =?UTF-8?q?PATCH=20=EA=B4=80=EB=A0=A8=20=EC=97=85?= =?UTF-8?q?=EB=AC=B4=EB=8D=B0=EC=9D=B4=ED=84=B0=20=EC=85=8B=ED=8C=85?= =?UTF-8?q?=ED=95=98=EB=8F=84=EB=A1=9D=20=EC=88=98=EC=A0=95(POST=EC=99=80?= =?UTF-8?q?=20=EB=8F=99=EC=9D=BC).?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../adapter/http/client/impl/HttpClient5AdapterServiceRest.java | 1 + 1 file changed, 1 insertion(+) diff --git a/src/main/java/com/eactive/eai/adapter/http/client/impl/HttpClient5AdapterServiceRest.java b/src/main/java/com/eactive/eai/adapter/http/client/impl/HttpClient5AdapterServiceRest.java index 9fb8702..6c8c548 100644 --- a/src/main/java/com/eactive/eai/adapter/http/client/impl/HttpClient5AdapterServiceRest.java +++ b/src/main/java/com/eactive/eai/adapter/http/client/impl/HttpClient5AdapterServiceRest.java @@ -381,6 +381,7 @@ public class HttpClient5AdapterServiceRest extends HttpClient5AdapterServiceSupp break; case PUT: case POST: + case PATCH: // assignPostBody(dataObject, contentType, vo.getEncode(), method); //assignPostBody(dataContent, contentType, vo.getEncode(), method); // jwhong commnet // KJBank API 추적정보를 Header에 제공. jwhong From f58359baa18d1d81b1118207427c8e23c4584e29 Mon Sep 17 00:00:00 2001 From: cho Date: Fri, 30 Jan 2026 10:08:48 +0900 Subject: [PATCH 127/159] =?UTF-8?q?=EB=A0=88=EA=B1=B0=EC=8B=9C=20HTT=20Inb?= =?UTF-8?q?ound=20=EB=B0=A9=EC=8B=9D=20HTTP=5FADAPTER=5FEXTRA=5FLOG=20?= =?UTF-8?q?=ED=85=8C=EC=9D=B4=EB=B8=94=EC=97=90=20=EB=A1=9C=EA=B7=B8?= =?UTF-8?q?=EA=B0=80=20=EC=95=88=EB=82=A8=EB=8A=94=20=ED=98=84=EC=83=81=20?= =?UTF-8?q?bugfix?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit HttpAdapterServiceRest.java 참고함. --- .../dynamic/impl/HttpAdapterServiceStandard.java | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/eactive/eai/adapter/http/dynamic/impl/HttpAdapterServiceStandard.java b/src/main/java/com/eactive/eai/adapter/http/dynamic/impl/HttpAdapterServiceStandard.java index fa92a25..0ff6ffe 100644 --- a/src/main/java/com/eactive/eai/adapter/http/dynamic/impl/HttpAdapterServiceStandard.java +++ b/src/main/java/com/eactive/eai/adapter/http/dynamic/impl/HttpAdapterServiceStandard.java @@ -7,10 +7,13 @@ import com.eactive.eai.adapter.AdapterVO; import com.eactive.eai.adapter.Keys; import com.eactive.eai.adapter.http.HttpMemoryLogger; import com.eactive.eai.adapter.http.HttpStatusException; +import com.eactive.eai.adapter.http.client.HttpClientAdapterServiceKey; import com.eactive.eai.adapter.http.dynamic.HttpAdapterServiceKey; import com.eactive.eai.adapter.http.dynamic.HttpAdapterServiceSupport; +import com.eactive.eai.common.TransactionContextKeys; import com.eactive.eai.common.exception.ExceptionUtil; import com.eactive.eai.common.util.CommonLib; +import com.eactive.eai.common.util.HttpAdapterExtraLogUtil; import com.eactive.eai.common.util.Logger; import com.eactive.eai.common.util.MessageUtil; import com.eactive.eai.env.ElinkConfig; @@ -59,6 +62,7 @@ public class HttpAdapterServiceStandard extends HttpAdapterServiceSupport int traceLevel = 0; AdapterGroupVO adapterGroupVo = null; + Properties prop = null; try { AdapterManager adapterManager = AdapterManager.getInstance(); @@ -164,7 +168,7 @@ public class HttpAdapterServiceStandard extends HttpAdapterServiceSupport logger.debug("HttpAdapter] " + resMsg); } - Properties prop = new Properties(); + prop = new Properties(); prop.put(INBOUND_METHOD, request.getMethod()); prop.put(INBOUND_URI, request.getRequestURI()); prop.put(INBOUND_HEADER, getHeaders(request)); @@ -336,7 +340,15 @@ public class HttpAdapterServiceStandard extends HttpAdapterServiceSupport } - } + }finally { + String uuid = prop.getProperty(TransactionContextKeys.TRANSACTION_UUID); + String url = prop.getProperty(HttpClientAdapterServiceKey.INBOUND_EXTURI); + String method = prop.getProperty(HttpClientAdapterServiceKey.INBOUND_METHOD); + String adapterGroupName = prop.getProperty(HttpClientAdapterServiceKey.ADAPTER_GROUP_NAME); + String adapterName = prop.getProperty(HttpClientAdapterServiceKey.ADAPTER_NAME); + int httpStatusCode = response.getStatus(); + HttpAdapterExtraLogUtil.insertHttpAdapterExtraLog(uuid, 400, adapterGroupName, adapterName, new HashMap<>(), url, method, httpStatusCode); + } } /** From c112164518097b63266f0d4588b7739d6e7813c4 Mon Sep 17 00:00:00 2001 From: cho Date: Mon, 2 Feb 2026 10:25:19 +0900 Subject: [PATCH 128/159] =?UTF-8?q?HTTP=20=ED=97=A4=EB=8D=94=20400=20?= =?UTF-8?q?=EB=A1=9C=EA=B9=85=20=EB=B0=8F=20=EC=9D=B8=EC=A6=9D=EA=B0=92=20?= =?UTF-8?q?=EB=B3=B4=EC=95=88=EC=9D=B4=EC=9C=A0=EB=A1=9C=20hidden=EC=B2=98?= =?UTF-8?q?=EB=A6=AC=20=EA=B3=A0=EA=B0=9D=EC=9A=94=EC=B2=AD=EC=9C=BC?= =?UTF-8?q?=EB=A1=9C=20=EC=A0=9C=EA=B1=B0.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../dynamic/impl/HttpAdapterServiceRest.java | 8 +++++++- .../impl/HttpAdapterServiceStandard.java | 8 +++++++- .../common/util/HttpAdapterExtraLogUtil.java | 19 +++++++++---------- 3 files changed, 23 insertions(+), 12 deletions(-) diff --git a/src/main/java/com/eactive/eai/adapter/http/dynamic/impl/HttpAdapterServiceRest.java b/src/main/java/com/eactive/eai/adapter/http/dynamic/impl/HttpAdapterServiceRest.java index dfa8bd8..13089e7 100644 --- a/src/main/java/com/eactive/eai/adapter/http/dynamic/impl/HttpAdapterServiceRest.java +++ b/src/main/java/com/eactive/eai/adapter/http/dynamic/impl/HttpAdapterServiceRest.java @@ -588,7 +588,13 @@ public class HttpAdapterServiceRest extends HttpAdapterServiceSupport { String adapterGroupName = prop.getProperty(HttpClientAdapterServiceKey.ADAPTER_GROUP_NAME); String adapterName = prop.getProperty(HttpClientAdapterServiceKey.ADAPTER_NAME); int httpStatusCode = response.getStatus(); - HttpAdapterExtraLogUtil.insertHttpAdapterExtraLog(uuid, 400, adapterGroupName, adapterName, new HashMap<>(), url, method, httpStatusCode); + Map headerMap = new HashMap<>(); + // 응답 헤더 로깅 + for (String headerName : response.getHeaderNames()) { + String headerValue = response.getHeader(headerName); + headerMap.put(headerName, headerValue); + } + HttpAdapterExtraLogUtil.insertHttpAdapterExtraLog(uuid, 400, adapterGroupName, adapterName, headerMap, url, method, httpStatusCode); } } diff --git a/src/main/java/com/eactive/eai/adapter/http/dynamic/impl/HttpAdapterServiceStandard.java b/src/main/java/com/eactive/eai/adapter/http/dynamic/impl/HttpAdapterServiceStandard.java index 0ff6ffe..17103ab 100644 --- a/src/main/java/com/eactive/eai/adapter/http/dynamic/impl/HttpAdapterServiceStandard.java +++ b/src/main/java/com/eactive/eai/adapter/http/dynamic/impl/HttpAdapterServiceStandard.java @@ -347,7 +347,13 @@ public class HttpAdapterServiceStandard extends HttpAdapterServiceSupport String adapterGroupName = prop.getProperty(HttpClientAdapterServiceKey.ADAPTER_GROUP_NAME); String adapterName = prop.getProperty(HttpClientAdapterServiceKey.ADAPTER_NAME); int httpStatusCode = response.getStatus(); - HttpAdapterExtraLogUtil.insertHttpAdapterExtraLog(uuid, 400, adapterGroupName, adapterName, new HashMap<>(), url, method, httpStatusCode); + Map headerMap = new HashMap<>(); + // 응답 헤더 로깅 + for (String headerName : response.getHeaderNames()) { + String headerValue = response.getHeader(headerName); + headerMap.put(headerName, headerValue); + } + HttpAdapterExtraLogUtil.insertHttpAdapterExtraLog(uuid, 400, adapterGroupName, adapterName, headerMap, url, method, httpStatusCode); } } diff --git a/src/main/java/com/eactive/eai/common/util/HttpAdapterExtraLogUtil.java b/src/main/java/com/eactive/eai/common/util/HttpAdapterExtraLogUtil.java index 40913c5..62c0627 100644 --- a/src/main/java/com/eactive/eai/common/util/HttpAdapterExtraLogUtil.java +++ b/src/main/java/com/eactive/eai/common/util/HttpAdapterExtraLogUtil.java @@ -57,17 +57,16 @@ public class HttpAdapterExtraLogUtil { httpAdapterExtraLogVo.setHttpMethod(httpMethod); for (HttpAdapterExtraHeaderVo httpAdapterExtraHeaderVo : headerVoList) { - String name = httpAdapterExtraHeaderVo.getName(); - if(StringUtils.isNotBlank(name) && "authorization".equals(name.toLowerCase())) { - httpAdapterExtraHeaderVo.setValue("{hidden}"); - } + String value = httpAdapterExtraHeaderVo.getValue(); - if(StringUtils.isNotBlank(value) && value.length() > 400) { - value = value.substring(0, 400) + "..."; - httpAdapterExtraHeaderVo.setValue(value); - }else if(value == null){ - httpAdapterExtraHeaderVo.setValue(" "); - } + + if (StringUtils.isNotBlank(value) && value.length() > 400) { + value = value.substring(0, 400) + "..."; + httpAdapterExtraHeaderVo.setValue(value); + } else if (value == null) { + httpAdapterExtraHeaderVo.setValue(" "); + } + } httpAdapterExtraLogVo.setHeaderList(headerVoList); httpAdapterExtraLogVo.setHttpStatus(httpStatus); From 562f0bc0eec1f0bd3d536d24468252b0700ea8b7 Mon Sep 17 00:00:00 2001 From: cho Date: Tue, 3 Feb 2026 14:48:28 +0900 Subject: [PATCH 129/159] =?UTF-8?q?DR=20=EC=A0=84=ED=99=98=20=EB=A1=9C?= =?UTF-8?q?=EC=A7=81=20=EC=B6=94=EA=B0=80,?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 공통프로퍼티 그룹키(DR) 추가 및 전환키(dr.enable) --- .../http/client/HttpClient5AdapterServiceSupport.java | 8 ++++++++ .../adapter/http/client/HttpClientAdapterServiceKey.java | 3 +++ .../http/client/HttpClientAdapterServiceSupport.java | 7 +++++++ 3 files changed, 18 insertions(+) diff --git a/src/main/java/com/eactive/eai/adapter/http/client/HttpClient5AdapterServiceSupport.java b/src/main/java/com/eactive/eai/adapter/http/client/HttpClient5AdapterServiceSupport.java index b81600f..64e0e6d 100644 --- a/src/main/java/com/eactive/eai/adapter/http/client/HttpClient5AdapterServiceSupport.java +++ b/src/main/java/com/eactive/eai/adapter/http/client/HttpClient5AdapterServiceSupport.java @@ -40,6 +40,7 @@ import com.eactive.eai.adapter.AdapterManager; import com.eactive.eai.adapter.Keys; import com.eactive.eai.adapter.http.secure.HttpClient5SSLContextFactory; import com.eactive.eai.common.TransactionContextKeys; +import com.eactive.eai.common.property.PropManager; import com.eactive.eai.common.util.HttpAdapterExtraLogUtil; import com.eactive.eai.common.util.Logger; import com.eactive.eai.httpouttlsinfo.HttpOutTlsInfoVO; @@ -88,6 +89,13 @@ public abstract class HttpClient5AdapterServiceSupport implements HttpClientAdap if (!StringUtils.isEmpty(url2grp)) { url = url2grp; } + + boolean isDrMode = Boolean.valueOf(PropManager.getInstance().getProperty(DR_PROP_GROUP, DR_PROP_KEY, "false")); + + if (isDrMode) { + url = prop.getProperty(DR_URL); + } + method = prop.getProperty(METHOD); parameterName = prop.getProperty(PARAMETER_NAME, PARAMETER_MESSAGE); contentType = prop.getProperty(CONTENT_TYPE, ""); diff --git a/src/main/java/com/eactive/eai/adapter/http/client/HttpClientAdapterServiceKey.java b/src/main/java/com/eactive/eai/adapter/http/client/HttpClientAdapterServiceKey.java index 0238cbc..6e6bad5 100644 --- a/src/main/java/com/eactive/eai/adapter/http/client/HttpClientAdapterServiceKey.java +++ b/src/main/java/com/eactive/eai/adapter/http/client/HttpClientAdapterServiceKey.java @@ -8,6 +8,9 @@ public interface HttpClientAdapterServiceKey { public static final String HTTP_TYPE = "HTTP_TYPE"; public static final String URL = "URL"; + public static final String DR_PROP_GROUP = "DR"; + public static final String DR_PROP_KEY = "dr.enable"; + public static final String DR_URL = "URL_DR"; public static final String URL_2GRP = "URL_2GRP"; public static final String METHOD = "METHOD"; diff --git a/src/main/java/com/eactive/eai/adapter/http/client/HttpClientAdapterServiceSupport.java b/src/main/java/com/eactive/eai/adapter/http/client/HttpClientAdapterServiceSupport.java index 5829cb0..f72bfc9 100644 --- a/src/main/java/com/eactive/eai/adapter/http/client/HttpClientAdapterServiceSupport.java +++ b/src/main/java/com/eactive/eai/adapter/http/client/HttpClientAdapterServiceSupport.java @@ -27,6 +27,7 @@ import com.eactive.eai.adapter.http.secure.CustomHttpsSocketFactory; import com.eactive.eai.adapter.http.secure.CustomSSLProtocolSocketFactory; import com.eactive.eai.adapter.http.secure.EasySSLProtocolSocketFactory; import com.eactive.eai.adapter.http.secure.SSLContextFactory; +import com.eactive.eai.common.property.PropManager; import com.eactive.eai.common.util.Logger; import com.eactive.eai.httpouttlsinfo.HttpOutTlsInfoManager; import com.eactive.eai.httpouttlsinfo.HttpOutTlsInfoVO; @@ -100,6 +101,12 @@ public abstract class HttpClientAdapterServiceSupport implements HttpClientAdapt if (StringUtils.isNotBlank(interfaceTimeout) && NumberUtils.toInt(interfaceTimeout) > 0) { timeoutTemp = interfaceTimeout; } + + boolean isDrMode = Boolean.valueOf(PropManager.getInstance().getProperty(DR_PROP_GROUP, DR_PROP_KEY, "false")); + + if (isDrMode) { + url = prop.getProperty(DR_URL); + } url = StringUtils.trim(url); parameterName = StringUtils.trim(parameterName); From e83c699dc57df7ff7ad56de89462f6c6abbec0d5 Mon Sep 17 00:00:00 2001 From: cho Date: Tue, 3 Feb 2026 17:49:52 +0900 Subject: [PATCH 130/159] =?UTF-8?q?http=ED=97=A4=EB=8D=94=EA=B0=92=20400?= =?UTF-8?q?=EC=9E=90=EB=A6=AC=20=EB=84=98=EB=8A=94=EA=B1=B0=20=EC=B6=95?= =?UTF-8?q?=EC=95=BD=20=EB=A1=9C=EC=A7=81=20=EC=A0=9C=EA=B1=B0.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/eactive/eai/common/util/HttpAdapterExtraLogUtil.java | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/main/java/com/eactive/eai/common/util/HttpAdapterExtraLogUtil.java b/src/main/java/com/eactive/eai/common/util/HttpAdapterExtraLogUtil.java index 62c0627..5e76a92 100644 --- a/src/main/java/com/eactive/eai/common/util/HttpAdapterExtraLogUtil.java +++ b/src/main/java/com/eactive/eai/common/util/HttpAdapterExtraLogUtil.java @@ -60,10 +60,7 @@ public class HttpAdapterExtraLogUtil { String value = httpAdapterExtraHeaderVo.getValue(); - if (StringUtils.isNotBlank(value) && value.length() > 400) { - value = value.substring(0, 400) + "..."; - httpAdapterExtraHeaderVo.setValue(value); - } else if (value == null) { + if (value == null) { httpAdapterExtraHeaderVo.setValue(" "); } From fcedbabfc9d1cc7dc77f89d0493257500ca29d3f Mon Sep 17 00:00:00 2001 From: cho Date: Thu, 5 Feb 2026 17:56:34 +0900 Subject: [PATCH 131/159] =?UTF-8?q?UMS=20=EC=97=B0=EA=B3=84=20=EC=BD=94?= =?UTF-8?q?=EB=93=9C=20=EC=9D=B4=EA=B4=80=20(admin-portal->oline-common)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../eai/custom/alarm/ums/IUmsGsonObject.java | 7 + .../alarm/ums/ObpMonitoringUmsTemplate.java | 12 ++ .../eai/custom/alarm/ums/UmsBizWorkCode.java | 19 +++ .../eai/custom/alarm/ums/UmsCallResult.java | 18 +++ .../custom/alarm/ums/UmsRequestPayload.java | 103 ++++++++++++++ .../eai/custom/alarm/ums/UmsService.java | 133 ++++++++++++++++++ .../eai/custom/alarm/ums/ValidationUtil.java | 53 +++++++ .../alarm/ums/VerifyPhoneUmsTemplate.java | 12 ++ 8 files changed, 357 insertions(+) create mode 100644 src/main/java/com/eactive/eai/custom/alarm/ums/IUmsGsonObject.java create mode 100644 src/main/java/com/eactive/eai/custom/alarm/ums/ObpMonitoringUmsTemplate.java create mode 100644 src/main/java/com/eactive/eai/custom/alarm/ums/UmsBizWorkCode.java create mode 100644 src/main/java/com/eactive/eai/custom/alarm/ums/UmsCallResult.java create mode 100644 src/main/java/com/eactive/eai/custom/alarm/ums/UmsRequestPayload.java create mode 100644 src/main/java/com/eactive/eai/custom/alarm/ums/UmsService.java create mode 100644 src/main/java/com/eactive/eai/custom/alarm/ums/ValidationUtil.java create mode 100644 src/main/java/com/eactive/eai/custom/alarm/ums/VerifyPhoneUmsTemplate.java diff --git a/src/main/java/com/eactive/eai/custom/alarm/ums/IUmsGsonObject.java b/src/main/java/com/eactive/eai/custom/alarm/ums/IUmsGsonObject.java new file mode 100644 index 0000000..58037b1 --- /dev/null +++ b/src/main/java/com/eactive/eai/custom/alarm/ums/IUmsGsonObject.java @@ -0,0 +1,7 @@ +package com.eactive.eai.custom.alarm.ums; + +/** + * GSON Serialize 용 Object + */ +public interface IUmsGsonObject { +} diff --git a/src/main/java/com/eactive/eai/custom/alarm/ums/ObpMonitoringUmsTemplate.java b/src/main/java/com/eactive/eai/custom/alarm/ums/ObpMonitoringUmsTemplate.java new file mode 100644 index 0000000..1570885 --- /dev/null +++ b/src/main/java/com/eactive/eai/custom/alarm/ums/ObpMonitoringUmsTemplate.java @@ -0,0 +1,12 @@ +package com.eactive.eai.custom.alarm.ums; + +import com.google.gson.annotations.SerializedName; +import lombok.Builder; +import lombok.Data; + +@Data +@Builder +public class ObpMonitoringUmsTemplate implements IUmsGsonObject { + @SerializedName("MOTR_EVAL_CNTN") + private String message; +} diff --git a/src/main/java/com/eactive/eai/custom/alarm/ums/UmsBizWorkCode.java b/src/main/java/com/eactive/eai/custom/alarm/ums/UmsBizWorkCode.java new file mode 100644 index 0000000..898f4b6 --- /dev/null +++ b/src/main/java/com/eactive/eai/custom/alarm/ums/UmsBizWorkCode.java @@ -0,0 +1,19 @@ +package com.eactive.eai.custom.alarm.ums; + +import lombok.Getter; + +public enum UmsBizWorkCode { + MONITORING("B_ELFN_09510", "OBP 모니터링"), + VERIFY_PHONE("S55_ICT_0006", "API Portal 인증번호"), + ; + + @Getter + private String code; + @Getter + private String displayName; + + UmsBizWorkCode(String code, String displayName) { + this.code = code; + this.displayName = displayName; + } +} diff --git a/src/main/java/com/eactive/eai/custom/alarm/ums/UmsCallResult.java b/src/main/java/com/eactive/eai/custom/alarm/ums/UmsCallResult.java new file mode 100644 index 0000000..f63b6d8 --- /dev/null +++ b/src/main/java/com/eactive/eai/custom/alarm/ums/UmsCallResult.java @@ -0,0 +1,18 @@ +package com.eactive.eai.custom.alarm.ums; + + +import lombok.Builder; +import lombok.Data; + +@Data +@Builder +public class UmsCallResult { + private String umsMessageId; + private boolean isSuccess; + + private String returnCode; + private String returnMessage; + private String returnPayload; + + private Throwable throwable; +} diff --git a/src/main/java/com/eactive/eai/custom/alarm/ums/UmsRequestPayload.java b/src/main/java/com/eactive/eai/custom/alarm/ums/UmsRequestPayload.java new file mode 100644 index 0000000..6e11bd1 --- /dev/null +++ b/src/main/java/com/eactive/eai/custom/alarm/ums/UmsRequestPayload.java @@ -0,0 +1,103 @@ +package com.eactive.eai.custom.alarm.ums; + +import com.google.gson.annotations.SerializedName; +import lombok.Builder; +import lombok.Data; +import lombok.Getter; +import org.hibernate.validator.constraints.Length; +import org.hibernate.validator.constraints.NotEmpty; + +import javax.validation.constraints.NotNull; +import javax.validation.constraints.Pattern; +import java.time.LocalDateTime; +import java.time.format.DateTimeFormatter; + +@Data +@Builder +@Getter +public class UmsRequestPayload { + // MSG_IDNT_NO string 메시지식별번호 50 O "발송 구분을 위한 거래 번호 (GUID 권고) + //GUID로 입력이 어려울시 + //어플리케이션코드(3자리)+난수 로 유니크한 ID로 채번 권고" + @Length(min = 1, max = 50) + @NotEmpty + @SerializedName("MSG_IDNT_NO") + private String messageIdentityNo; + + // MSG_BZWK_CD string 메시지업무코드 30 O UMS에 등록된 메시지업무코드(AS-IS 템플릿ID) + @NotEmpty + @Length(min = 1, max = 30) + @SerializedName("MSG_BZWK_CD") + private String msgBizWorkCode; + + // 메시지업무파라미터내용 / 4000 / JSONObject + // MSG_BZWK_PARAM_CTNT object 메시지업무파라미터내용 4000 메시지업무코드의 템플릿에서 사용하는 변수와 변수값 + @NotNull + @SerializedName("MSG_BZWK_PARAM_CTNT") + private IUmsGsonObject content; + + // 발송예약일시 / 14 / 실 발송 일자(yyyyMMddHHmmss) + // SND_RESR_DTTM string 발송예약일시 14 20240418111500 O 실 발송 일자(현재시간) + @Pattern(regexp = "^[0-9]{14}$") + @NotEmpty + @SerializedName("SND_RESR_DTTM") + @Builder.Default + private String sendReservationDatetime = DateTimeFormatter.ofPattern("yyyyMMddHHmmss").format(LocalDateTime.now()); + + // 휴대전화번호 / 44 / 휴대폰번호(평문, 암호화 둘다가능) + // CPNO string 휴대전화번호 44 "암호화 또는 평문 (safedb not rrno) + //문자일 시 암호문 + //숫자일 시 전화번호 + //고객번호 또는 휴대전화번호 필수" + @NotEmpty + @Pattern(regexp = "^[0-9]{10,11}$") + @SerializedName("CPNO") + private String cellphone; + + // 발송부점코드 / 4 / + // SND_BRCD string 발송부점코드 4 O 0333 + @NotEmpty + @SerializedName("SND_BRCD") + @Builder.Default + private String sendBranchCode = "0990"; + + // 발송직원번호 / 7 / ECEB057(텔러번호?) + // SND_EMPNO string 발송직원번호 7 O ? 넣긴해야함 + @NotEmpty + @SerializedName("SND_EMPNO") + @Builder.Default + private String sendEmployeeNo = "ECEB057"; + + // SRVC_ID string 서비스ID 11 요청단 측 서비스ID + @NotEmpty + @SerializedName("SRVC_ID") + @Builder.Default + private String serviceId = "eAPIM"; + + // MSG_SND_CHNL_CD string 메시지발송채널코드 2 + @SerializedName("MSG_SND_CHNL_CD") + @NotNull + @Builder.Default + private ChannelCode msgSndChnlCd = ChannelCode.KM; + + // VALDTN_RSLT_CD string 검증결과코드 2 00으로 고정 + @SerializedName("VALDTN_RSLT_CD") + @NotEmpty + @Builder.Default + private String validationResultCode = "00"; + + public enum ChannelCode { + SM, // SMS + LM, // LMS + MM, // MMS + KM, // 카카오-알림톡 + FM, // 카카오-친구톡 + SR, // RCS-SMS + LR, // RCS-LMS + MR, // RCS-MMS + TR, // RCS-TEMPLATE + IR, // RCS-IMAGE Template + PM // Push + } +} + diff --git a/src/main/java/com/eactive/eai/custom/alarm/ums/UmsService.java b/src/main/java/com/eactive/eai/custom/alarm/ums/UmsService.java new file mode 100644 index 0000000..08b6135 --- /dev/null +++ b/src/main/java/com/eactive/eai/custom/alarm/ums/UmsService.java @@ -0,0 +1,133 @@ +package com.eactive.eai.custom.alarm.ums; + +import java.io.IOException; +import java.nio.charset.Charset; +import java.time.LocalDateTime; +import java.time.format.DateTimeFormatter; +import java.util.Arrays; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.Future; + +import org.apache.hc.client5.http.classic.methods.HttpPost; +import org.apache.hc.client5.http.config.RequestConfig; +import org.apache.hc.client5.http.entity.EntityBuilder; +import org.apache.hc.client5.http.impl.classic.CloseableHttpClient; +import org.apache.hc.client5.http.impl.classic.HttpClients; +import org.apache.hc.core5.http.ContentType; +import org.apache.hc.core5.http.ProtocolException; +import org.apache.hc.core5.http.io.entity.EntityUtils; +import org.apache.hc.core5.util.Timeout; +import org.springframework.stereotype.Component; +import org.springframework.util.StreamUtils; + +import com.eactive.eai.common.util.Logger; +import com.google.gson.Gson; +import com.google.gson.JsonSyntaxException; + +@Component +public class UmsService { + + protected static Logger logger = Logger.getLogger(Logger.LOGGER_DEFAULT); + + private final static String UMS_URL = "http://172.31.35.144:9021"; + private final static String API_KEY = "API_KEY"; + private final static String SEND_URL = "/ums/openapi/send"; + private final static String CONTENT_TYPE = "application/json; charset=utf-8"; + private final static String AUTHORIZATION_FMT = "Bearer %s"; + + Future send(String cpno, String message, UmsBizWorkCode code) throws Exception { + + if (message == null) { + throw new IllegalArgumentException("content is null"); + } + + String guid = String.format("APM-%s", + DateTimeFormatter.ofPattern("yyyyMMddHHmmssSSS").format(LocalDateTime.now())); + + UmsRequestPayload payload = UmsRequestPayload.builder().messageIdentityNo(guid).msgBizWorkCode(code.getCode()) + .content(ObpMonitoringUmsTemplate.builder().message(message).build()).cellphone(cpno) + .msgSndChnlCd(UmsRequestPayload.ChannelCode.KM).build(); + + try { + ValidationUtil.validateOrThrow(payload); + } catch (Exception ex) { + logger.debug(String.format("UMS Request payload validation failed - %s", payload)); + throw ex; + } + + return call(SEND_URL, payload); + } + + private CloseableHttpClient createHttpClient() { + return HttpClients.createDefault(); + } + + private Future call(String url, UmsRequestPayload requestPayload) throws Exception { + + ExecutorService executor = Executors.newSingleThreadExecutor(); + Gson gson = new Gson(); + String json = gson.toJson(requestPayload); + + HttpPost httpPost = new HttpPost(UMS_URL + url); + httpPost.setHeader("Content-Type", CONTENT_TYPE); + httpPost.setHeader("Authorization", String.format(AUTHORIZATION_FMT, API_KEY)); + httpPost.setEntity(EntityBuilder.create().setText(json).setContentType(ContentType.APPLICATION_JSON).build()); + + if (logger.isDebugEnabled()) { + try { + logger.debug("Header - {}", httpPost.getHeader("Content-Type")); + logger.debug("Header - {}", httpPost.getHeader("Authorization")); + logger.debug("Request Body : {}", + StreamUtils.copyToString(httpPost.getEntity().getContent(), Charset.defaultCharset())); + } catch (ProtocolException | IOException e) { + throw new RuntimeException(e); + } + } + + httpPost.setConfig(RequestConfig.custom().setConnectTimeout(Timeout.ofSeconds(3)) + .setResponseTimeout(Timeout.ofSeconds(3)).build()); + Future future; + try (CloseableHttpClient httpClient = createHttpClient()) { + future = executor.submit(() -> { + return httpClient.execute(httpPost, res -> { + try { + UmsCallResult result; + String body = EntityUtils.toString(res.getEntity()); + if (logger.isDebugEnabled()) { + logger.debug("Response - {}", body); + } + result = gson.fromJson(body, UmsCallResult.class); + result.setUmsMessageId(requestPayload.getMessageIdentityNo()); + result.setSuccess(true); + return result; + } catch (JsonSyntaxException e) { + logger.error("UMS Call error(JSON Syntax)", e); + return UmsCallResult.builder().umsMessageId(requestPayload.getMessageIdentityNo()) + .isSuccess(false).throwable(e).build(); + } catch (Exception e) { + logger.error("UMS Call error", e); + return UmsCallResult.builder().umsMessageId(requestPayload.getMessageIdentityNo()) + .isSuccess(false).throwable(e).build(); + } finally { + logger.debug("Response status - {}", res.getCode()); + + if (res.getCode() != 200) { + Arrays.asList(res.getHeaders()).forEach(o -> { + logger.warn("[Header] {}: {}", o.getName(), o.getValue()); + }); + } + } + }); + }); + + return future; + } catch (Exception e) { + logger.error("UMS call exception", e); + throw new Exception("UMS call failed", e); + } finally { + executor.shutdown(); + } + + } +} diff --git a/src/main/java/com/eactive/eai/custom/alarm/ums/ValidationUtil.java b/src/main/java/com/eactive/eai/custom/alarm/ums/ValidationUtil.java new file mode 100644 index 0000000..7aacc4f --- /dev/null +++ b/src/main/java/com/eactive/eai/custom/alarm/ums/ValidationUtil.java @@ -0,0 +1,53 @@ +package com.eactive.eai.custom.alarm.ums; + +import java.util.Set; +import java.util.stream.Collectors; + +import javax.validation.ConstraintViolation; +import javax.validation.ConstraintViolationException; +import javax.validation.Validation; +import javax.validation.Validator; +import javax.validation.ValidatorFactory; + +import org.hibernate.validator.messageinterpolation.ParameterMessageInterpolator; + +public class ValidationUtil { + private static final ValidatorFactory factory; + private static final Validator validator; + + static { + factory = Validation.byDefaultProvider() + .configure() + .messageInterpolator(new ParameterMessageInterpolator()) + .buildValidatorFactory(); + + validator = factory.getValidator(); + } + + + private ValidationUtil() { + } + + + public static Set> validate(T target) { + return validator.validate(target); + } + + public static void validateOrThrow(T target) { + Set> violations = validate(target); + if (!violations.isEmpty()) { + String message = violations.stream() + .map(v -> v.getPropertyPath() + " : " + v.getMessage()) + .collect(Collectors.joining(", ")); + throw new ConstraintViolationException("Validation failed: " + message, violations); + } + } + + public static String getViolationMessage(T target) { + Set> violations = validate(target); + if (violations.isEmpty()) return null; + return violations.stream() + .map(v -> v.getPropertyPath() + " : " + v.getMessage()) + .collect(Collectors.joining(", ")); + } +} \ No newline at end of file diff --git a/src/main/java/com/eactive/eai/custom/alarm/ums/VerifyPhoneUmsTemplate.java b/src/main/java/com/eactive/eai/custom/alarm/ums/VerifyPhoneUmsTemplate.java new file mode 100644 index 0000000..7af2586 --- /dev/null +++ b/src/main/java/com/eactive/eai/custom/alarm/ums/VerifyPhoneUmsTemplate.java @@ -0,0 +1,12 @@ +package com.eactive.eai.custom.alarm.ums; + +import com.google.gson.annotations.SerializedName; +import lombok.Builder; +import lombok.Data; + +@Data +@Builder +public class VerifyPhoneUmsTemplate implements IUmsGsonObject { + @SerializedName("ATHN_NO") + private String authNumber; +} From 0340f63a799d3a81071b73a3495a707b7d0cc474 Mon Sep 17 00:00:00 2001 From: cho Date: Fri, 6 Feb 2026 09:43:58 +0900 Subject: [PATCH 132/159] =?UTF-8?q?ums=20Alarm=20=EC=9E=91=EC=97=85..?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/eactive/eai/common/util/Jsons.java | 10 +++ .../eai/custom/alarm/AlarmService.java | 80 ++++++++++++++++++ .../eai/custom/alarm/AlarmStateManager.java | 78 +++++++++++++++++ .../alarm/condition/AlarmCondition.java | 19 +++++ .../custom/alarm/condition/AlarmLevel.java | 5 ++ .../eai/custom/alarm/event/AlarmEvent.java | 37 +++++++++ .../eai/custom/alarm/key/AlarmKey.java | 5 ++ .../eai/custom/alarm/key/CoreAlarmKey.java | 9 ++ .../eai/custom/alarm/key/DynamicAlarmKey.java | 30 +++++++ .../eai/custom/alarm/policy/AlarmPolicy.java | 83 +++++++++++++++++++ .../eai/custom/alarm/policy/AlarmType.java | 5 ++ .../custom/alarm/policy/CounterPolicy.java | 39 +++++++++ .../eai/custom/alarm/policy/TimerPolicy.java | 52 ++++++++++++ 13 files changed, 452 insertions(+) create mode 100644 src/main/java/com/eactive/eai/common/util/Jsons.java create mode 100644 src/main/java/com/eactive/eai/custom/alarm/AlarmService.java create mode 100644 src/main/java/com/eactive/eai/custom/alarm/AlarmStateManager.java create mode 100644 src/main/java/com/eactive/eai/custom/alarm/condition/AlarmCondition.java create mode 100644 src/main/java/com/eactive/eai/custom/alarm/condition/AlarmLevel.java create mode 100644 src/main/java/com/eactive/eai/custom/alarm/event/AlarmEvent.java create mode 100644 src/main/java/com/eactive/eai/custom/alarm/key/AlarmKey.java create mode 100644 src/main/java/com/eactive/eai/custom/alarm/key/CoreAlarmKey.java create mode 100644 src/main/java/com/eactive/eai/custom/alarm/key/DynamicAlarmKey.java create mode 100644 src/main/java/com/eactive/eai/custom/alarm/policy/AlarmPolicy.java create mode 100644 src/main/java/com/eactive/eai/custom/alarm/policy/AlarmType.java create mode 100644 src/main/java/com/eactive/eai/custom/alarm/policy/CounterPolicy.java create mode 100644 src/main/java/com/eactive/eai/custom/alarm/policy/TimerPolicy.java diff --git a/src/main/java/com/eactive/eai/common/util/Jsons.java b/src/main/java/com/eactive/eai/common/util/Jsons.java new file mode 100644 index 0000000..a9379f4 --- /dev/null +++ b/src/main/java/com/eactive/eai/common/util/Jsons.java @@ -0,0 +1,10 @@ +package com.eactive.eai.common.util; + +import com.google.gson.Gson; + +public final class Jsons { + + private Jsons() {} + + public static final Gson GSON = new Gson(); +} \ No newline at end of file diff --git a/src/main/java/com/eactive/eai/custom/alarm/AlarmService.java b/src/main/java/com/eactive/eai/custom/alarm/AlarmService.java new file mode 100644 index 0000000..6f28796 --- /dev/null +++ b/src/main/java/com/eactive/eai/custom/alarm/AlarmService.java @@ -0,0 +1,80 @@ +package com.eactive.eai.custom.alarm; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; +import java.util.Optional; +import java.util.Properties; + +import org.springframework.stereotype.Service; + +import com.eactive.eai.common.property.PropManager; +import com.eactive.eai.common.util.Jsons; +import com.eactive.eai.common.util.Logger; +import com.eactive.eai.custom.alarm.key.DynamicAlarmKey; +import com.eactive.eai.custom.alarm.policy.AlarmPolicy; +import com.eactive.eai.custom.alarm.policy.CounterPolicy; +import com.eactive.eai.custom.alarm.policy.TimerPolicy; +import com.google.gson.Gson; +import com.google.gson.JsonObject; + +@Service +public class AlarmService { + + protected static Logger logger = Logger.getLogger(Logger.LOGGER_DEFAULT); + + final static String ALARM_GROUP = "Alarm"; + final static String ALARM_KEY = "Alarm"; + final static String ALARM_RECIVER = "{RECIVER}"; + + public List getAlarmPolicy() { + + List policyList = new ArrayList(); + + try { + + Properties props = PropManager.getInstance().getProperties(ALARM_GROUP); + + props.forEach((key, value) -> { + String keyName = (String) key; + String configStr = (String) value; + + if (keyName.contains(ALARM_RECIVER)) + return; + + policyList.add(buildAlarmPolicy(keyName, configStr)); + + }); + + } catch (Exception e) { + logger.error("getAlarmPolicy fail.", e); + return Collections.EMPTY_LIST; + } + + return null; + } + + AlarmPolicy buildAlarmPolicy(String key, String configJsonStr) { + + JsonObject alarmConfig = Jsons.GSON.fromJson(configJsonStr, JsonObject.class); + + String policyType = alarmConfig.get("type").getAsString(); + int coolDownSec = Optional.ofNullable(alarmConfig.get("coolDownSec")).map(i -> i.getAsInt()).orElse(60); + int thresholdCount = Optional.ofNullable(alarmConfig.get("thresholdCount")).map(i -> i.getAsInt()).orElse(5); + int timeWindowSec = Optional.ofNullable(alarmConfig.get("timeWindowSec")).map(i -> i.getAsInt()).orElse(60); + + AlarmPolicy alarmPolicy; + + if ("CountPolicy".equals(policyType)) { + alarmPolicy = CounterPolicy.builder().alarmKey(new DynamicAlarmKey(key)).coolDownMs(coolDownSec * 1000) + .thresholdCount(thresholdCount).build(); + } else { + alarmPolicy = TimerPolicy.builder().alarmKey(new DynamicAlarmKey(key)).coolDownMs(coolDownSec * 1000) + .timeWindowMs(timeWindowSec * 1000).build(); + } + + return alarmPolicy; + + } +} diff --git a/src/main/java/com/eactive/eai/custom/alarm/AlarmStateManager.java b/src/main/java/com/eactive/eai/custom/alarm/AlarmStateManager.java new file mode 100644 index 0000000..8d4bfd8 --- /dev/null +++ b/src/main/java/com/eactive/eai/custom/alarm/AlarmStateManager.java @@ -0,0 +1,78 @@ +package com.eactive.eai.custom.alarm; + +import java.util.ArrayList; +import java.util.List; +import java.util.Optional; +import java.util.concurrent.Executors; +import java.util.concurrent.ScheduledExecutorService; +import java.util.concurrent.TimeUnit; + +import org.springframework.stereotype.Component; + +import com.eactive.eai.common.util.Logger; +import com.eactive.eai.custom.alarm.event.AlarmEvent; + +@Component +public class AlarmStateManager { + + + List registerAlarmList = new ArrayList(); + + private final ScheduledExecutorService scheduler; + + protected static Logger logger = Logger.getLogger(Logger.LOGGER_DEFAULT); + + + public AlarmStateManager() { + + this.scheduler = Executors.newSingleThreadScheduledExecutor(r -> { + Thread t = new Thread(r); + t.setName("AlarmStateManager-worker"); + t.setDaemon(false); + return t; + }); + + scheduler.scheduleWithFixedDelay(() -> { + + try { + // === 여기에 지속 실행할 로직 === + fireAlarm(); + + } catch (Throwable e) { + // 반드시 예외 잡기 (안 잡으면 스케줄 자체가 죽음) + logger.error("fireAlarm fail", e); + } + + }, 0, 5, TimeUnit.SECONDS); // 최초 0초, 이후 5초 간격 + } + + + public void onEvnet(AlarmEvent alaramEvent) { + + Optional existEvent = + registerAlarmList.stream() + .filter(e -> e.equals(alaramEvent)) + .findFirst(); + + if (existEvent.isPresent()) { + AlarmEvent event = existEvent.get(); + event.onOcurr(); + } else { + registerAlarmList.add(alaramEvent); + } + + } + + private void fireAlarm() { + + for(AlarmEvent event : registerAlarmList) { + + + + } + + } + + + +} \ No newline at end of file diff --git a/src/main/java/com/eactive/eai/custom/alarm/condition/AlarmCondition.java b/src/main/java/com/eactive/eai/custom/alarm/condition/AlarmCondition.java new file mode 100644 index 0000000..7d852f4 --- /dev/null +++ b/src/main/java/com/eactive/eai/custom/alarm/condition/AlarmCondition.java @@ -0,0 +1,19 @@ +package com.eactive.eai.custom.alarm.condition; + +import lombok.Builder; +import lombok.Getter; + +@Builder +@Getter +public class AlarmCondition { + AlarmLevel level; + final long ocurredAt; + long lastOcurredAt; + long count = 1; + + public void onOcurr() { + this.lastOcurredAt = System.currentTimeMillis(); + this.count++; + } + +} diff --git a/src/main/java/com/eactive/eai/custom/alarm/condition/AlarmLevel.java b/src/main/java/com/eactive/eai/custom/alarm/condition/AlarmLevel.java new file mode 100644 index 0000000..f88986a --- /dev/null +++ b/src/main/java/com/eactive/eai/custom/alarm/condition/AlarmLevel.java @@ -0,0 +1,5 @@ +package com.eactive.eai.custom.alarm.condition; + +public enum AlarmLevel { + ERROR, WARN, FATAL +} diff --git a/src/main/java/com/eactive/eai/custom/alarm/event/AlarmEvent.java b/src/main/java/com/eactive/eai/custom/alarm/event/AlarmEvent.java new file mode 100644 index 0000000..1d29a3f --- /dev/null +++ b/src/main/java/com/eactive/eai/custom/alarm/event/AlarmEvent.java @@ -0,0 +1,37 @@ +package com.eactive.eai.custom.alarm.event; + +import java.util.Objects; + +import com.eactive.eai.custom.alarm.condition.AlarmCondition; +import com.eactive.eai.custom.alarm.key.AlarmKey; + +import lombok.Builder; +import lombok.Getter; +import lombok.Setter; + +@Setter +@Getter +@Builder +public class AlarmEvent { + AlarmKey key; + AlarmCondition condition; + String message; + + public void onOcurr() { + condition.onOcurr(); + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (!(o instanceof AlarmEvent)) return false; + + AlarmEvent that = (AlarmEvent) o; + return Objects.equals(this.key, that.key); + } + + @Override + public int hashCode() { + return Objects.hash(key); + } +} diff --git a/src/main/java/com/eactive/eai/custom/alarm/key/AlarmKey.java b/src/main/java/com/eactive/eai/custom/alarm/key/AlarmKey.java new file mode 100644 index 0000000..c81778a --- /dev/null +++ b/src/main/java/com/eactive/eai/custom/alarm/key/AlarmKey.java @@ -0,0 +1,5 @@ +package com.eactive.eai.custom.alarm.key; + +public interface AlarmKey { + String code(); +} diff --git a/src/main/java/com/eactive/eai/custom/alarm/key/CoreAlarmKey.java b/src/main/java/com/eactive/eai/custom/alarm/key/CoreAlarmKey.java new file mode 100644 index 0000000..eae718b --- /dev/null +++ b/src/main/java/com/eactive/eai/custom/alarm/key/CoreAlarmKey.java @@ -0,0 +1,9 @@ +package com.eactive.eai.custom.alarm.key; +public enum CoreAlarmKey implements AlarmKey { + CircuitBreaker; + + @Override + public String code() { + return name(); + } +} \ No newline at end of file diff --git a/src/main/java/com/eactive/eai/custom/alarm/key/DynamicAlarmKey.java b/src/main/java/com/eactive/eai/custom/alarm/key/DynamicAlarmKey.java new file mode 100644 index 0000000..c26298b --- /dev/null +++ b/src/main/java/com/eactive/eai/custom/alarm/key/DynamicAlarmKey.java @@ -0,0 +1,30 @@ +package com.eactive.eai.custom.alarm.key; + +public final class DynamicAlarmKey implements AlarmKey { + + private final String code; + + public DynamicAlarmKey(String code) { + if (code == null || code.isEmpty()) { + throw new IllegalArgumentException("AlarmKey code must not be empty"); + } + this.code = code; + } + + @Override + public String code() { + return code; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (!(o instanceof AlarmKey)) return false; + return code.equals(((AlarmKey) o).code()); + } + + @Override + public int hashCode() { + return code.hashCode(); + } +} \ No newline at end of file diff --git a/src/main/java/com/eactive/eai/custom/alarm/policy/AlarmPolicy.java b/src/main/java/com/eactive/eai/custom/alarm/policy/AlarmPolicy.java new file mode 100644 index 0000000..2f42186 --- /dev/null +++ b/src/main/java/com/eactive/eai/custom/alarm/policy/AlarmPolicy.java @@ -0,0 +1,83 @@ +package com.eactive.eai.custom.alarm.policy; + +import com.eactive.eai.custom.alarm.event.AlarmEvent; +import com.eactive.eai.custom.alarm.key.AlarmKey; + +public abstract class AlarmPolicy { + + private AlarmKey alarmKey; + + private int thresholdCount; + + private long timeWindowMs; + + private long coolDownMs; + + protected AlarmPolicy(Builder builder) { + this.alarmKey = builder.alarmKey; + this.thresholdCount = builder.thresholdCount; + this.timeWindowMs = builder.timeWindowMs; + this.coolDownMs = builder.coolDownMs; + } + + public AlarmKey getAlarmKey() { + return alarmKey; + } + + public int getThresholdCount() { + return thresholdCount; + } + + public long getTimeWindowMs() { + return timeWindowMs; + } + + public long getCoolDownMs() { + return coolDownMs; + } + + abstract boolean isAlarmTriggered(AlarmEvent event); + + public boolean hasElapsed(long baseTimeMs, long currentTimeMs) { + + return currentTimeMs - baseTimeMs >= timeWindowMs; + + } + + public boolean hasExceededLimit(long count) { + return count >= thresholdCount; + } + + public abstract static class Builder> { + + private AlarmKey alarmKey; + private int thresholdCount; + private long timeWindowMs; + private long coolDownMs; + + public T alarmKey(AlarmKey alarmKey) { + this.alarmKey = alarmKey; + return self(); + } + + public T thresholdCount(int thresholdCount) { + this.thresholdCount = thresholdCount; + return self(); + } + + public T timeWindowMs(long timeWindowMs) { + this.timeWindowMs = timeWindowMs; + return self(); + } + + public T coolDownMs(long coolDownMs) { + this.coolDownMs = coolDownMs; + return self(); + } + + protected abstract T self(); + + abstract AlarmPolicy build(); + } + +} \ No newline at end of file diff --git a/src/main/java/com/eactive/eai/custom/alarm/policy/AlarmType.java b/src/main/java/com/eactive/eai/custom/alarm/policy/AlarmType.java new file mode 100644 index 0000000..547eaf2 --- /dev/null +++ b/src/main/java/com/eactive/eai/custom/alarm/policy/AlarmType.java @@ -0,0 +1,5 @@ +package com.eactive.eai.custom.alarm.policy; + +public enum AlarmType { + COUNT, TIMER +} diff --git a/src/main/java/com/eactive/eai/custom/alarm/policy/CounterPolicy.java b/src/main/java/com/eactive/eai/custom/alarm/policy/CounterPolicy.java new file mode 100644 index 0000000..97f763d --- /dev/null +++ b/src/main/java/com/eactive/eai/custom/alarm/policy/CounterPolicy.java @@ -0,0 +1,39 @@ +package com.eactive.eai.custom.alarm.policy; + +import com.eactive.eai.custom.alarm.event.AlarmEvent; + +public class CounterPolicy extends AlarmPolicy { + + private CounterPolicy(Builder builder) { + super(builder); + } + + @Override + boolean isAlarmTriggered(AlarmEvent event) { + + if (!event.equals(getAlarmKey())) { + return false; + } + + long count = event.getCondition().getCount(); + return hasExceededLimit(count); + } + + public static Builder builder() { + return new Builder(); + } + + public static class Builder extends AlarmPolicy.Builder { + + @Override + protected Builder self() { + return this; + } + + @Override + public CounterPolicy build() { + return new CounterPolicy(this); + } + } + +} diff --git a/src/main/java/com/eactive/eai/custom/alarm/policy/TimerPolicy.java b/src/main/java/com/eactive/eai/custom/alarm/policy/TimerPolicy.java new file mode 100644 index 0000000..b56dde7 --- /dev/null +++ b/src/main/java/com/eactive/eai/custom/alarm/policy/TimerPolicy.java @@ -0,0 +1,52 @@ +package com.eactive.eai.custom.alarm.policy; + +import com.eactive.eai.custom.alarm.condition.AlarmCondition; +import com.eactive.eai.custom.alarm.event.AlarmEvent; +import com.eactive.eai.custom.alarm.policy.CounterPolicy.Builder; + +public class TimerPolicy extends AlarmPolicy { + + private TimerPolicy(Builder builder) { + super(builder); + } + + @Override + boolean isAlarmTriggered(AlarmEvent event) { + + if (event.equals(getAlarmKey())) { + + AlarmCondition condition = event.getCondition(); + + long baseTimeMs = condition.getOcurredAt(); + long lastTimeMs = condition.getLastOcurredAt(); + + if (hasElapsed(baseTimeMs, lastTimeMs)) { + return true; + } else { + return false; + } + + } + + return false; + + } + + public static Builder builder() { + return new Builder(); + } + + public static class Builder extends AlarmPolicy.Builder { + + @Override + protected Builder self() { + return this; + } + + @Override + public TimerPolicy build() { + return new TimerPolicy(this); + } + } + +} From 77e1ccb16eb26febfcb3e8fa9e6621874f5058f5 Mon Sep 17 00:00:00 2001 From: jaewohong Date: Fri, 6 Feb 2026 10:13:10 +0900 Subject: [PATCH 133/159] asyn in to out header relay --- .../filter/HttpAdapterFilterFactoryKjb.java | 3 + .../dynamic/filter/HttpAdapterFilterType.java | 1 + .../filter/ReflectAllHeaderFilter.java | 96 +++++++++++++++++++ 3 files changed, 100 insertions(+) create mode 100644 src/main/java/com/eactive/eai/adapter/http/dynamic/filter/ReflectAllHeaderFilter.java diff --git a/src/main/java/com/eactive/eai/adapter/http/dynamic/filter/HttpAdapterFilterFactoryKjb.java b/src/main/java/com/eactive/eai/adapter/http/dynamic/filter/HttpAdapterFilterFactoryKjb.java index 977f92f..1b3f0c1 100644 --- a/src/main/java/com/eactive/eai/adapter/http/dynamic/filter/HttpAdapterFilterFactoryKjb.java +++ b/src/main/java/com/eactive/eai/adapter/http/dynamic/filter/HttpAdapterFilterFactoryKjb.java @@ -36,6 +36,9 @@ public class HttpAdapterFilterFactoryKjb extends HttpAdapterFilterFactory { case HMAC_SHA256: filter = new HmacSha256VerifyFilterKjb(); break; + case REFLECTALLHEADER: + filter = new ReflectAllHeaderFilter(); + break; default: filter = classForName(type); if (filter == null) { diff --git a/src/main/java/com/eactive/eai/adapter/http/dynamic/filter/HttpAdapterFilterType.java b/src/main/java/com/eactive/eai/adapter/http/dynamic/filter/HttpAdapterFilterType.java index c522614..b22dc60 100644 --- a/src/main/java/com/eactive/eai/adapter/http/dynamic/filter/HttpAdapterFilterType.java +++ b/src/main/java/com/eactive/eai/adapter/http/dynamic/filter/HttpAdapterFilterType.java @@ -6,6 +6,7 @@ public enum HttpAdapterFilterType { IPWHITELISTFILTER, ADAPTERALLOWIPLISTFILTER, HMAC_SHA256, + REFLECTALLHEADER, UNKNOWN; public static HttpAdapterFilterType getValue(String type) { diff --git a/src/main/java/com/eactive/eai/adapter/http/dynamic/filter/ReflectAllHeaderFilter.java b/src/main/java/com/eactive/eai/adapter/http/dynamic/filter/ReflectAllHeaderFilter.java new file mode 100644 index 0000000..ca0633e --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/http/dynamic/filter/ReflectAllHeaderFilter.java @@ -0,0 +1,96 @@ +package com.eactive.eai.adapter.http.dynamic.filter; + +import java.util.Enumeration; +import java.util.Properties; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import org.apache.commons.lang3.StringUtils; +import com.eactive.eai.common.util.Logger; +import com.eactive.eai.common.property.PropManager; + +import java.util.Arrays; +import java.util.stream.Stream; + +public class ReflectAllHeaderFilter implements HttpAdapterFilter { + + public ReflectAllHeaderFilter() { + super(); + } + + protected static Logger logger = Logger.getLogger(Logger.LOGGER_ADAPTER); + + public static final String PROPERTIES_GROUP_NAME = "HttpHeaderFilter"; + public static final String HEADER_KEY_NAMES = "AllHeaderFilter.blackList"; + + String[] HttpHeaderRelayBlackList = { + "Content-Length", + "Transfer-Encoding", + "Host", + "Authorization", + "Accept", + "Host", + "Cookie", + "Connection", + "Keep-Alive", + "Proxy-Authenticate", + "Proxy-Authorization", + "TE", + "Trailer", + "Transfer-Encoding", + "Upgrade", + "Content-Type", + "Content-Encoding", + "Content-Language", + "Content-Location", + "Content-MD5", + "Expect", + }; + + + @Override + public Object doPreFilter(String adptGrpName, String adptName, Object message, Properties prop, + HttpServletRequest request, HttpServletResponse response) throws Exception { + return message; + } + + @Override + public Object doPostFilter(String adptGrpName, String adptName, Object resultMessage, Properties prop, + HttpServletRequest request, HttpServletResponse response) throws Exception { + + logger.debug("doPreFilter ReflectAllHeaderFilter Start."); + + String propValue = PropManager.getInstance().getProperty(PROPERTIES_GROUP_NAME, HEADER_KEY_NAMES, "").trim(); + String[] userSettingBlackList = propValue.split(","); + + if( userSettingBlackList.length > 0 ) { + HttpHeaderRelayBlackList = Stream + .concat(Arrays.stream(HttpHeaderRelayBlackList), Arrays.stream(userSettingBlackList)) + .toArray(String[]::new); + } + + try { + Enumeration headerNames = request.getHeaderNames(); + while (headerNames.hasMoreElements()) { + + String headerName = headerNames.nextElement(); + String headerValue = request.getHeader(headerName); + + if( StringUtils.equalsAnyIgnoreCase( headerName, HttpHeaderRelayBlackList ) ) { + logger.debug("Skip Processing Key ["+headerName+"], value ["+headerValue+"] in HttpHeaderRelayBlackList"); + continue; + } + + response.setHeader(headerName, headerValue); + } + + } catch (Exception e) { + logger.error(e.getMessage()); + } + + logger.debug("doPreFilter ReflectAllHeaderFilter End."); + + return resultMessage; + } +} + From 94b22aa90f2582a1e55755b69dca7b254ac5adae Mon Sep 17 00:00:00 2001 From: cho Date: Fri, 6 Feb 2026 11:55:27 +0900 Subject: [PATCH 134/159] =?UTF-8?q?=EC=9D=B4=EB=B2=A4=ED=8A=B8=20=EC=84=B1?= =?UTF-8?q?=EA=B2=A9=EC=97=90=20=EB=94=B0=EB=9D=BC=20=EB=B0=9C=EC=86=A1?= =?UTF-8?q?=EC=A0=95=EC=B1=85(SendPolicy)=EB=A5=BC=20=EB=91=90=EA=B3=A0=20?= =?UTF-8?q?=EA=B7=B8=EC=97=90=20=EB=94=B0=EB=9D=BC=20UMS=EC=97=B0=EA=B3=84?= =?UTF-8?q?=ED=95=98=EC=97=AC=20=EB=AC=B8=EC=9E=90=EB=A9=94=EC=84=B8?= =?UTF-8?q?=EC=A7=80=20=EB=B0=9C=EC=86=A1=ED=95=98=EB=8F=84=EB=A1=9D=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit UMS playload관련 패키지 이동. --- .../eai/custom/alarm/AlarmService.java | 68 +++++++-- .../eai/custom/alarm/AlarmStateManager.java | 144 +++++++++++------- .../alarm/condition/AlarmCondition.java | 5 +- .../eai/custom/alarm/event/AlarmEvent.java | 4 + .../eai/custom/alarm/key/CoreAlarmKey.java | 15 +- .../eai/custom/alarm/policy/AlarmPolicy.java | 8 +- .../custom/alarm/policy/CounterPolicy.java | 2 +- .../eai/custom/alarm/policy/SendPolicy.java | 22 +++ .../eai/custom/alarm/policy/TimerPolicy.java | 5 +- .../eai/custom/alarm/ums/UmsSendManager.java | 62 ++++++++ .../eai/custom/alarm/ums/UmsService.java | 24 ++- .../ums/{ => payload}/IUmsGsonObject.java | 2 +- .../ObpMonitoringUmsTemplate.java | 2 +- .../ums/{ => payload}/UmsBizWorkCode.java | 2 +- .../ums/{ => payload}/UmsRequestPayload.java | 8 +- .../ums/{ => payload}/ValidationUtil.java | 2 +- .../{ => payload}/VerifyPhoneUmsTemplate.java | 2 +- 17 files changed, 277 insertions(+), 100 deletions(-) create mode 100644 src/main/java/com/eactive/eai/custom/alarm/policy/SendPolicy.java create mode 100644 src/main/java/com/eactive/eai/custom/alarm/ums/UmsSendManager.java rename src/main/java/com/eactive/eai/custom/alarm/ums/{ => payload}/IUmsGsonObject.java (59%) rename src/main/java/com/eactive/eai/custom/alarm/ums/{ => payload}/ObpMonitoringUmsTemplate.java (83%) rename src/main/java/com/eactive/eai/custom/alarm/ums/{ => payload}/UmsBizWorkCode.java (88%) rename src/main/java/com/eactive/eai/custom/alarm/ums/{ => payload}/UmsRequestPayload.java (91%) rename src/main/java/com/eactive/eai/custom/alarm/ums/{ => payload}/ValidationUtil.java (97%) rename src/main/java/com/eactive/eai/custom/alarm/ums/{ => payload}/VerifyPhoneUmsTemplate.java (82%) diff --git a/src/main/java/com/eactive/eai/custom/alarm/AlarmService.java b/src/main/java/com/eactive/eai/custom/alarm/AlarmService.java index 6f28796..cc07095 100644 --- a/src/main/java/com/eactive/eai/custom/alarm/AlarmService.java +++ b/src/main/java/com/eactive/eai/custom/alarm/AlarmService.java @@ -1,9 +1,11 @@ package com.eactive.eai.custom.alarm; -import java.util.ArrayList; import java.util.Arrays; +import java.util.Collection; import java.util.Collections; +import java.util.HashMap; import java.util.List; +import java.util.Map; import java.util.Optional; import java.util.Properties; @@ -12,11 +14,12 @@ import org.springframework.stereotype.Service; import com.eactive.eai.common.property.PropManager; import com.eactive.eai.common.util.Jsons; import com.eactive.eai.common.util.Logger; +import com.eactive.eai.custom.alarm.key.AlarmKey; import com.eactive.eai.custom.alarm.key.DynamicAlarmKey; import com.eactive.eai.custom.alarm.policy.AlarmPolicy; import com.eactive.eai.custom.alarm.policy.CounterPolicy; +import com.eactive.eai.custom.alarm.policy.SendPolicy; import com.eactive.eai.custom.alarm.policy.TimerPolicy; -import com.google.gson.Gson; import com.google.gson.JsonObject; @Service @@ -28,9 +31,9 @@ public class AlarmService { final static String ALARM_KEY = "Alarm"; final static String ALARM_RECIVER = "{RECIVER}"; - public List getAlarmPolicy() { + public Map getAlarmPolicy() { - List policyList = new ArrayList(); + Map policyMap = new HashMap(); try { @@ -40,22 +43,24 @@ public class AlarmService { String keyName = (String) key; String configStr = (String) value; - if (keyName.contains(ALARM_RECIVER)) - return; + if (keyName.contains(ALARM_RECIVER)) return; - policyList.add(buildAlarmPolicy(keyName, configStr)); + AlarmPolicy newPolicy = buildAlarmPolicy(keyName, configStr); + + + policyMap.put(newPolicy.getAlarmKey(), newPolicy); }); } catch (Exception e) { - logger.error("getAlarmPolicy fail.", e); - return Collections.EMPTY_LIST; + logger.warn("getAlarmPolicy fail.", e); + return Collections.EMPTY_MAP; } - return null; + return policyMap; } - AlarmPolicy buildAlarmPolicy(String key, String configJsonStr) { + private AlarmPolicy buildAlarmPolicy(String key, String configJsonStr) { JsonObject alarmConfig = Jsons.GSON.fromJson(configJsonStr, JsonObject.class); @@ -77,4 +82,45 @@ public class AlarmService { return alarmPolicy; } + + public Map getSendPolicy() { + + Map policyMap = new HashMap(); + + try { + + Properties props = PropManager.getInstance().getProperties(ALARM_GROUP); + + props.forEach((key, value) -> { + String keyName = (String) key; + String configStr = (String) value; + + if (!keyName.contains(ALARM_RECIVER)) return; + + SendPolicy newPolicy = buildSendPolicy(keyName, configStr); + + + policyMap.put(newPolicy.getAlarmKey(), newPolicy); + + }); + + } catch (Exception e) { + logger.warn("getSendPolicy fail.", e); + return Collections.EMPTY_MAP; + } + + return policyMap; + } + + private SendPolicy buildSendPolicy(String key, String configStr) { + + List reciverList = Optional.ofNullable(configStr).map( t -> Arrays.asList(t.split(",")) ).orElse(Collections.EMPTY_LIST); + + key = key.replaceAll(ALARM_RECIVER, "").trim(); + + SendPolicy sendPolicy = new SendPolicy(key, reciverList); + + return sendPolicy; + + } } diff --git a/src/main/java/com/eactive/eai/custom/alarm/AlarmStateManager.java b/src/main/java/com/eactive/eai/custom/alarm/AlarmStateManager.java index 8d4bfd8..ef0e5ed 100644 --- a/src/main/java/com/eactive/eai/custom/alarm/AlarmStateManager.java +++ b/src/main/java/com/eactive/eai/custom/alarm/AlarmStateManager.java @@ -2,77 +2,117 @@ package com.eactive.eai.custom.alarm; import java.util.ArrayList; import java.util.List; +import java.util.Map; import java.util.Optional; import java.util.concurrent.Executors; import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.TimeUnit; +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; import com.eactive.eai.common.util.Logger; import com.eactive.eai.custom.alarm.event.AlarmEvent; +import com.eactive.eai.custom.alarm.key.AlarmKey; +import com.eactive.eai.custom.alarm.policy.AlarmPolicy; +import com.eactive.eai.custom.alarm.policy.CounterPolicy; +import com.eactive.eai.custom.alarm.policy.SendPolicy; +import com.eactive.eai.custom.alarm.ums.UmsService; +import com.eactive.eai.custom.alarm.ums.payload.IUmsGsonObject; +import com.eactive.eai.custom.alarm.ums.payload.ObpMonitoringUmsTemplate; +import com.eactive.eai.custom.alarm.ums.payload.UmsRequestPayload; @Component public class AlarmStateManager { - - - List registerAlarmList = new ArrayList(); - - private final ScheduledExecutorService scheduler; - - protected static Logger logger = Logger.getLogger(Logger.LOGGER_DEFAULT); - - - public AlarmStateManager() { - - this.scheduler = Executors.newSingleThreadScheduledExecutor(r -> { - Thread t = new Thread(r); - t.setName("AlarmStateManager-worker"); - t.setDaemon(false); - return t; - }); - - scheduler.scheduleWithFixedDelay(() -> { - try { - // === 여기에 지속 실행할 로직 === - fireAlarm(); + List registerAlarmList = new ArrayList(); - } catch (Throwable e) { - // 반드시 예외 잡기 (안 잡으면 스케줄 자체가 죽음) - logger.error("fireAlarm fail", e); - } + private final ScheduledExecutorService scheduler; - }, 0, 5, TimeUnit.SECONDS); // 최초 0초, 이후 5초 간격 + protected static Logger logger = Logger.getLogger(Logger.LOGGER_DEFAULT); + + @Autowired + AlarmService alarmService; + + @Autowired + UmsService usmService; + + public AlarmStateManager() { + + this.scheduler = Executors.newSingleThreadScheduledExecutor(r -> { + Thread t = new Thread(r); + t.setName("AlarmStateManager-worker"); + t.setDaemon(false); + return t; + }); + + scheduler.scheduleWithFixedDelay(() -> { + + try { + // === 여기에 지속 실행할 로직 === + fireAlarm(); + + } catch (Throwable e) { + // 반드시 예외 잡기 (안 잡으면 스케줄 자체가 죽음) + logger.error("fireAlarm fail", e); + } + + }, 0, 5, TimeUnit.SECONDS); // 최초 0초, 이후 5초 간격 + } + + public void onEvnet(AlarmEvent alaramEvent) { + + Optional existEvent = registerAlarmList.stream().filter(e -> e.equals(alaramEvent)).findFirst(); + + if (existEvent.isPresent()) { + AlarmEvent event = existEvent.get(); + event.onOcurr(); + } else { + registerAlarmList.add(alaramEvent); } - - - public void onEvnet(AlarmEvent alaramEvent) { - - Optional existEvent = - registerAlarmList.stream() - .filter(e -> e.equals(alaramEvent)) - .findFirst(); - if (existEvent.isPresent()) { - AlarmEvent event = existEvent.get(); - event.onOcurr(); - } else { - registerAlarmList.add(alaramEvent); - } + } + + private void fireAlarm() { + + Map alarmPolicyMap = alarmService.getAlarmPolicy(); + Map sendPolicyMap = alarmService.getSendPolicy(); + + for (AlarmEvent event : registerAlarmList) { + + AlarmPolicy alarmPolicy = alarmPolicyMap.get(event.getKey()); + + if (alarmPolicy.isAlarmTriggered(event)) { + + SendPolicy sendPolicy = sendPolicyMap.get(event.getKey()); + + } } - - private void fireAlarm() { - - for(AlarmEvent event : registerAlarmList) { - - - - } - + + } + + private void send(SendPolicy sendPolicy, AlarmEvent event) { + + UmsRequestPayload payload = null; + + try { + + List cellPhoneList = sendPolicy.getCellpohoneList(); + + for (String cellPhone : cellPhoneList) { + + payload = UmsRequestPayload.builder() + .content(ObpMonitoringUmsTemplate.builder().message(event.getMessage()).build()) + .cellphone(cellPhone).build(); + + usmService.send(payload); + } + + } catch (Exception e) { + logger.error(String.format("Alarm message delivery failed (UMS), payload=%s", payload), e); + } - - + } } \ No newline at end of file diff --git a/src/main/java/com/eactive/eai/custom/alarm/condition/AlarmCondition.java b/src/main/java/com/eactive/eai/custom/alarm/condition/AlarmCondition.java index 7d852f4..996dbd0 100644 --- a/src/main/java/com/eactive/eai/custom/alarm/condition/AlarmCondition.java +++ b/src/main/java/com/eactive/eai/custom/alarm/condition/AlarmCondition.java @@ -6,9 +6,8 @@ import lombok.Getter; @Builder @Getter public class AlarmCondition { - AlarmLevel level; - final long ocurredAt; - long lastOcurredAt; + final long ocurredAt = System.currentTimeMillis(); + long lastOcurredAt; // 일단, 미사용 long count = 1; public void onOcurr() { diff --git a/src/main/java/com/eactive/eai/custom/alarm/event/AlarmEvent.java b/src/main/java/com/eactive/eai/custom/alarm/event/AlarmEvent.java index 1d29a3f..fa435b8 100644 --- a/src/main/java/com/eactive/eai/custom/alarm/event/AlarmEvent.java +++ b/src/main/java/com/eactive/eai/custom/alarm/event/AlarmEvent.java @@ -4,6 +4,8 @@ import java.util.Objects; import com.eactive.eai.custom.alarm.condition.AlarmCondition; import com.eactive.eai.custom.alarm.key.AlarmKey; +import com.eactive.eai.custom.alarm.policy.AlarmPolicy; +import com.eactive.eai.custom.alarm.policy.CounterPolicy; import lombok.Builder; import lombok.Getter; @@ -34,4 +36,6 @@ public class AlarmEvent { public int hashCode() { return Objects.hash(key); } + + } diff --git a/src/main/java/com/eactive/eai/custom/alarm/key/CoreAlarmKey.java b/src/main/java/com/eactive/eai/custom/alarm/key/CoreAlarmKey.java index eae718b..70c5027 100644 --- a/src/main/java/com/eactive/eai/custom/alarm/key/CoreAlarmKey.java +++ b/src/main/java/com/eactive/eai/custom/alarm/key/CoreAlarmKey.java @@ -1,9 +1,12 @@ package com.eactive.eai.custom.alarm.key; -public enum CoreAlarmKey implements AlarmKey { - CircuitBreaker; - @Override - public String code() { - return name(); - } +public final class CoreAlarmKey { + + private CoreAlarmKey() { } + + public static final AlarmKey CircuitBreaker = new DynamicAlarmKey("CircuitBreaker"); + + public static final AlarmKey Timeout = new DynamicAlarmKey("Timeout"); + + } \ No newline at end of file diff --git a/src/main/java/com/eactive/eai/custom/alarm/policy/AlarmPolicy.java b/src/main/java/com/eactive/eai/custom/alarm/policy/AlarmPolicy.java index 2f42186..d1230b6 100644 --- a/src/main/java/com/eactive/eai/custom/alarm/policy/AlarmPolicy.java +++ b/src/main/java/com/eactive/eai/custom/alarm/policy/AlarmPolicy.java @@ -1,5 +1,6 @@ package com.eactive.eai.custom.alarm.policy; +import com.eactive.eai.custom.alarm.condition.AlarmCondition; import com.eactive.eai.custom.alarm.event.AlarmEvent; import com.eactive.eai.custom.alarm.key.AlarmKey; @@ -36,11 +37,12 @@ public abstract class AlarmPolicy { return coolDownMs; } - abstract boolean isAlarmTriggered(AlarmEvent event); + public abstract boolean isAlarmTriggered(AlarmEvent event); + - public boolean hasElapsed(long baseTimeMs, long currentTimeMs) { + public boolean hasElapsed(long baseTimeMs) { - return currentTimeMs - baseTimeMs >= timeWindowMs; + return System.currentTimeMillis() - baseTimeMs >= timeWindowMs; } diff --git a/src/main/java/com/eactive/eai/custom/alarm/policy/CounterPolicy.java b/src/main/java/com/eactive/eai/custom/alarm/policy/CounterPolicy.java index 97f763d..65d3f7f 100644 --- a/src/main/java/com/eactive/eai/custom/alarm/policy/CounterPolicy.java +++ b/src/main/java/com/eactive/eai/custom/alarm/policy/CounterPolicy.java @@ -9,7 +9,7 @@ public class CounterPolicy extends AlarmPolicy { } @Override - boolean isAlarmTriggered(AlarmEvent event) { + public boolean isAlarmTriggered(AlarmEvent event) { if (!event.equals(getAlarmKey())) { return false; diff --git a/src/main/java/com/eactive/eai/custom/alarm/policy/SendPolicy.java b/src/main/java/com/eactive/eai/custom/alarm/policy/SendPolicy.java new file mode 100644 index 0000000..945881d --- /dev/null +++ b/src/main/java/com/eactive/eai/custom/alarm/policy/SendPolicy.java @@ -0,0 +1,22 @@ +package com.eactive.eai.custom.alarm.policy; + +import java.util.ArrayList; +import java.util.List; + +import com.eactive.eai.custom.alarm.key.AlarmKey; +import com.eactive.eai.custom.alarm.key.DynamicAlarmKey; + +import lombok.Getter; + +@Getter +public class SendPolicy { + + final AlarmKey alarmKey; + + final List cellpohoneList = new ArrayList(); + + public SendPolicy(String alarmKey, List cellPhoneList) { + this.alarmKey = new DynamicAlarmKey(alarmKey); + } + +} diff --git a/src/main/java/com/eactive/eai/custom/alarm/policy/TimerPolicy.java b/src/main/java/com/eactive/eai/custom/alarm/policy/TimerPolicy.java index b56dde7..0a51b02 100644 --- a/src/main/java/com/eactive/eai/custom/alarm/policy/TimerPolicy.java +++ b/src/main/java/com/eactive/eai/custom/alarm/policy/TimerPolicy.java @@ -11,16 +11,15 @@ public class TimerPolicy extends AlarmPolicy { } @Override - boolean isAlarmTriggered(AlarmEvent event) { + public boolean isAlarmTriggered(AlarmEvent event) { if (event.equals(getAlarmKey())) { AlarmCondition condition = event.getCondition(); long baseTimeMs = condition.getOcurredAt(); - long lastTimeMs = condition.getLastOcurredAt(); - if (hasElapsed(baseTimeMs, lastTimeMs)) { + if (hasElapsed(baseTimeMs)) { return true; } else { return false; diff --git a/src/main/java/com/eactive/eai/custom/alarm/ums/UmsSendManager.java b/src/main/java/com/eactive/eai/custom/alarm/ums/UmsSendManager.java new file mode 100644 index 0000000..dfab3b5 --- /dev/null +++ b/src/main/java/com/eactive/eai/custom/alarm/ums/UmsSendManager.java @@ -0,0 +1,62 @@ +package com.eactive.eai.custom.alarm.ums; + +import java.util.Queue; +import java.util.concurrent.ConcurrentLinkedQueue; +import java.util.concurrent.Executors; +import java.util.concurrent.ScheduledExecutorService; +import java.util.concurrent.TimeUnit; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import com.eactive.eai.common.util.Logger; +import com.eactive.eai.custom.alarm.ums.payload.UmsRequestPayload; + +@Component +public class UmsSendManager { + + private final ScheduledExecutorService scheduler; + + protected static Logger logger = Logger.getLogger(Logger.LOGGER_DEFAULT); + + Queue queue = new ConcurrentLinkedQueue(); + + @Autowired + UmsService umsService; + + public UmsSendManager() { + this.scheduler = Executors.newSingleThreadScheduledExecutor(r -> { + Thread t = new Thread(r); + t.setName("AlarmStateManager-worker"); + t.setDaemon(false); + return t; + }); + + scheduler.scheduleWithFixedDelay(() -> { + + try { + // === 여기에 지속 실행할 로직 === + sendMessage(); + + } catch (Throwable e) { + // 반드시 예외 잡기 (안 잡으면 스케줄 자체가 죽음) + logger.error("fireAlarm fail", e); + } + + }, 0, 5, TimeUnit.SECONDS); // 최초 0초, 이후 5초 간격 + } + + void sendMessage() throws Exception { + UmsRequestPayload payload; + while ((payload = queue.poll()) != null) { + umsService.send(payload); + } + + } + + public void enqueue(UmsRequestPayload payload) { + queue.offer(payload); + } + + +} diff --git a/src/main/java/com/eactive/eai/custom/alarm/ums/UmsService.java b/src/main/java/com/eactive/eai/custom/alarm/ums/UmsService.java index 08b6135..4b1b981 100644 --- a/src/main/java/com/eactive/eai/custom/alarm/ums/UmsService.java +++ b/src/main/java/com/eactive/eai/custom/alarm/ums/UmsService.java @@ -2,8 +2,6 @@ package com.eactive.eai.custom.alarm.ums; import java.io.IOException; import java.nio.charset.Charset; -import java.time.LocalDateTime; -import java.time.format.DateTimeFormatter; import java.util.Arrays; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; @@ -21,8 +19,10 @@ import org.apache.hc.core5.util.Timeout; import org.springframework.stereotype.Component; import org.springframework.util.StreamUtils; +import com.eactive.eai.common.util.Jsons; import com.eactive.eai.common.util.Logger; -import com.google.gson.Gson; +import com.eactive.eai.custom.alarm.ums.payload.UmsRequestPayload; +import com.eactive.eai.custom.alarm.ums.payload.ValidationUtil; import com.google.gson.JsonSyntaxException; @Component @@ -36,18 +36,16 @@ public class UmsService { private final static String CONTENT_TYPE = "application/json; charset=utf-8"; private final static String AUTHORIZATION_FMT = "Bearer %s"; - Future send(String cpno, String message, UmsBizWorkCode code) throws Exception { + public Future send(UmsRequestPayload payload) throws Exception { - if (message == null) { + if (payload.getContent() == null) { throw new IllegalArgumentException("content is null"); } - String guid = String.format("APM-%s", - DateTimeFormatter.ofPattern("yyyyMMddHHmmssSSS").format(LocalDateTime.now())); - UmsRequestPayload payload = UmsRequestPayload.builder().messageIdentityNo(guid).msgBizWorkCode(code.getCode()) - .content(ObpMonitoringUmsTemplate.builder().message(message).build()).cellphone(cpno) - .msgSndChnlCd(UmsRequestPayload.ChannelCode.KM).build(); +// UmsRequestPayload payload = UmsRequestPayload.builder() +// .content(ObpMonitoringUmsTemplate.builder().message(message).build()).cellphone(cpno) +// .build(); try { ValidationUtil.validateOrThrow(payload); @@ -66,8 +64,8 @@ public class UmsService { private Future call(String url, UmsRequestPayload requestPayload) throws Exception { ExecutorService executor = Executors.newSingleThreadExecutor(); - Gson gson = new Gson(); - String json = gson.toJson(requestPayload); + + String json = Jsons.GSON.toJson(requestPayload); HttpPost httpPost = new HttpPost(UMS_URL + url); httpPost.setHeader("Content-Type", CONTENT_TYPE); @@ -97,7 +95,7 @@ public class UmsService { if (logger.isDebugEnabled()) { logger.debug("Response - {}", body); } - result = gson.fromJson(body, UmsCallResult.class); + result = Jsons.GSON.fromJson(body, UmsCallResult.class); result.setUmsMessageId(requestPayload.getMessageIdentityNo()); result.setSuccess(true); return result; diff --git a/src/main/java/com/eactive/eai/custom/alarm/ums/IUmsGsonObject.java b/src/main/java/com/eactive/eai/custom/alarm/ums/payload/IUmsGsonObject.java similarity index 59% rename from src/main/java/com/eactive/eai/custom/alarm/ums/IUmsGsonObject.java rename to src/main/java/com/eactive/eai/custom/alarm/ums/payload/IUmsGsonObject.java index 58037b1..a1b7220 100644 --- a/src/main/java/com/eactive/eai/custom/alarm/ums/IUmsGsonObject.java +++ b/src/main/java/com/eactive/eai/custom/alarm/ums/payload/IUmsGsonObject.java @@ -1,4 +1,4 @@ -package com.eactive.eai.custom.alarm.ums; +package com.eactive.eai.custom.alarm.ums.payload; /** * GSON Serialize 용 Object diff --git a/src/main/java/com/eactive/eai/custom/alarm/ums/ObpMonitoringUmsTemplate.java b/src/main/java/com/eactive/eai/custom/alarm/ums/payload/ObpMonitoringUmsTemplate.java similarity index 83% rename from src/main/java/com/eactive/eai/custom/alarm/ums/ObpMonitoringUmsTemplate.java rename to src/main/java/com/eactive/eai/custom/alarm/ums/payload/ObpMonitoringUmsTemplate.java index 1570885..9f5af06 100644 --- a/src/main/java/com/eactive/eai/custom/alarm/ums/ObpMonitoringUmsTemplate.java +++ b/src/main/java/com/eactive/eai/custom/alarm/ums/payload/ObpMonitoringUmsTemplate.java @@ -1,4 +1,4 @@ -package com.eactive.eai.custom.alarm.ums; +package com.eactive.eai.custom.alarm.ums.payload; import com.google.gson.annotations.SerializedName; import lombok.Builder; diff --git a/src/main/java/com/eactive/eai/custom/alarm/ums/UmsBizWorkCode.java b/src/main/java/com/eactive/eai/custom/alarm/ums/payload/UmsBizWorkCode.java similarity index 88% rename from src/main/java/com/eactive/eai/custom/alarm/ums/UmsBizWorkCode.java rename to src/main/java/com/eactive/eai/custom/alarm/ums/payload/UmsBizWorkCode.java index 898f4b6..d669b23 100644 --- a/src/main/java/com/eactive/eai/custom/alarm/ums/UmsBizWorkCode.java +++ b/src/main/java/com/eactive/eai/custom/alarm/ums/payload/UmsBizWorkCode.java @@ -1,4 +1,4 @@ -package com.eactive.eai.custom.alarm.ums; +package com.eactive.eai.custom.alarm.ums.payload; import lombok.Getter; diff --git a/src/main/java/com/eactive/eai/custom/alarm/ums/UmsRequestPayload.java b/src/main/java/com/eactive/eai/custom/alarm/ums/payload/UmsRequestPayload.java similarity index 91% rename from src/main/java/com/eactive/eai/custom/alarm/ums/UmsRequestPayload.java rename to src/main/java/com/eactive/eai/custom/alarm/ums/payload/UmsRequestPayload.java index 6e11bd1..51fc6f6 100644 --- a/src/main/java/com/eactive/eai/custom/alarm/ums/UmsRequestPayload.java +++ b/src/main/java/com/eactive/eai/custom/alarm/ums/payload/UmsRequestPayload.java @@ -1,4 +1,4 @@ -package com.eactive.eai.custom.alarm.ums; +package com.eactive.eai.custom.alarm.ums.payload; import com.google.gson.annotations.SerializedName; import lombok.Builder; @@ -22,13 +22,15 @@ public class UmsRequestPayload { @Length(min = 1, max = 50) @NotEmpty @SerializedName("MSG_IDNT_NO") - private String messageIdentityNo; + @Builder.Default + private String messageIdentityNo = String.format("APM-%s",DateTimeFormatter.ofPattern("yyyyMMddHHmmssSSS").format(LocalDateTime.now())); // MSG_BZWK_CD string 메시지업무코드 30 O UMS에 등록된 메시지업무코드(AS-IS 템플릿ID) @NotEmpty @Length(min = 1, max = 30) @SerializedName("MSG_BZWK_CD") - private String msgBizWorkCode; + @Builder.Default + private String msgBizWorkCode = UmsBizWorkCode.MONITORING.getCode(); // 메시지업무파라미터내용 / 4000 / JSONObject // MSG_BZWK_PARAM_CTNT object 메시지업무파라미터내용 4000 메시지업무코드의 템플릿에서 사용하는 변수와 변수값 diff --git a/src/main/java/com/eactive/eai/custom/alarm/ums/ValidationUtil.java b/src/main/java/com/eactive/eai/custom/alarm/ums/payload/ValidationUtil.java similarity index 97% rename from src/main/java/com/eactive/eai/custom/alarm/ums/ValidationUtil.java rename to src/main/java/com/eactive/eai/custom/alarm/ums/payload/ValidationUtil.java index 7aacc4f..ecb8cf8 100644 --- a/src/main/java/com/eactive/eai/custom/alarm/ums/ValidationUtil.java +++ b/src/main/java/com/eactive/eai/custom/alarm/ums/payload/ValidationUtil.java @@ -1,4 +1,4 @@ -package com.eactive.eai.custom.alarm.ums; +package com.eactive.eai.custom.alarm.ums.payload; import java.util.Set; import java.util.stream.Collectors; diff --git a/src/main/java/com/eactive/eai/custom/alarm/ums/VerifyPhoneUmsTemplate.java b/src/main/java/com/eactive/eai/custom/alarm/ums/payload/VerifyPhoneUmsTemplate.java similarity index 82% rename from src/main/java/com/eactive/eai/custom/alarm/ums/VerifyPhoneUmsTemplate.java rename to src/main/java/com/eactive/eai/custom/alarm/ums/payload/VerifyPhoneUmsTemplate.java index 7af2586..4840fbf 100644 --- a/src/main/java/com/eactive/eai/custom/alarm/ums/VerifyPhoneUmsTemplate.java +++ b/src/main/java/com/eactive/eai/custom/alarm/ums/payload/VerifyPhoneUmsTemplate.java @@ -1,4 +1,4 @@ -package com.eactive.eai.custom.alarm.ums; +package com.eactive.eai.custom.alarm.ums.payload; import com.google.gson.annotations.SerializedName; import lombok.Builder; From 3d29407a47f7c46a039ba6b09af6739cca2aaf1c Mon Sep 17 00:00:00 2001 From: cho Date: Fri, 6 Feb 2026 13:37:48 +0900 Subject: [PATCH 135/159] =?UTF-8?q?AlarmStateManager=20=EC=8A=A4=ED=94=84?= =?UTF-8?q?=EB=A7=81bean=20=EC=95=84=EB=8B=8C=20=EA=B3=B3=EC=97=90=20?= =?UTF-8?q?=EC=82=AC=EC=9A=A9=ED=95=A0=EC=88=98=EC=9E=88=EB=8F=84=EB=A1=9D?= =?UTF-8?q?=20getAlarmStateManager()=20=EC=B6=94=EA=B0=80.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit RESTProcess에 circuitbreak시, 이벤트 전달하도록 수정. --- .../eai/custom/alarm/AlarmStateManager.java | 17 ++++++-- .../com/eactive/eai/outbound/RESTProcess.java | 43 ++++++++++++++----- 2 files changed, 46 insertions(+), 14 deletions(-) diff --git a/src/main/java/com/eactive/eai/custom/alarm/AlarmStateManager.java b/src/main/java/com/eactive/eai/custom/alarm/AlarmStateManager.java index ef0e5ed..0539b15 100644 --- a/src/main/java/com/eactive/eai/custom/alarm/AlarmStateManager.java +++ b/src/main/java/com/eactive/eai/custom/alarm/AlarmStateManager.java @@ -11,14 +11,14 @@ import java.util.concurrent.TimeUnit; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; +import com.eactive.eai.common.property.PropManager; +import com.eactive.eai.common.util.ApplicationContextProvider; import com.eactive.eai.common.util.Logger; import com.eactive.eai.custom.alarm.event.AlarmEvent; import com.eactive.eai.custom.alarm.key.AlarmKey; import com.eactive.eai.custom.alarm.policy.AlarmPolicy; -import com.eactive.eai.custom.alarm.policy.CounterPolicy; import com.eactive.eai.custom.alarm.policy.SendPolicy; import com.eactive.eai.custom.alarm.ums.UmsService; -import com.eactive.eai.custom.alarm.ums.payload.IUmsGsonObject; import com.eactive.eai.custom.alarm.ums.payload.ObpMonitoringUmsTemplate; import com.eactive.eai.custom.alarm.ums.payload.UmsRequestPayload; @@ -31,12 +31,21 @@ public class AlarmStateManager { protected static Logger logger = Logger.getLogger(Logger.LOGGER_DEFAULT); + private static AlarmStateManager alarmStateManager; + @Autowired AlarmService alarmService; @Autowired UmsService usmService; + public static AlarmStateManager getAlarmStateManager() { + if (alarmStateManager == null) { + alarmStateManager = ApplicationContextProvider.getContext().getBean(AlarmStateManager.class); + } + return alarmStateManager; + } + public AlarmStateManager() { this.scheduler = Executors.newSingleThreadScheduledExecutor(r -> { @@ -86,6 +95,7 @@ public class AlarmStateManager { SendPolicy sendPolicy = sendPolicyMap.get(event.getKey()); + send(sendPolicy, event); } } @@ -106,7 +116,8 @@ public class AlarmStateManager { .content(ObpMonitoringUmsTemplate.builder().message(event.getMessage()).build()) .cellphone(cellPhone).build(); - usmService.send(payload); + // usmService.send(payload); + logger.info("UMS Send!!, {}", payload); } } catch (Exception e) { diff --git a/src/main/java/com/eactive/eai/outbound/RESTProcess.java b/src/main/java/com/eactive/eai/outbound/RESTProcess.java index 29bb60a..345de41 100644 --- a/src/main/java/com/eactive/eai/outbound/RESTProcess.java +++ b/src/main/java/com/eactive/eai/outbound/RESTProcess.java @@ -42,6 +42,11 @@ import com.eactive.eai.common.worker.ResponseMap; import com.eactive.eai.control.HttpSender; import com.eactive.eai.control.LogSender; import com.eactive.eai.control.Transform; +import com.eactive.eai.custom.alarm.AlarmStateManager; +import com.eactive.eai.custom.alarm.condition.AlarmCondition; +import com.eactive.eai.custom.alarm.event.AlarmEvent; +import com.eactive.eai.custom.alarm.key.AlarmKey; +import com.eactive.eai.custom.alarm.key.CoreAlarmKey; import com.eactive.eai.env.ElinkConfig; import com.eactive.eai.inbound.processor.Processor; import com.ext.eai.common.stdmessage.STDMessageKeys; @@ -96,20 +101,36 @@ public class RESTProcess extends HTTPProcess { String circuitBreakerUseYn = PropManager.getInstance().getProperty("CircuitBreaker", "useYn"); try { - if("Y".equals(circuitBreakerUseYn)){ - String apiId = reqEaiMsg.getEAISvcCd(); - CircuitBreaker circuitBreaker = CircuitBreakerManager.getInstance().getCircuitBreaker(apiId); + if ("Y".equals(circuitBreakerUseYn)) { + String apiId = reqEaiMsg.getEAISvcCd(); + CircuitBreaker circuitBreaker = CircuitBreakerManager.getInstance().getCircuitBreaker(apiId); - // ObjectMapper 인스턴스 생성 - ObjectMapper objectMapper = new ObjectMapper(); + // ObjectMapper 인스턴스 생성 + ObjectMapper objectMapper = new ObjectMapper(); - // 서킷 브레이커의 메트릭 정보와 상태 정보를 직접 Node로 변환 - ObjectNode combinedNode = objectMapper.createObjectNode(); - combinedNode.put("state", circuitBreaker.getState().toString()); - combinedNode.set("metrics", objectMapper.valueToTree(circuitBreaker.getMetrics())); + // 서킷 브레이커의 메트릭 정보와 상태 정보를 직접 Node로 변환 + ObjectNode combinedNode = objectMapper.createObjectNode(); + combinedNode.put("state", circuitBreaker.getState().toString()); + combinedNode.set("metrics", objectMapper.valueToTree(circuitBreaker.getMetrics())); + + logger.info("CircuitBreaker state " + combinedNode.toString()); + this.resObject = circuitBreaker.executeCallable(() -> HttpSender + .callService(this.adapterGroupName, this.outboundProp, this.reqObject, this.tempProp)); + + circuitBreaker.getEventPublisher().onStateTransition(event -> { + CircuitBreaker.State from = event.getStateTransition().getFromState(); + CircuitBreaker.State to = event.getStateTransition().getToState(); + + AlarmEvent alarmEvent = AlarmEvent.builder().key(CoreAlarmKey.CircuitBreaker) + .condition(AlarmCondition.builder().build()) + .message(String.format("CircuitBreaker state changed. apiId=%s, %s -> %s", apiId, from, to)) + .build(); + + AlarmStateManager.getAlarmStateManager().onEvnet(alarmEvent); + + logger.warn("CircuitBreaker state changed. apiId={}, {} -> {}", apiId, from, to); + }); - logger.info("CircuitBreaker state "+combinedNode.toString()); - this.resObject = circuitBreaker.executeCallable(() -> HttpSender.callService(this.adapterGroupName, this.outboundProp, this.reqObject, this.tempProp)); }else{ this.resObject = HttpSender.callService(this.adapterGroupName, this.outboundProp, this.reqObject, this.tempProp); } From 700659843a8f58573c81d066f02c4ca434cfb841 Mon Sep 17 00:00:00 2001 From: cho Date: Fri, 6 Feb 2026 15:41:24 +0900 Subject: [PATCH 136/159] =?UTF-8?q?AlarmPolicy=ED=83=80=EC=9E=85("CountPol?= =?UTF-8?q?icy"->"count")=20=EC=88=98=EC=A0=95,?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 너무 길어서.. --- src/main/java/com/eactive/eai/custom/alarm/AlarmService.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/com/eactive/eai/custom/alarm/AlarmService.java b/src/main/java/com/eactive/eai/custom/alarm/AlarmService.java index cc07095..bcd00ed 100644 --- a/src/main/java/com/eactive/eai/custom/alarm/AlarmService.java +++ b/src/main/java/com/eactive/eai/custom/alarm/AlarmService.java @@ -71,7 +71,7 @@ public class AlarmService { AlarmPolicy alarmPolicy; - if ("CountPolicy".equals(policyType)) { + if ("count".equals(policyType)) { alarmPolicy = CounterPolicy.builder().alarmKey(new DynamicAlarmKey(key)).coolDownMs(coolDownSec * 1000) .thresholdCount(thresholdCount).build(); } else { From 554a6667086c1d5d13c234a452aa88739fa8855a Mon Sep 17 00:00:00 2001 From: cho Date: Fri, 6 Feb 2026 16:00:14 +0900 Subject: [PATCH 137/159] =?UTF-8?q?AlamKey=20=EA=B0=92(=EA=B0=99=EC=9D=80?= =?UTF-8?q?=EC=A2=85=EB=A5=98=20=EC=95=8C=EB=9E=8C)=EC=9D=B4=20=EA=B0=99?= =?UTF-8?q?=EB=8D=94=EB=9D=BC=EB=8F=84,=20message=20=EA=B0=80=20=EB=8B=A4?= =?UTF-8?q?=EB=A5=B4=EB=A9=B4=20=EB=94=B0=EB=A1=9C=20=EC=95=8C=EB=9E=8C?= =?UTF-8?q?=ED=95=98=EB=8F=84=EB=A1=9D,?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 예시) CircuitBreaker 알람이라도, api에 따라 따로 알람 가야함. Timeout 알람이라도 같은 호스트가 아니면 따로 알람 가야함. --- .../java/com/eactive/eai/custom/alarm/event/AlarmEvent.java | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/eactive/eai/custom/alarm/event/AlarmEvent.java b/src/main/java/com/eactive/eai/custom/alarm/event/AlarmEvent.java index fa435b8..36f6d74 100644 --- a/src/main/java/com/eactive/eai/custom/alarm/event/AlarmEvent.java +++ b/src/main/java/com/eactive/eai/custom/alarm/event/AlarmEvent.java @@ -29,12 +29,13 @@ public class AlarmEvent { if (!(o instanceof AlarmEvent)) return false; AlarmEvent that = (AlarmEvent) o; - return Objects.equals(this.key, that.key); + return Objects.equals(this.key, that.key) + && Objects.equals(this.message, that.message); } @Override public int hashCode() { - return Objects.hash(key); + return Objects.hash(key, message); } From 44238b2c121b9ac49cc38473466bc4210e29d261 Mon Sep 17 00:00:00 2001 From: cho Date: Fri, 6 Feb 2026 16:11:26 +0900 Subject: [PATCH 138/159] =?UTF-8?q?ums=20=EC=8B=A4=EC=A0=9C=20=EB=B3=B4?= =?UTF-8?q?=EB=82=B4=EB=8F=84=EB=A1=9D=20=EC=A3=BC=EC=84=9D=20=EC=A0=9C?= =?UTF-8?q?=EA=B1=B0.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit UmsService에서 ums 서버정보 프로퍼티(UMS)에서 받도록 추가. --- .../eai/custom/alarm/AlarmStateManager.java | 3 +-- .../eai/custom/alarm/ums/UmsService.java | 24 +++++++++++-------- 2 files changed, 15 insertions(+), 12 deletions(-) diff --git a/src/main/java/com/eactive/eai/custom/alarm/AlarmStateManager.java b/src/main/java/com/eactive/eai/custom/alarm/AlarmStateManager.java index 0539b15..5706b5d 100644 --- a/src/main/java/com/eactive/eai/custom/alarm/AlarmStateManager.java +++ b/src/main/java/com/eactive/eai/custom/alarm/AlarmStateManager.java @@ -116,8 +116,7 @@ public class AlarmStateManager { .content(ObpMonitoringUmsTemplate.builder().message(event.getMessage()).build()) .cellphone(cellPhone).build(); - // usmService.send(payload); - logger.info("UMS Send!!, {}", payload); + usmService.send(payload); } } catch (Exception e) { diff --git a/src/main/java/com/eactive/eai/custom/alarm/ums/UmsService.java b/src/main/java/com/eactive/eai/custom/alarm/ums/UmsService.java index 4b1b981..4368826 100644 --- a/src/main/java/com/eactive/eai/custom/alarm/ums/UmsService.java +++ b/src/main/java/com/eactive/eai/custom/alarm/ums/UmsService.java @@ -19,6 +19,7 @@ import org.apache.hc.core5.util.Timeout; import org.springframework.stereotype.Component; import org.springframework.util.StreamUtils; +import com.eactive.eai.common.property.PropManager; import com.eactive.eai.common.util.Jsons; import com.eactive.eai.common.util.Logger; import com.eactive.eai.custom.alarm.ums.payload.UmsRequestPayload; @@ -30,8 +31,12 @@ public class UmsService { protected static Logger logger = Logger.getLogger(Logger.LOGGER_DEFAULT); + private final static String UMS_GROUP_PROP_NAME = "UMS"; + private final static String UMS_PROP_HOST = "host"; + private final static String UMS_PROP_URL = "url"; + private final static String UMS_PROP_API_KEY = "apiKey"; private final static String UMS_URL = "http://172.31.35.144:9021"; - private final static String API_KEY = "API_KEY"; + private final static String API_KEY = "7cca6d58-e4f7-474d-9edd-525806bc99ff"; private final static String SEND_URL = "/ums/openapi/send"; private final static String CONTENT_TYPE = "application/json; charset=utf-8"; private final static String AUTHORIZATION_FMT = "Bearer %s"; @@ -42,11 +47,6 @@ public class UmsService { throw new IllegalArgumentException("content is null"); } - -// UmsRequestPayload payload = UmsRequestPayload.builder() -// .content(ObpMonitoringUmsTemplate.builder().message(message).build()).cellphone(cpno) -// .build(); - try { ValidationUtil.validateOrThrow(payload); } catch (Exception ex) { @@ -54,22 +54,26 @@ public class UmsService { throw ex; } - return call(SEND_URL, payload); + return call(payload); } private CloseableHttpClient createHttpClient() { return HttpClients.createDefault(); } - private Future call(String url, UmsRequestPayload requestPayload) throws Exception { + private Future call(UmsRequestPayload requestPayload) throws Exception { ExecutorService executor = Executors.newSingleThreadExecutor(); String json = Jsons.GSON.toJson(requestPayload); + + String host = PropManager.getInstance().getProperty(UMS_GROUP_PROP_NAME, UMS_PROP_HOST, UMS_URL); + String url = PropManager.getInstance().getProperty(UMS_GROUP_PROP_NAME, UMS_PROP_URL, SEND_URL); + String apiKey = PropManager.getInstance().getProperty(UMS_GROUP_PROP_NAME, UMS_PROP_API_KEY, API_KEY); - HttpPost httpPost = new HttpPost(UMS_URL + url); + HttpPost httpPost = new HttpPost(host + url); httpPost.setHeader("Content-Type", CONTENT_TYPE); - httpPost.setHeader("Authorization", String.format(AUTHORIZATION_FMT, API_KEY)); + httpPost.setHeader("Authorization", String.format(AUTHORIZATION_FMT, apiKey)); httpPost.setEntity(EntityBuilder.create().setText(json).setContentType(ContentType.APPLICATION_JSON).build()); if (logger.isDebugEnabled()) { From 8564a2a35282bbc9574e49e9d5ebfc05261f2d64 Mon Sep 17 00:00:00 2001 From: cho Date: Fri, 6 Feb 2026 17:03:17 +0900 Subject: [PATCH 139/159] =?UTF-8?q?=EC=98=88=EC=99=B8=20=EC=B2=98=EB=A6=AC?= =?UTF-8?q?=EC=B6=94=EA=B0=80,=20key=EA=B0=92=EC=9D=80=20=EC=9E=88?= =?UTF-8?q?=EB=8A=94=EB=8D=B0=20null=EC=85=8B=ED=8C=85=EB=90=98=EB=8A=94?= =?UTF-8?q?=20entry=EA=B0=80=20=EC=9E=88=EB=8A=94=EB=93=AF.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/eactive/eai/common/util/HttpAdapterExtraLogUtil.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/main/java/com/eactive/eai/common/util/HttpAdapterExtraLogUtil.java b/src/main/java/com/eactive/eai/common/util/HttpAdapterExtraLogUtil.java index 5e76a92..2797a88 100644 --- a/src/main/java/com/eactive/eai/common/util/HttpAdapterExtraLogUtil.java +++ b/src/main/java/com/eactive/eai/common/util/HttpAdapterExtraLogUtil.java @@ -2,6 +2,7 @@ package com.eactive.eai.common.util; import java.util.ArrayList; import java.util.Arrays; +import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Map; @@ -111,7 +112,8 @@ public class HttpAdapterExtraLogUtil { public static List convertMapToListOfHttpAdapterExtraHeaderVo(Map map) { return map.entrySet().stream() - .map(entry -> new HttpAdapterExtraHeaderVo(entry.getKey().toString(), entry.getValue().toString())) + .map(entry -> new HttpAdapterExtraHeaderVo(entry.getKey().toString(), entry.getValue() == null ? "" : entry.getValue().toString())) .collect(Collectors.toList()); } + } From 48fae94b488945189cce1eed4c2809ff4641ccdf Mon Sep 17 00:00:00 2001 From: cho Date: Wed, 11 Feb 2026 13:24:18 +0900 Subject: [PATCH 140/159] =?UTF-8?q?=EC=84=9C=ED=82=B7=EB=B8=8C=EB=A0=88?= =?UTF-8?q?=EC=9D=B4=EC=BB=A4=20=EC=83=81=ED=83=9C=EC=A0=84=EC=9D=B4=20?= =?UTF-8?q?=EC=9D=B4=EB=B2=A4=ED=8A=B8=20=EB=A6=AC=EC=8A=A4=EB=84=88=20?= =?UTF-8?q?=EC=A4=91=EB=B3=B5=EB=93=B1=EB=A1=9D=20=EB=B0=A9=EC=A7=80?= =?UTF-8?q?=EB=A5=BC=20=EC=9C=84=ED=95=B4=20=EB=93=B1=EB=A1=9D=EC=8B=9C?= =?UTF-8?q?=EC=97=90=EB=A7=8C=20=ED=95=9C=EB=B2=88=20=ED=95=98=EB=8F=84?= =?UTF-8?q?=EB=A1=9D=20=EC=BD=94=EB=93=9C=20=EC=9D=B4=EB=8F=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../circuitBreaker/CircuitBreakerManager.java | 27 +++++++++++++++++++ .../com/eactive/eai/outbound/RESTProcess.java | 18 +++---------- 2 files changed, 30 insertions(+), 15 deletions(-) diff --git a/src/main/java/com/eactive/eai/common/circuitBreaker/CircuitBreakerManager.java b/src/main/java/com/eactive/eai/common/circuitBreaker/CircuitBreakerManager.java index 1b59209..4dce347 100644 --- a/src/main/java/com/eactive/eai/common/circuitBreaker/CircuitBreakerManager.java +++ b/src/main/java/com/eactive/eai/common/circuitBreaker/CircuitBreakerManager.java @@ -6,6 +6,11 @@ import com.eactive.eai.common.lifecycle.LifecycleListener; import com.eactive.eai.common.lifecycle.LifecycleSupport; import com.eactive.eai.common.property.PropManager; import com.eactive.eai.common.util.Logger; +import com.eactive.eai.custom.alarm.AlarmStateManager; +import com.eactive.eai.custom.alarm.condition.AlarmCondition; +import com.eactive.eai.custom.alarm.event.AlarmEvent; +import com.eactive.eai.custom.alarm.key.CoreAlarmKey; + import io.github.resilience4j.circuitbreaker.CircuitBreaker; import io.github.resilience4j.circuitbreaker.CircuitBreakerConfig; import io.github.resilience4j.circuitbreaker.CircuitBreakerRegistry; @@ -71,6 +76,28 @@ public class CircuitBreakerManager implements Lifecycle { circuitBreakerRegistry = CircuitBreakerRegistry.of(config); TaggedCircuitBreakerMetrics.ofCircuitBreakerRegistry(circuitBreakerRegistry).bindTo(meterRegistry); + + circuitBreakerRegistry.getEventPublisher().onEntryAdded(event -> { + CircuitBreaker cb = event.getAddedEntry(); + String apiId = cb.getName(); + + // 여기서 상태 변경 리스너를 한 번만 등록 + cb.getEventPublisher().onStateTransition(stateEvent -> { + CircuitBreaker.State from = stateEvent.getStateTransition().getFromState(); + CircuitBreaker.State to = stateEvent.getStateTransition().getToState(); + + AlarmEvent alarmEvent = AlarmEvent.builder().key(CoreAlarmKey.CircuitBreaker) + .condition(AlarmCondition.builder().build()) + .message(String.format("CircuitBreaker state changed. apiId=%s, %s -> %s", apiId, from, to)) + .build(); + + AlarmStateManager.getAlarmStateManager().onEvnet(alarmEvent); + + logger.warn("CircuitBreaker state changed. apiId={}, {} -> {}", apiId, from, to); + }); + + logger.info("Registered StateTransition listener for: {}", apiId); + }); logger.info("init CircuitBreaker - "+config); } diff --git a/src/main/java/com/eactive/eai/outbound/RESTProcess.java b/src/main/java/com/eactive/eai/outbound/RESTProcess.java index 345de41..d22cde9 100644 --- a/src/main/java/com/eactive/eai/outbound/RESTProcess.java +++ b/src/main/java/com/eactive/eai/outbound/RESTProcess.java @@ -101,7 +101,7 @@ public class RESTProcess extends HTTPProcess { String circuitBreakerUseYn = PropManager.getInstance().getProperty("CircuitBreaker", "useYn"); try { - if ("Y".equals(circuitBreakerUseYn)) { + if (true) { String apiId = reqEaiMsg.getEAISvcCd(); CircuitBreaker circuitBreaker = CircuitBreakerManager.getInstance().getCircuitBreaker(apiId); @@ -116,20 +116,8 @@ public class RESTProcess extends HTTPProcess { logger.info("CircuitBreaker state " + combinedNode.toString()); this.resObject = circuitBreaker.executeCallable(() -> HttpSender .callService(this.adapterGroupName, this.outboundProp, this.reqObject, this.tempProp)); - - circuitBreaker.getEventPublisher().onStateTransition(event -> { - CircuitBreaker.State from = event.getStateTransition().getFromState(); - CircuitBreaker.State to = event.getStateTransition().getToState(); - - AlarmEvent alarmEvent = AlarmEvent.builder().key(CoreAlarmKey.CircuitBreaker) - .condition(AlarmCondition.builder().build()) - .message(String.format("CircuitBreaker state changed. apiId=%s, %s -> %s", apiId, from, to)) - .build(); - - AlarmStateManager.getAlarmStateManager().onEvnet(alarmEvent); - - logger.warn("CircuitBreaker state changed. apiId={}, {} -> {}", apiId, from, to); - }); + + }else{ this.resObject = HttpSender.callService(this.adapterGroupName, this.outboundProp, this.reqObject, this.tempProp); From 72d89125975b0730ddb2b559fdf4a5303c5a4f09 Mon Sep 17 00:00:00 2001 From: cho Date: Wed, 11 Feb 2026 13:24:44 +0900 Subject: [PATCH 141/159] =?UTF-8?q?=ED=85=8C=EC=8A=A4=ED=8A=B8=20=EC=99=84?= =?UTF-8?q?=EB=A3=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../eai/custom/alarm/AlarmService.java | 44 +++++++++++-------- .../eai/custom/alarm/AlarmStateManager.java | 33 ++++++++++---- .../alarm/condition/AlarmCondition.java | 3 ++ .../eai/custom/alarm/event/AlarmEvent.java | 2 + .../eai/custom/alarm/key/AlarmKey.java | 1 + .../eai/custom/alarm/key/CoreAlarmKey.java | 4 +- .../eai/custom/alarm/key/DynamicAlarmKey.java | 3 ++ .../eai/custom/alarm/policy/AlarmPolicy.java | 14 ------ .../custom/alarm/policy/CounterPolicy.java | 2 +- .../eai/custom/alarm/policy/SendPolicy.java | 7 +-- .../eai/custom/alarm/policy/TimerPolicy.java | 2 +- 11 files changed, 67 insertions(+), 48 deletions(-) diff --git a/src/main/java/com/eactive/eai/custom/alarm/AlarmService.java b/src/main/java/com/eactive/eai/custom/alarm/AlarmService.java index bcd00ed..7f26e67 100644 --- a/src/main/java/com/eactive/eai/custom/alarm/AlarmService.java +++ b/src/main/java/com/eactive/eai/custom/alarm/AlarmService.java @@ -28,8 +28,9 @@ public class AlarmService { protected static Logger logger = Logger.getLogger(Logger.LOGGER_DEFAULT); final static String ALARM_GROUP = "Alarm"; - final static String ALARM_KEY = "Alarm"; + final static String ALARM_KEY = "{ALARM}"; final static String ALARM_RECIVER = "{RECIVER}"; + final static String ALARM_EABLE = "enable.alarm"; public Map getAlarmPolicy() { @@ -40,16 +41,16 @@ public class AlarmService { Properties props = PropManager.getInstance().getProperties(ALARM_GROUP); props.forEach((key, value) -> { + String keyName = (String) key; String configStr = (String) value; - if (keyName.contains(ALARM_RECIVER)) return; + if (keyName.contains(ALARM_KEY)) { - AlarmPolicy newPolicy = buildAlarmPolicy(keyName, configStr); - - - policyMap.put(newPolicy.getAlarmKey(), newPolicy); + AlarmPolicy newPolicy = buildAlarmPolicy(keyName, configStr); + policyMap.put(newPolicy.getAlarmKey(), newPolicy); + } }); } catch (Exception e) { @@ -60,29 +61,33 @@ public class AlarmService { return policyMap; } + public boolean isAlarmEnabled() { + return Optional.ofNullable(PropManager.getInstance().getProperty(ALARM_GROUP, ALARM_EABLE)) + .map(Boolean::valueOf).orElse(false); + } + private AlarmPolicy buildAlarmPolicy(String key, String configJsonStr) { JsonObject alarmConfig = Jsons.GSON.fromJson(configJsonStr, JsonObject.class); String policyType = alarmConfig.get("type").getAsString(); - int coolDownSec = Optional.ofNullable(alarmConfig.get("coolDownSec")).map(i -> i.getAsInt()).orElse(60); int thresholdCount = Optional.ofNullable(alarmConfig.get("thresholdCount")).map(i -> i.getAsInt()).orElse(5); int timeWindowSec = Optional.ofNullable(alarmConfig.get("timeWindowSec")).map(i -> i.getAsInt()).orElse(60); AlarmPolicy alarmPolicy; if ("count".equals(policyType)) { - alarmPolicy = CounterPolicy.builder().alarmKey(new DynamicAlarmKey(key)).coolDownMs(coolDownSec * 1000) - .thresholdCount(thresholdCount).build(); + alarmPolicy = CounterPolicy.builder().alarmKey(new DynamicAlarmKey(key)).thresholdCount(thresholdCount) + .build(); } else { - alarmPolicy = TimerPolicy.builder().alarmKey(new DynamicAlarmKey(key)).coolDownMs(coolDownSec * 1000) - .timeWindowMs(timeWindowSec * 1000).build(); + alarmPolicy = TimerPolicy.builder().alarmKey(new DynamicAlarmKey(key)).timeWindowMs(timeWindowSec * 1000) + .build(); } return alarmPolicy; } - + public Map getSendPolicy() { Map policyMap = new HashMap(); @@ -95,11 +100,11 @@ public class AlarmService { String keyName = (String) key; String configStr = (String) value; - if (!keyName.contains(ALARM_RECIVER)) return; + if (!keyName.contains(ALARM_RECIVER)) + return; SendPolicy newPolicy = buildSendPolicy(keyName, configStr); - - + policyMap.put(newPolicy.getAlarmKey(), newPolicy); }); @@ -111,12 +116,13 @@ public class AlarmService { return policyMap; } - + private SendPolicy buildSendPolicy(String key, String configStr) { - List reciverList = Optional.ofNullable(configStr).map( t -> Arrays.asList(t.split(",")) ).orElse(Collections.EMPTY_LIST); - - key = key.replaceAll(ALARM_RECIVER, "").trim(); + List reciverList = Optional.ofNullable(configStr).map(t -> Arrays.asList(t.split(","))) + .orElse(Collections.EMPTY_LIST); + + key = key.replace(ALARM_RECIVER, "").trim() + "{ALARM}"; SendPolicy sendPolicy = new SendPolicy(key, reciverList); diff --git a/src/main/java/com/eactive/eai/custom/alarm/AlarmStateManager.java b/src/main/java/com/eactive/eai/custom/alarm/AlarmStateManager.java index 5706b5d..719a204 100644 --- a/src/main/java/com/eactive/eai/custom/alarm/AlarmStateManager.java +++ b/src/main/java/com/eactive/eai/custom/alarm/AlarmStateManager.java @@ -1,6 +1,7 @@ package com.eactive.eai.custom.alarm; import java.util.ArrayList; +import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Optional; @@ -11,7 +12,6 @@ import java.util.concurrent.TimeUnit; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; -import com.eactive.eai.common.property.PropManager; import com.eactive.eai.common.util.ApplicationContextProvider; import com.eactive.eai.common.util.Logger; import com.eactive.eai.custom.alarm.event.AlarmEvent; @@ -85,19 +85,36 @@ public class AlarmStateManager { private void fireAlarm() { Map alarmPolicyMap = alarmService.getAlarmPolicy(); + Map sendPolicyMap = alarmService.getSendPolicy(); - for (AlarmEvent event : registerAlarmList) { + Iterator iterator = registerAlarmList.iterator(); + while (iterator.hasNext()) { + AlarmEvent event = iterator.next(); AlarmPolicy alarmPolicy = alarmPolicyMap.get(event.getKey()); - if (alarmPolicy.isAlarmTriggered(event)) { - + if (alarmPolicy != null && alarmPolicy.isAlarmTriggered(event)) { + // 알람 발송 로직 SendPolicy sendPolicy = sendPolicyMap.get(event.getKey()); - - send(sendPolicy, event); + if (alarmService.isAlarmEnabled()) { + send(sendPolicy, event); + } else { + logger.info("Alarm is disabled, event = {}, policy = {}", event, sendPolicy); + } + // 리스트에서 안전하게 제거 + iterator.remove(); + }else { //트리거 조건이 안되더라도, 이벤트발생한지 오래 되었으면 제거하여 OOM 예방. + + + long firstOcurredAt = event.getCondition().getOcurredAt(); + + long diffInMs = System.currentTimeMillis() - firstOcurredAt; + + if ( diffInMs >= TimeUnit.MINUTES.toMillis(60) ) { //1시간 지난거면 삭제 + iterator.remove(); + } } - } } @@ -108,7 +125,7 @@ public class AlarmStateManager { try { - List cellPhoneList = sendPolicy.getCellpohoneList(); + List cellPhoneList = sendPolicy.getCellPhoneList(); for (String cellPhone : cellPhoneList) { diff --git a/src/main/java/com/eactive/eai/custom/alarm/condition/AlarmCondition.java b/src/main/java/com/eactive/eai/custom/alarm/condition/AlarmCondition.java index 996dbd0..2313fdf 100644 --- a/src/main/java/com/eactive/eai/custom/alarm/condition/AlarmCondition.java +++ b/src/main/java/com/eactive/eai/custom/alarm/condition/AlarmCondition.java @@ -2,12 +2,15 @@ package com.eactive.eai.custom.alarm.condition; import lombok.Builder; import lombok.Getter; +import lombok.ToString; @Builder @Getter +@ToString public class AlarmCondition { final long ocurredAt = System.currentTimeMillis(); long lastOcurredAt; // 일단, 미사용 + @Builder.Default long count = 1; public void onOcurr() { diff --git a/src/main/java/com/eactive/eai/custom/alarm/event/AlarmEvent.java b/src/main/java/com/eactive/eai/custom/alarm/event/AlarmEvent.java index 36f6d74..194128d 100644 --- a/src/main/java/com/eactive/eai/custom/alarm/event/AlarmEvent.java +++ b/src/main/java/com/eactive/eai/custom/alarm/event/AlarmEvent.java @@ -10,10 +10,12 @@ import com.eactive.eai.custom.alarm.policy.CounterPolicy; import lombok.Builder; import lombok.Getter; import lombok.Setter; +import lombok.ToString; @Setter @Getter @Builder +@ToString public class AlarmEvent { AlarmKey key; AlarmCondition condition; diff --git a/src/main/java/com/eactive/eai/custom/alarm/key/AlarmKey.java b/src/main/java/com/eactive/eai/custom/alarm/key/AlarmKey.java index c81778a..ddcf0ad 100644 --- a/src/main/java/com/eactive/eai/custom/alarm/key/AlarmKey.java +++ b/src/main/java/com/eactive/eai/custom/alarm/key/AlarmKey.java @@ -1,5 +1,6 @@ package com.eactive.eai.custom.alarm.key; + public interface AlarmKey { String code(); } diff --git a/src/main/java/com/eactive/eai/custom/alarm/key/CoreAlarmKey.java b/src/main/java/com/eactive/eai/custom/alarm/key/CoreAlarmKey.java index 70c5027..cc1d79b 100644 --- a/src/main/java/com/eactive/eai/custom/alarm/key/CoreAlarmKey.java +++ b/src/main/java/com/eactive/eai/custom/alarm/key/CoreAlarmKey.java @@ -4,9 +4,9 @@ public final class CoreAlarmKey { private CoreAlarmKey() { } - public static final AlarmKey CircuitBreaker = new DynamicAlarmKey("CircuitBreaker"); + public static final AlarmKey CircuitBreaker = new DynamicAlarmKey("CircuitBreaker{ALARM}"); - public static final AlarmKey Timeout = new DynamicAlarmKey("Timeout"); + public static final AlarmKey Timeout = new DynamicAlarmKey("Timeout{ALARM}"); } \ No newline at end of file diff --git a/src/main/java/com/eactive/eai/custom/alarm/key/DynamicAlarmKey.java b/src/main/java/com/eactive/eai/custom/alarm/key/DynamicAlarmKey.java index c26298b..6a76d46 100644 --- a/src/main/java/com/eactive/eai/custom/alarm/key/DynamicAlarmKey.java +++ b/src/main/java/com/eactive/eai/custom/alarm/key/DynamicAlarmKey.java @@ -1,5 +1,8 @@ package com.eactive.eai.custom.alarm.key; +import lombok.ToString; + +@ToString public final class DynamicAlarmKey implements AlarmKey { private final String code; diff --git a/src/main/java/com/eactive/eai/custom/alarm/policy/AlarmPolicy.java b/src/main/java/com/eactive/eai/custom/alarm/policy/AlarmPolicy.java index d1230b6..3c6dd8f 100644 --- a/src/main/java/com/eactive/eai/custom/alarm/policy/AlarmPolicy.java +++ b/src/main/java/com/eactive/eai/custom/alarm/policy/AlarmPolicy.java @@ -1,6 +1,5 @@ package com.eactive.eai.custom.alarm.policy; -import com.eactive.eai.custom.alarm.condition.AlarmCondition; import com.eactive.eai.custom.alarm.event.AlarmEvent; import com.eactive.eai.custom.alarm.key.AlarmKey; @@ -12,13 +11,10 @@ public abstract class AlarmPolicy { private long timeWindowMs; - private long coolDownMs; - protected AlarmPolicy(Builder builder) { this.alarmKey = builder.alarmKey; this.thresholdCount = builder.thresholdCount; this.timeWindowMs = builder.timeWindowMs; - this.coolDownMs = builder.coolDownMs; } public AlarmKey getAlarmKey() { @@ -33,10 +29,6 @@ public abstract class AlarmPolicy { return timeWindowMs; } - public long getCoolDownMs() { - return coolDownMs; - } - public abstract boolean isAlarmTriggered(AlarmEvent event); @@ -55,7 +47,6 @@ public abstract class AlarmPolicy { private AlarmKey alarmKey; private int thresholdCount; private long timeWindowMs; - private long coolDownMs; public T alarmKey(AlarmKey alarmKey) { this.alarmKey = alarmKey; @@ -72,11 +63,6 @@ public abstract class AlarmPolicy { return self(); } - public T coolDownMs(long coolDownMs) { - this.coolDownMs = coolDownMs; - return self(); - } - protected abstract T self(); abstract AlarmPolicy build(); diff --git a/src/main/java/com/eactive/eai/custom/alarm/policy/CounterPolicy.java b/src/main/java/com/eactive/eai/custom/alarm/policy/CounterPolicy.java index 65d3f7f..7bf3c0a 100644 --- a/src/main/java/com/eactive/eai/custom/alarm/policy/CounterPolicy.java +++ b/src/main/java/com/eactive/eai/custom/alarm/policy/CounterPolicy.java @@ -11,7 +11,7 @@ public class CounterPolicy extends AlarmPolicy { @Override public boolean isAlarmTriggered(AlarmEvent event) { - if (!event.equals(getAlarmKey())) { + if (!event.getKey().equals(getAlarmKey())) { return false; } diff --git a/src/main/java/com/eactive/eai/custom/alarm/policy/SendPolicy.java b/src/main/java/com/eactive/eai/custom/alarm/policy/SendPolicy.java index 945881d..592d529 100644 --- a/src/main/java/com/eactive/eai/custom/alarm/policy/SendPolicy.java +++ b/src/main/java/com/eactive/eai/custom/alarm/policy/SendPolicy.java @@ -1,22 +1,23 @@ package com.eactive.eai.custom.alarm.policy; -import java.util.ArrayList; import java.util.List; import com.eactive.eai.custom.alarm.key.AlarmKey; import com.eactive.eai.custom.alarm.key.DynamicAlarmKey; import lombok.Getter; - +import lombok.ToString; +@ToString @Getter public class SendPolicy { final AlarmKey alarmKey; - final List cellpohoneList = new ArrayList(); + final List cellPhoneList; public SendPolicy(String alarmKey, List cellPhoneList) { this.alarmKey = new DynamicAlarmKey(alarmKey); + this.cellPhoneList = cellPhoneList; } } diff --git a/src/main/java/com/eactive/eai/custom/alarm/policy/TimerPolicy.java b/src/main/java/com/eactive/eai/custom/alarm/policy/TimerPolicy.java index 0a51b02..29c719a 100644 --- a/src/main/java/com/eactive/eai/custom/alarm/policy/TimerPolicy.java +++ b/src/main/java/com/eactive/eai/custom/alarm/policy/TimerPolicy.java @@ -13,7 +13,7 @@ public class TimerPolicy extends AlarmPolicy { @Override public boolean isAlarmTriggered(AlarmEvent event) { - if (event.equals(getAlarmKey())) { + if (event.getKey().equals(getAlarmKey())) { AlarmCondition condition = event.getCondition(); From 38dddf6e92c0e8c3d199806f01755b9ae5376715 Mon Sep 17 00:00:00 2001 From: cho Date: Wed, 11 Feb 2026 13:57:35 +0900 Subject: [PATCH 142/159] =?UTF-8?q?httpHeader=20100=20=EB=A1=9C=EA=B9=85?= =?UTF-8?q?=EC=8B=9C,=20url=EC=97=90=20=EC=BF=BC=EB=A6=AC=EC=8A=A4?= =?UTF-8?q?=ED=8A=B8=EB=A7=81=20=EC=A0=95=EB=B3=B4=20=EC=B6=94=EA=B0=80.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../eai/adapter/http/client/HttpClientAdapterServiceKey.java | 1 + .../eactive/eai/adapter/http/dynamic/HttpAdapterServiceKey.java | 1 + .../eai/adapter/http/dynamic/impl/HttpAdapterServiceBypass.java | 1 + .../eai/adapter/http/dynamic/impl/HttpAdapterServiceRest.java | 1 + .../adapter/http/dynamic/impl/HttpAdapterServiceStandard.java | 1 + .../com/eactive/eai/inbound/processor/RequestProcessor.java | 2 +- 6 files changed, 6 insertions(+), 1 deletion(-) diff --git a/src/main/java/com/eactive/eai/adapter/http/client/HttpClientAdapterServiceKey.java b/src/main/java/com/eactive/eai/adapter/http/client/HttpClientAdapterServiceKey.java index 6e6bad5..4de44f4 100644 --- a/src/main/java/com/eactive/eai/adapter/http/client/HttpClientAdapterServiceKey.java +++ b/src/main/java/com/eactive/eai/adapter/http/client/HttpClientAdapterServiceKey.java @@ -69,6 +69,7 @@ public interface HttpClientAdapterServiceKey { public static final String INBOUND_METHOD = "INBOUND_METHOD"; public static final String INBOUND_URI = "INBOUND_URI"; public static final String INBOUND_EXTURI = "INBOUND_EXTURI"; + public static final String INBOUND_EXTPARAMS = "INBOUND_EXTPARAMS"; public static final String INBOUND_HEADER = "INBOUND_HEADER"; public static final String HTTP_VERSION = "HTTP_VERSION"; diff --git a/src/main/java/com/eactive/eai/adapter/http/dynamic/HttpAdapterServiceKey.java b/src/main/java/com/eactive/eai/adapter/http/dynamic/HttpAdapterServiceKey.java index c617084..b662e26 100644 --- a/src/main/java/com/eactive/eai/adapter/http/dynamic/HttpAdapterServiceKey.java +++ b/src/main/java/com/eactive/eai/adapter/http/dynamic/HttpAdapterServiceKey.java @@ -43,6 +43,7 @@ public interface HttpAdapterServiceKey { static final String INBOUND_METHOD = "INBOUND_METHOD"; static final String INBOUND_URI = "INBOUND_URI"; static final String INBOUND_EXTURI = "INBOUND_EXTURI"; + static final String INBOUND_EXTPARAMS = "INBOUND_EXTPARAMS"; static final String INBOUND_HEADER = "INBOUND_HEADER"; static final String INBOUND_QUERY_STRING = "INBOUND_QUERY_STRING"; static final String INBOUND_REWRITE_PATH = "INBOUND_REWRITE_PATH"; diff --git a/src/main/java/com/eactive/eai/adapter/http/dynamic/impl/HttpAdapterServiceBypass.java b/src/main/java/com/eactive/eai/adapter/http/dynamic/impl/HttpAdapterServiceBypass.java index 0d47483..94ef194 100644 --- a/src/main/java/com/eactive/eai/adapter/http/dynamic/impl/HttpAdapterServiceBypass.java +++ b/src/main/java/com/eactive/eai/adapter/http/dynamic/impl/HttpAdapterServiceBypass.java @@ -131,6 +131,7 @@ public class HttpAdapterServiceBypass extends HttpAdapterServiceSupport { prop.put(INBOUND_URI, request.getRequestURI()); prop.put(INBOUND_QUERY_STRING, StringUtils.defaultString(request.getQueryString())); prop.put(INBOUND_HEADER, getHeaders(request)); + prop.put(INBOUND_EXTPARAMS, request.getQueryString()); if (StringUtils.equals(adptVO.getAdapterGroupVO().getType(), Keys.TYPE_REST) || StringUtils.equals(adptVO.getAdapterGroupVO().getType(), Keys.TYPE_HTTP_CUSTOM)) { // /api/v1/public/getUserInfo.svc diff --git a/src/main/java/com/eactive/eai/adapter/http/dynamic/impl/HttpAdapterServiceRest.java b/src/main/java/com/eactive/eai/adapter/http/dynamic/impl/HttpAdapterServiceRest.java index 13089e7..070d99b 100644 --- a/src/main/java/com/eactive/eai/adapter/http/dynamic/impl/HttpAdapterServiceRest.java +++ b/src/main/java/com/eactive/eai/adapter/http/dynamic/impl/HttpAdapterServiceRest.java @@ -275,6 +275,7 @@ public class HttpAdapterServiceRest extends HttpAdapterServiceSupport { prop = new Properties(); prop.put(INBOUND_METHOD, request.getMethod()); prop.put(INBOUND_URI, request.getRequestURI()); + prop.put(INBOUND_EXTPARAMS, request.getQueryString()); prop.put(INBOUND_HEADER, getHeaders(request)); if (StringUtils.equals(adptVO.getAdapterGroupVO().getType(), Keys.TYPE_REST) || StringUtils.equals(adptVO.getAdapterGroupVO().getType(), Keys.TYPE_HTTP_CUSTOM)) { diff --git a/src/main/java/com/eactive/eai/adapter/http/dynamic/impl/HttpAdapterServiceStandard.java b/src/main/java/com/eactive/eai/adapter/http/dynamic/impl/HttpAdapterServiceStandard.java index 17103ab..b78408f 100644 --- a/src/main/java/com/eactive/eai/adapter/http/dynamic/impl/HttpAdapterServiceStandard.java +++ b/src/main/java/com/eactive/eai/adapter/http/dynamic/impl/HttpAdapterServiceStandard.java @@ -172,6 +172,7 @@ public class HttpAdapterServiceStandard extends HttpAdapterServiceSupport prop.put(INBOUND_METHOD, request.getMethod()); prop.put(INBOUND_URI, request.getRequestURI()); prop.put(INBOUND_HEADER, getHeaders(request)); + prop.put(INBOUND_EXTPARAMS, request.getQueryString()); if (StringUtils.equals(adptVO.getAdapterGroupVO().getType(), Keys.TYPE_REST) || StringUtils.equals(adptVO.getAdapterGroupVO().getType(), Keys.TYPE_HTTP_CUSTOM)) { // /api/v1/public/getUserInfo.svc diff --git a/src/main/java/com/eactive/eai/inbound/processor/RequestProcessor.java b/src/main/java/com/eactive/eai/inbound/processor/RequestProcessor.java index db60802..25d4c1d 100644 --- a/src/main/java/com/eactive/eai/inbound/processor/RequestProcessor.java +++ b/src/main/java/com/eactive/eai/inbound/processor/RequestProcessor.java @@ -426,7 +426,7 @@ public class RequestProcessor extends RequestProcessorSupport { prop.getProperty(HttpClientAdapterServiceKey.ADAPTER_GROUP_NAME), prop.getProperty(HttpClientAdapterServiceKey.ADAPTER_NAME), (Properties) prop.get(HttpClientAdapterServiceKey.INBOUND_HEADER), - prop.getProperty(HttpClientAdapterServiceKey.INBOUND_EXTURI), + prop.getProperty(HttpClientAdapterServiceKey.INBOUND_EXTURI)+"?"+prop.getProperty(HttpClientAdapterServiceKey.INBOUND_EXTPARAMS), prop.getProperty(HttpClientAdapterServiceKey.INBOUND_METHOD)); } From 8375f134c65a122e3d8dc6c4fd8b315b676120d8 Mon Sep 17 00:00:00 2001 From: cho Date: Wed, 11 Feb 2026 16:48:50 +0900 Subject: [PATCH 143/159] =?UTF-8?q?=EC=9D=98=EC=A1=B4=EC=84=B1=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- build.gradle | 2 ++ 1 file changed, 2 insertions(+) diff --git a/build.gradle b/build.gradle index 7acaa39..f1d0b88 100644 --- a/build.gradle +++ b/build.gradle @@ -65,6 +65,8 @@ dependencies { api 'io.github.resilience4j:resilience4j-micrometer:1.7.1' api 'io.micrometer:micrometer-core:1.5.17' api 'io.micrometer:micrometer-registry-prometheus:1.5.17' + + implementation "com.google.code.gson:gson:2.3.1" //api "com.eactive:mina-core-1.0.10-custom:1.0:custom@jar" api ("org.apache.mina:mina-filter-ssl:1.0.10") { From 86ccc7047ac20c047198cb53842a718137e79e01 Mon Sep 17 00:00:00 2001 From: cho Date: Thu, 12 Feb 2026 09:28:38 +0900 Subject: [PATCH 144/159] =?UTF-8?q?=EB=A1=9C=EC=BB=AC=ED=85=8C=EC=8A=A4?= =?UTF-8?q?=ED=8A=B8=EB=A5=BC=20=EC=9C=84=ED=95=9C=20=ED=94=8C=EB=9E=98?= =?UTF-8?q?=EA=B7=B8=20=EB=8B=A4=EC=8B=9C=20=EC=9B=90=EB=B3=B5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/com/eactive/eai/outbound/RESTProcess.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/com/eactive/eai/outbound/RESTProcess.java b/src/main/java/com/eactive/eai/outbound/RESTProcess.java index d22cde9..e05c556 100644 --- a/src/main/java/com/eactive/eai/outbound/RESTProcess.java +++ b/src/main/java/com/eactive/eai/outbound/RESTProcess.java @@ -101,7 +101,7 @@ public class RESTProcess extends HTTPProcess { String circuitBreakerUseYn = PropManager.getInstance().getProperty("CircuitBreaker", "useYn"); try { - if (true) { + if ("Y".equals(circuitBreakerUseYn)) { String apiId = reqEaiMsg.getEAISvcCd(); CircuitBreaker circuitBreaker = CircuitBreakerManager.getInstance().getCircuitBreaker(apiId); From d1c2b75e182de212ff071c26f43c2dbb85086a99 Mon Sep 17 00:00:00 2001 From: cho Date: Thu, 12 Feb 2026 14:15:07 +0900 Subject: [PATCH 145/159] =?UTF-8?q?httpClient=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../eai/custom/alarm/AlarmStateManager.java | 2 +- .../eai/custom/alarm/ums/UmsSendManager.java | 13 +- .../eai/custom/alarm/ums/UmsService.java | 217 ++++++++++-------- 3 files changed, 131 insertions(+), 101 deletions(-) diff --git a/src/main/java/com/eactive/eai/custom/alarm/AlarmStateManager.java b/src/main/java/com/eactive/eai/custom/alarm/AlarmStateManager.java index 719a204..83e4e14 100644 --- a/src/main/java/com/eactive/eai/custom/alarm/AlarmStateManager.java +++ b/src/main/java/com/eactive/eai/custom/alarm/AlarmStateManager.java @@ -132,7 +132,7 @@ public class AlarmStateManager { payload = UmsRequestPayload.builder() .content(ObpMonitoringUmsTemplate.builder().message(event.getMessage()).build()) .cellphone(cellPhone).build(); - + logger.info("Alarm is disabled, UmsRequestPayload = {}", payload); usmService.send(payload); } diff --git a/src/main/java/com/eactive/eai/custom/alarm/ums/UmsSendManager.java b/src/main/java/com/eactive/eai/custom/alarm/ums/UmsSendManager.java index dfab3b5..396705f 100644 --- a/src/main/java/com/eactive/eai/custom/alarm/ums/UmsSendManager.java +++ b/src/main/java/com/eactive/eai/custom/alarm/ums/UmsSendManager.java @@ -1,6 +1,7 @@ package com.eactive.eai.custom.alarm.ums; import java.util.Queue; +import java.util.concurrent.CompletableFuture; import java.util.concurrent.ConcurrentLinkedQueue; import java.util.concurrent.Executors; import java.util.concurrent.ScheduledExecutorService; @@ -49,7 +50,17 @@ public class UmsSendManager { void sendMessage() throws Exception { UmsRequestPayload payload; while ((payload = queue.poll()) != null) { - umsService.send(payload); + final UmsRequestPayload finalPayload = payload; + CompletableFuture.runAsync(() -> { + UmsCallResult result = null; + try { + result = umsService.send(finalPayload); + } catch (Exception e) { + logger.error("UMS 전송 실패", e); + }finally { + logger.info(result); + } + }); } } diff --git a/src/main/java/com/eactive/eai/custom/alarm/ums/UmsService.java b/src/main/java/com/eactive/eai/custom/alarm/ums/UmsService.java index 4368826..74777de 100644 --- a/src/main/java/com/eactive/eai/custom/alarm/ums/UmsService.java +++ b/src/main/java/com/eactive/eai/custom/alarm/ums/UmsService.java @@ -1,135 +1,154 @@ package com.eactive.eai.custom.alarm.ums; import java.io.IOException; -import java.nio.charset.Charset; -import java.util.Arrays; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Executors; -import java.util.concurrent.Future; +import java.nio.charset.StandardCharsets; + +import javax.annotation.PreDestroy; import org.apache.hc.client5.http.classic.methods.HttpPost; import org.apache.hc.client5.http.config.RequestConfig; import org.apache.hc.client5.http.entity.EntityBuilder; import org.apache.hc.client5.http.impl.classic.CloseableHttpClient; import org.apache.hc.client5.http.impl.classic.HttpClients; +import org.apache.hc.client5.http.impl.io.PoolingHttpClientConnectionManagerBuilder; +import org.apache.hc.client5.http.io.HttpClientConnectionManager; import org.apache.hc.core5.http.ContentType; -import org.apache.hc.core5.http.ProtocolException; import org.apache.hc.core5.http.io.entity.EntityUtils; +import org.apache.hc.core5.util.TimeValue; import org.apache.hc.core5.util.Timeout; import org.springframework.stereotype.Component; -import org.springframework.util.StreamUtils; import com.eactive.eai.common.property.PropManager; import com.eactive.eai.common.util.Jsons; import com.eactive.eai.common.util.Logger; import com.eactive.eai.custom.alarm.ums.payload.UmsRequestPayload; import com.eactive.eai.custom.alarm.ums.payload.ValidationUtil; -import com.google.gson.JsonSyntaxException; @Component public class UmsService { - protected static Logger logger = Logger.getLogger(Logger.LOGGER_DEFAULT); + protected static Logger logger = Logger.getLogger(Logger.LOGGER_DEFAULT); - private final static String UMS_GROUP_PROP_NAME = "UMS"; - private final static String UMS_PROP_HOST = "host"; - private final static String UMS_PROP_URL = "url"; - private final static String UMS_PROP_API_KEY = "apiKey"; - private final static String UMS_URL = "http://172.31.35.144:9021"; - private final static String API_KEY = "7cca6d58-e4f7-474d-9edd-525806bc99ff"; - private final static String SEND_URL = "/ums/openapi/send"; - private final static String CONTENT_TYPE = "application/json; charset=utf-8"; - private final static String AUTHORIZATION_FMT = "Bearer %s"; + // 설정 상수 + private final static String UMS_GROUP_PROP_NAME = "UMS"; + private final static String UMS_PROP_HOST = "host"; + private final static String UMS_PROP_URL = "url"; + private final static String UMS_PROP_API_KEY = "apiKey"; + private final static String UMS_PROP_CONNECTION_TIMEOUT = "timeout.connection.ms"; + private final static String UMS_PROP_TIMEOUT = "timeout.ms"; + + // 기본값 + private final static String DEFAULT_UMS_URL = "http://172.31.35.144:9021"; + private final static String DEFAULT_SEND_URI = "/ums/openapi/send"; + private final static String DEFAULT_API_KEY = "7cca6d58-e4f7-474d-9edd-525806bc99ff"; + private final static String AUTHORIZATION_FMT = "Bearer %s"; - public Future send(UmsRequestPayload payload) throws Exception { + // 재사용되는 HttpClient (Thread-Safe) + private final CloseableHttpClient httpClient; - if (payload.getContent() == null) { - throw new IllegalArgumentException("content is null"); - } + public UmsService() { + // 커넥션 풀 설정: 매번 소켓을 열고 닫지 않고 재사용함 + HttpClientConnectionManager cm = PoolingHttpClientConnectionManagerBuilder.create() + .setMaxConnTotal(100) // 전체 최대 커넥션 수 + .setMaxConnPerRoute(20) // 호스트당 최대 커넥션 수 + .setConnectionTimeToLive(TimeValue.ofMinutes(3)) // TTL + .setValidateAfterInactivity(TimeValue.ofSeconds(5)) // 🔥 중요 + .build(); - try { - ValidationUtil.validateOrThrow(payload); - } catch (Exception ex) { - logger.debug(String.format("UMS Request payload validation failed - %s", payload)); - throw ex; - } + this.httpClient = HttpClients.custom() + .setConnectionManager(cm) + .evictExpiredConnections() // 만료 제거 + .evictIdleConnections(TimeValue.ofSeconds(20)) // 20초 idle 제거 + .build(); + } - return call(payload); - } + public UmsCallResult send(UmsRequestPayload payload) throws Exception { + if (payload.getContent() == null) { + throw new IllegalArgumentException("content is null"); + } - private CloseableHttpClient createHttpClient() { - return HttpClients.createDefault(); - } + try { + ValidationUtil.validateOrThrow(payload); + } catch (Exception ex) { + logger.debug(String.format("UMS Request payload validation failed - %s", payload)); + throw ex; + } - private Future call(UmsRequestPayload requestPayload) throws Exception { + return call(payload); + } - ExecutorService executor = Executors.newSingleThreadExecutor(); - - String json = Jsons.GSON.toJson(requestPayload); - - String host = PropManager.getInstance().getProperty(UMS_GROUP_PROP_NAME, UMS_PROP_HOST, UMS_URL); - String url = PropManager.getInstance().getProperty(UMS_GROUP_PROP_NAME, UMS_PROP_URL, SEND_URL); - String apiKey = PropManager.getInstance().getProperty(UMS_GROUP_PROP_NAME, UMS_PROP_API_KEY, API_KEY); + private UmsCallResult call(UmsRequestPayload requestPayload) throws Exception { + // 1. 프로퍼티 로드 + PropManager prop = PropManager.getInstance(); + String host = prop.getProperty(UMS_GROUP_PROP_NAME, UMS_PROP_HOST, DEFAULT_UMS_URL); + String uri = prop.getProperty(UMS_GROUP_PROP_NAME, UMS_PROP_URL, DEFAULT_SEND_URI); + String apiKey = prop.getProperty(UMS_GROUP_PROP_NAME, UMS_PROP_API_KEY, DEFAULT_API_KEY); + long connectionTimeoutMs = Long.parseLong(prop.getProperty(UMS_GROUP_PROP_NAME, UMS_PROP_CONNECTION_TIMEOUT, "3000")); + long timeoutMs = Long.parseLong(prop.getProperty(UMS_GROUP_PROP_NAME, UMS_PROP_TIMEOUT, "3000")); + // 2. 요청 생성 + HttpPost httpPost = new HttpPost(host + uri); + httpPost.setHeader("Authorization", String.format(AUTHORIZATION_FMT, apiKey)); + + String json = Jsons.GSON.toJson(requestPayload); + httpPost.setEntity(EntityBuilder.create() + .setText(json) + .setContentType(ContentType.APPLICATION_JSON) + .setContentEncoding("UTF-8") + .build()); - HttpPost httpPost = new HttpPost(host + url); - httpPost.setHeader("Content-Type", CONTENT_TYPE); - httpPost.setHeader("Authorization", String.format(AUTHORIZATION_FMT, apiKey)); - httpPost.setEntity(EntityBuilder.create().setText(json).setContentType(ContentType.APPLICATION_JSON).build()); + // 3. 타임아웃 설정 (설정파일 값 적용) + RequestConfig config = RequestConfig.custom() + .setConnectTimeout(Timeout.ofMilliseconds(connectionTimeoutMs)) + .setResponseTimeout(Timeout.ofMilliseconds(timeoutMs)) + .build(); + httpPost.setConfig(config); - if (logger.isDebugEnabled()) { - try { - logger.debug("Header - {}", httpPost.getHeader("Content-Type")); - logger.debug("Header - {}", httpPost.getHeader("Authorization")); - logger.debug("Request Body : {}", - StreamUtils.copyToString(httpPost.getEntity().getContent(), Charset.defaultCharset())); - } catch (ProtocolException | IOException e) { - throw new RuntimeException(e); - } - } + if (logger.isDebugEnabled()) { + logger.debug("UMS Request to: {}", host + uri); + logger.debug("UMS Request Body: {}", json); + } - httpPost.setConfig(RequestConfig.custom().setConnectTimeout(Timeout.ofSeconds(3)) - .setResponseTimeout(Timeout.ofSeconds(3)).build()); - Future future; - try (CloseableHttpClient httpClient = createHttpClient()) { - future = executor.submit(() -> { - return httpClient.execute(httpPost, res -> { - try { - UmsCallResult result; - String body = EntityUtils.toString(res.getEntity()); - if (logger.isDebugEnabled()) { - logger.debug("Response - {}", body); - } - result = Jsons.GSON.fromJson(body, UmsCallResult.class); - result.setUmsMessageId(requestPayload.getMessageIdentityNo()); - result.setSuccess(true); - return result; - } catch (JsonSyntaxException e) { - logger.error("UMS Call error(JSON Syntax)", e); - return UmsCallResult.builder().umsMessageId(requestPayload.getMessageIdentityNo()) - .isSuccess(false).throwable(e).build(); - } catch (Exception e) { - logger.error("UMS Call error", e); - return UmsCallResult.builder().umsMessageId(requestPayload.getMessageIdentityNo()) - .isSuccess(false).throwable(e).build(); - } finally { - logger.debug("Response status - {}", res.getCode()); + // 4. 실행 (HttpClient 재사용) + try { + return httpClient.execute(httpPost, response -> { + String body = EntityUtils.toString(response.getEntity(), StandardCharsets.UTF_8); + + if (logger.isDebugEnabled()) { + logger.debug("UMS Response Status: {}", response.getCode()); + logger.debug("UMS Response Body: {}", body); + } - if (res.getCode() != 200) { - Arrays.asList(res.getHeaders()).forEach(o -> { - logger.warn("[Header] {}: {}", o.getName(), o.getValue()); - }); - } - } - }); - }); + UmsCallResult result = Jsons.GSON.fromJson(body, UmsCallResult.class); + result.setUmsMessageId(requestPayload.getMessageIdentityNo()); + + // HTTP 200인 경우만 성공으로 간주 (필요에 따라 조정) + result.setSuccess(response.getCode() == 200); + + if (response.getCode() != 200) { + logger.warn("UMS Call failed with status: {}", response.getCode()); + } + + return result; + }); + } catch (Exception e) { + logger.error("UMS call exception: " + e.getMessage(), e); + return UmsCallResult.builder() + .umsMessageId(requestPayload.getMessageIdentityNo()) + .isSuccess(false) + .throwable(e) + .build(); + } + } - return future; - } catch (Exception e) { - logger.error("UMS call exception", e); - throw new Exception("UMS call failed", e); - } finally { - executor.shutdown(); - } - - } -} + @PreDestroy + public void destroy() { + try { + if (httpClient != null) { + httpClient.close(); + logger.info("UMS HttpClient closed."); + } + } catch (IOException e) { + logger.error("Error closing UMS HttpClient", e); + } + } +} \ No newline at end of file From d8d816dab7ec46813ce050c50f06f86c898c914c Mon Sep 17 00:00:00 2001 From: cho Date: Thu, 19 Feb 2026 15:53:14 +0900 Subject: [PATCH 146/159] =?UTF-8?q?body=EC=A0=84=EB=AC=B8=20=EC=97=86?= =?UTF-8?q?=EB=8A=94=20variablepath=20=EB=B0=8F=20=EC=98=88=EC=99=B8?= =?UTF-8?q?=EC=B2=98=EB=A6=AC=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../http/client/impl/HttpClient5AdapterServiceRest.java | 9 +++++++-- .../http/dynamic/impl/HttpAdapterServiceBypass.java | 2 +- .../http/dynamic/impl/HttpAdapterServiceRest.java | 2 +- .../http/dynamic/impl/HttpAdapterServiceStandard.java | 2 +- 4 files changed, 10 insertions(+), 5 deletions(-) diff --git a/src/main/java/com/eactive/eai/adapter/http/client/impl/HttpClient5AdapterServiceRest.java b/src/main/java/com/eactive/eai/adapter/http/client/impl/HttpClient5AdapterServiceRest.java index 6c8c548..f3d80bb 100644 --- a/src/main/java/com/eactive/eai/adapter/http/client/impl/HttpClient5AdapterServiceRest.java +++ b/src/main/java/com/eactive/eai/adapter/http/client/impl/HttpClient5AdapterServiceRest.java @@ -1523,12 +1523,17 @@ public class HttpClient5AdapterServiceRest extends HttpClient5AdapterServiceSupp } for (Object tempObject : uriVariables) { String urlVaribleId = (String) tempObject; - String uriVariable = (String) jsonObject.get(urlVaribleId); + String uriVariable = null; + if( jsonObject != null ) { + uriVariable = (String) jsonObject.get(urlVaribleId); + jsonObject.remove(urlVaribleId); + } + if (StringUtils.isBlank(uriVariable) && inboundPathVariables.containsKey(urlVaribleId)) { uriVariable = inboundPathVariables.get(urlVaribleId); } urlVariableList.add(uriVariable); - jsonObject.remove(urlVaribleId); + } } else if (MessageType.XML.equals(messageType)) { Document doc; diff --git a/src/main/java/com/eactive/eai/adapter/http/dynamic/impl/HttpAdapterServiceBypass.java b/src/main/java/com/eactive/eai/adapter/http/dynamic/impl/HttpAdapterServiceBypass.java index 94ef194..7cf71d2 100644 --- a/src/main/java/com/eactive/eai/adapter/http/dynamic/impl/HttpAdapterServiceBypass.java +++ b/src/main/java/com/eactive/eai/adapter/http/dynamic/impl/HttpAdapterServiceBypass.java @@ -131,7 +131,7 @@ public class HttpAdapterServiceBypass extends HttpAdapterServiceSupport { prop.put(INBOUND_URI, request.getRequestURI()); prop.put(INBOUND_QUERY_STRING, StringUtils.defaultString(request.getQueryString())); prop.put(INBOUND_HEADER, getHeaders(request)); - prop.put(INBOUND_EXTPARAMS, request.getQueryString()); + prop.put(INBOUND_EXTPARAMS, StringUtils.defaultString(request.getQueryString())); if (StringUtils.equals(adptVO.getAdapterGroupVO().getType(), Keys.TYPE_REST) || StringUtils.equals(adptVO.getAdapterGroupVO().getType(), Keys.TYPE_HTTP_CUSTOM)) { // /api/v1/public/getUserInfo.svc diff --git a/src/main/java/com/eactive/eai/adapter/http/dynamic/impl/HttpAdapterServiceRest.java b/src/main/java/com/eactive/eai/adapter/http/dynamic/impl/HttpAdapterServiceRest.java index 070d99b..3f3e9af 100644 --- a/src/main/java/com/eactive/eai/adapter/http/dynamic/impl/HttpAdapterServiceRest.java +++ b/src/main/java/com/eactive/eai/adapter/http/dynamic/impl/HttpAdapterServiceRest.java @@ -275,7 +275,7 @@ public class HttpAdapterServiceRest extends HttpAdapterServiceSupport { prop = new Properties(); prop.put(INBOUND_METHOD, request.getMethod()); prop.put(INBOUND_URI, request.getRequestURI()); - prop.put(INBOUND_EXTPARAMS, request.getQueryString()); + prop.put(INBOUND_EXTPARAMS, StringUtils.defaultString(request.getQueryString())); prop.put(INBOUND_HEADER, getHeaders(request)); if (StringUtils.equals(adptVO.getAdapterGroupVO().getType(), Keys.TYPE_REST) || StringUtils.equals(adptVO.getAdapterGroupVO().getType(), Keys.TYPE_HTTP_CUSTOM)) { diff --git a/src/main/java/com/eactive/eai/adapter/http/dynamic/impl/HttpAdapterServiceStandard.java b/src/main/java/com/eactive/eai/adapter/http/dynamic/impl/HttpAdapterServiceStandard.java index b78408f..0dffb4f 100644 --- a/src/main/java/com/eactive/eai/adapter/http/dynamic/impl/HttpAdapterServiceStandard.java +++ b/src/main/java/com/eactive/eai/adapter/http/dynamic/impl/HttpAdapterServiceStandard.java @@ -172,7 +172,7 @@ public class HttpAdapterServiceStandard extends HttpAdapterServiceSupport prop.put(INBOUND_METHOD, request.getMethod()); prop.put(INBOUND_URI, request.getRequestURI()); prop.put(INBOUND_HEADER, getHeaders(request)); - prop.put(INBOUND_EXTPARAMS, request.getQueryString()); + prop.put(INBOUND_EXTPARAMS, StringUtils.defaultString(request.getQueryString())); if (StringUtils.equals(adptVO.getAdapterGroupVO().getType(), Keys.TYPE_REST) || StringUtils.equals(adptVO.getAdapterGroupVO().getType(), Keys.TYPE_HTTP_CUSTOM)) { // /api/v1/public/getUserInfo.svc From fc0daac2eaea18df2b5bd6f17b01c186ff2f1110 Mon Sep 17 00:00:00 2001 From: cho Date: Fri, 20 Feb 2026 13:29:07 +0900 Subject: [PATCH 147/159] =?UTF-8?q?=EB=A1=9C=EA=B9=85=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../eactive/eai/inbound/processor/RequestProcessor.java | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/main/java/com/eactive/eai/inbound/processor/RequestProcessor.java b/src/main/java/com/eactive/eai/inbound/processor/RequestProcessor.java index 25d4c1d..b5cf01a 100644 --- a/src/main/java/com/eactive/eai/inbound/processor/RequestProcessor.java +++ b/src/main/java/com/eactive/eai/inbound/processor/RequestProcessor.java @@ -915,7 +915,10 @@ public class RequestProcessor extends RequestProcessorSupport { rVo = rManager.getRestrictInfoVO(instCode); } if(rVo != null) { + logger.info(String.format("RestrictInfoVO = %s", rVo.getEAICtrlDsticCtnt())); isCheckRestrictTime = checkRestrictTime(rVo); + + logger.info(String.format("isCheckRestrictTime = %s", isCheckRestrictTime)); if(isCheckRestrictTime) { if (logger.isInfo()) { logger.info(guidLogPrefix + " : 거래통제 기관코드["+instCode+"] EAI서비스코드 ["+eaiMsg.getEAISvcCd()+"] GUID["+ guid +"]"); @@ -924,7 +927,10 @@ public class RequestProcessor extends RequestProcessorSupport { } } } else { + + logger.info(String.format("RestrictInfoVO = %s", rVo.getEAICtrlDsticCtnt())); isCheckRestrictTime = checkRestrictTime(rVo); + logger.info(String.format("isCheckRestrictTime = %s", isCheckRestrictTime)); if (logger.isInfo() && isCheckRestrictTime) { logger.info(guidLogPrefix + " : 거래통제 EAI 서비스코드 ["+eaiMsg.getEAISvcCd()+"] GUID["+ guid +"]"); } @@ -939,6 +945,8 @@ public class RequestProcessor extends RequestProcessorSupport { isBlockedApp = true; } } + + logger.info(String.format("clientId = %s", clientId)); if(isBlockedApp || (rVo != null && isCheckRestrictTime)) { // 거래통제 대상 거래일 경우 '1'로 설정한다. From 0f05380cc25945937482d951bd59015c8210cb4d Mon Sep 17 00:00:00 2001 From: cho Date: Fri, 20 Feb 2026 14:15:04 +0900 Subject: [PATCH 148/159] =?UTF-8?q?Revert=20"=EB=A1=9C=EA=B9=85=EC=B6=94?= =?UTF-8?q?=EA=B0=80"?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This reverts commit fc0daac2eaea18df2b5bd6f17b01c186ff2f1110. --- .../eactive/eai/inbound/processor/RequestProcessor.java | 8 -------- 1 file changed, 8 deletions(-) diff --git a/src/main/java/com/eactive/eai/inbound/processor/RequestProcessor.java b/src/main/java/com/eactive/eai/inbound/processor/RequestProcessor.java index b5cf01a..25d4c1d 100644 --- a/src/main/java/com/eactive/eai/inbound/processor/RequestProcessor.java +++ b/src/main/java/com/eactive/eai/inbound/processor/RequestProcessor.java @@ -915,10 +915,7 @@ public class RequestProcessor extends RequestProcessorSupport { rVo = rManager.getRestrictInfoVO(instCode); } if(rVo != null) { - logger.info(String.format("RestrictInfoVO = %s", rVo.getEAICtrlDsticCtnt())); isCheckRestrictTime = checkRestrictTime(rVo); - - logger.info(String.format("isCheckRestrictTime = %s", isCheckRestrictTime)); if(isCheckRestrictTime) { if (logger.isInfo()) { logger.info(guidLogPrefix + " : 거래통제 기관코드["+instCode+"] EAI서비스코드 ["+eaiMsg.getEAISvcCd()+"] GUID["+ guid +"]"); @@ -927,10 +924,7 @@ public class RequestProcessor extends RequestProcessorSupport { } } } else { - - logger.info(String.format("RestrictInfoVO = %s", rVo.getEAICtrlDsticCtnt())); isCheckRestrictTime = checkRestrictTime(rVo); - logger.info(String.format("isCheckRestrictTime = %s", isCheckRestrictTime)); if (logger.isInfo() && isCheckRestrictTime) { logger.info(guidLogPrefix + " : 거래통제 EAI 서비스코드 ["+eaiMsg.getEAISvcCd()+"] GUID["+ guid +"]"); } @@ -945,8 +939,6 @@ public class RequestProcessor extends RequestProcessorSupport { isBlockedApp = true; } } - - logger.info(String.format("clientId = %s", clientId)); if(isBlockedApp || (rVo != null && isCheckRestrictTime)) { // 거래통제 대상 거래일 경우 '1'로 설정한다. From 80bec969314e6c10bcbb07b785b977687cd30f75 Mon Sep 17 00:00:00 2001 From: cho Date: Thu, 26 Feb 2026 15:03:50 +0900 Subject: [PATCH 149/159] =?UTF-8?q?=EB=B0=A9=EC=96=B4=EB=A1=9C=EC=A7=81=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80.............................................?= =?UTF-8?q?............?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../http/client/impl/HttpClient5AdapterServiceRest.java | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/eactive/eai/adapter/http/client/impl/HttpClient5AdapterServiceRest.java b/src/main/java/com/eactive/eai/adapter/http/client/impl/HttpClient5AdapterServiceRest.java index f3d80bb..ef810ae 100644 --- a/src/main/java/com/eactive/eai/adapter/http/client/impl/HttpClient5AdapterServiceRest.java +++ b/src/main/java/com/eactive/eai/adapter/http/client/impl/HttpClient5AdapterServiceRest.java @@ -968,9 +968,11 @@ public class HttpClient5AdapterServiceRest extends HttpClient5AdapterServiceSupp JSONObject jsonObject = (JSONObject) eaiBody; for (Object key : jsonObject.keySet()) { - //String encryptedValue = encrypt((String) jsonObject.get(key)); // encrypt by jwhong - //params.add(new BasicNameValuePair((String) key, encryptedValue )); + + if( jsonObject.get(key) instanceof String ) { params.add(new BasicNameValuePair((String) key, (String) jsonObject.get(key))); + } + } UrlEncodedFormEntity entity = new UrlEncodedFormEntity(params, StandardCharsets.UTF_8); From 1428d3e2faef29277f3ec8e57a0ff9ff4f547515 Mon Sep 17 00:00:00 2001 From: cho Date: Thu, 26 Feb 2026 19:44:36 +0900 Subject: [PATCH 150/159] =?UTF-8?q?=EB=B6=80=ED=95=98=ED=85=8C=EC=8A=A4?= =?UTF-8?q?=ED=8A=B8=EB=A5=BC=20=EC=9C=84=ED=95=9C=20=EB=A1=9C=EA=B7=B8?= =?UTF-8?q?=EB=A0=88=EB=B2=A8=20=EC=A1=B0=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../eactive/eai/common/logger/EAILogDAO.java | 4 +-- .../eai/common/session/SessionManager.java | 1 + .../session/SessionManagerForIgnite.java | 27 ++++++++++++++++++- .../service/DefaultInterfaceMapper.java | 2 +- 4 files changed, 30 insertions(+), 4 deletions(-) diff --git a/src/main/java/com/eactive/eai/common/logger/EAILogDAO.java b/src/main/java/com/eactive/eai/common/logger/EAILogDAO.java index 87fc0da..e8509f1 100644 --- a/src/main/java/com/eactive/eai/common/logger/EAILogDAO.java +++ b/src/main/java/com/eactive/eai/common/logger/EAILogDAO.java @@ -239,8 +239,8 @@ public class EAILogDAO { if (svcLogLvl > 3) { loggingBizData = false; } - if (logger.isWarn()) - logger.warn("EAILogDAO] loggingBizData - " + loggingBizData); + if (logger.isInfo()) + logger.info("EAILogDAO] loggingBizData - " + loggingBizData); // 복합거래인 경우 2X1,3X1 -> 200, 2X2,3X2 -> 300 처럼 처리한다. if ((logPssSno > 200 && logPssSno < 300) || (logPssSno > 300 && logPssSno < 400)) { diff --git a/src/main/java/com/eactive/eai/common/session/SessionManager.java b/src/main/java/com/eactive/eai/common/session/SessionManager.java index acfa0f1..1136743 100644 --- a/src/main/java/com/eactive/eai/common/session/SessionManager.java +++ b/src/main/java/com/eactive/eai/common/session/SessionManager.java @@ -68,6 +68,7 @@ public abstract class SessionManager implements Lifecycle { public static final String SESSION_MANAGER_EXPIRE_INTERVAL = "expireInterval"; public static final String SESSION_MANAGER_MULTI_GROUP_IP = "multi_group_ip"; + public static final String LOGGER_LEVEL = "loggerLevel"; public static final String SESSION_MANAGER_MULTI_GROUP_PORT = "multi_group_port"; public static final String SESSION_MANAGER_SESSION_TIMEOUT = "sessionTimeout"; public static final String SESSION_MANAGER_WEBSOCKET_TIMEOUT = "webSocketTimeout"; diff --git a/src/main/java/com/eactive/eai/common/session/SessionManagerForIgnite.java b/src/main/java/com/eactive/eai/common/session/SessionManagerForIgnite.java index 55650a4..b145f7f 100644 --- a/src/main/java/com/eactive/eai/common/session/SessionManagerForIgnite.java +++ b/src/main/java/com/eactive/eai/common/session/SessionManagerForIgnite.java @@ -333,7 +333,32 @@ public class SessionManagerForIgnite extends SessionManager { ch.qos.logback.classic.Logger blogger = (ch.qos.logback.classic.Logger) org.slf4j.LoggerFactory .getLogger("org.apache.ignite"); - blogger.setLevel(Level.INFO); + + String loggerLevel = prpty.getProperty(SessionManager.LOGGER_LEVEL, "ERROR"); + + switch(loggerLevel) { + case "ERROR": + blogger.setLevel(Level.ERROR); + break; + case "INFO": + blogger.setLevel(Level.INFO); + break; + case "WARN": + blogger.setLevel(Level.WARN); + break; + case "DEBUG": + blogger.setLevel(Level.DEBUG); + break; + case "TRACE": + blogger.setLevel(Level.TRACE); + break; + } + + if( logger.isDebug() ) { + + logger.debug("Ignite loggerLevel = "+loggerLevel); + + } IgniteLogger log = new Slf4jLogger((org.slf4j.Logger) blogger); config.setGridLogger(log); diff --git a/src/main/java/com/eactive/eai/message/service/DefaultInterfaceMapper.java b/src/main/java/com/eactive/eai/message/service/DefaultInterfaceMapper.java index 638c5d7..b5f0139 100644 --- a/src/main/java/com/eactive/eai/message/service/DefaultInterfaceMapper.java +++ b/src/main/java/com/eactive/eai/message/service/DefaultInterfaceMapper.java @@ -21,7 +21,7 @@ public class DefaultInterfaceMapper implements InterfaceMapper { protected String getPath(String key) { String path = itemPathMap.get(key); if(StringUtils.isBlank(path)) { - logger.warn("message-mapping not defined key = {}", key); + logger.debug("message-mapping not defined key = {}", key); } return path; } From 640f1e4f1e1b6751826923ebcf4481ce258ceecc Mon Sep 17 00:00:00 2001 From: cho Date: Fri, 27 Feb 2026 13:30:52 +0900 Subject: [PATCH 151/159] =?UTF-8?q?HttpClientConnectionManager=EC=97=90?= =?UTF-8?q?=EC=84=9C=20SSLContext=20=EC=83=9D=EC=84=B1=EC=8B=9C,=20entropy?= =?UTF-8?q?=20source(/dev/random)=EC=97=90=EC=84=9C=20=EB=9E=9C=EB=8D=A4?= =?UTF-8?q?=EC=8B=9C=EB=93=9C=EA=B0=92=20=EA=B0=80=EC=A0=B8=EC=98=AC?= =?UTF-8?q?=EB=95=8C,=20=EC=98=A4=EB=9E=98=EA=B1=B8=EB=A6=BC=20=EC=9D=B4?= =?UTF-8?q?=EC=8A=88.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit -Djava.security.egd=file:/dev/./urandom 설정이 들어가있지만, java security provider가 BC사용중이라 안먹는 것 같음. provider를 바꾸자니 성능 테스트 진행 중이라 영향이 갈수있으므로, Pooling 방식 제거. --- .../eai/custom/alarm/ums/UmsService.java | 41 +++---------------- 1 file changed, 5 insertions(+), 36 deletions(-) diff --git a/src/main/java/com/eactive/eai/custom/alarm/ums/UmsService.java b/src/main/java/com/eactive/eai/custom/alarm/ums/UmsService.java index 74777de..cc2b114 100644 --- a/src/main/java/com/eactive/eai/custom/alarm/ums/UmsService.java +++ b/src/main/java/com/eactive/eai/custom/alarm/ums/UmsService.java @@ -1,20 +1,15 @@ package com.eactive.eai.custom.alarm.ums; -import java.io.IOException; import java.nio.charset.StandardCharsets; -import javax.annotation.PreDestroy; - import org.apache.hc.client5.http.classic.methods.HttpPost; import org.apache.hc.client5.http.config.RequestConfig; import org.apache.hc.client5.http.entity.EntityBuilder; import org.apache.hc.client5.http.impl.classic.CloseableHttpClient; import org.apache.hc.client5.http.impl.classic.HttpClients; -import org.apache.hc.client5.http.impl.io.PoolingHttpClientConnectionManagerBuilder; -import org.apache.hc.client5.http.io.HttpClientConnectionManager; import org.apache.hc.core5.http.ContentType; +import org.apache.hc.core5.http.HttpVersion; import org.apache.hc.core5.http.io.entity.EntityUtils; -import org.apache.hc.core5.util.TimeValue; import org.apache.hc.core5.util.Timeout; import org.springframework.stereotype.Component; @@ -43,24 +38,6 @@ public class UmsService { private final static String DEFAULT_API_KEY = "7cca6d58-e4f7-474d-9edd-525806bc99ff"; private final static String AUTHORIZATION_FMT = "Bearer %s"; - // 재사용되는 HttpClient (Thread-Safe) - private final CloseableHttpClient httpClient; - - public UmsService() { - // 커넥션 풀 설정: 매번 소켓을 열고 닫지 않고 재사용함 - HttpClientConnectionManager cm = PoolingHttpClientConnectionManagerBuilder.create() - .setMaxConnTotal(100) // 전체 최대 커넥션 수 - .setMaxConnPerRoute(20) // 호스트당 최대 커넥션 수 - .setConnectionTimeToLive(TimeValue.ofMinutes(3)) // TTL - .setValidateAfterInactivity(TimeValue.ofSeconds(5)) // 🔥 중요 - .build(); - - this.httpClient = HttpClients.custom() - .setConnectionManager(cm) - .evictExpiredConnections() // 만료 제거 - .evictIdleConnections(TimeValue.ofSeconds(20)) // 20초 idle 제거 - .build(); - } public UmsCallResult send(UmsRequestPayload payload) throws Exception { if (payload.getContent() == null) { @@ -95,6 +72,9 @@ public class UmsService { .setContentType(ContentType.APPLICATION_JSON) .setContentEncoding("UTF-8") .build()); + + httpPost.setVersion(HttpVersion.HTTP_1_0); + httpPost.setHeader("Connection", "close"); // 3. 타임아웃 설정 (설정파일 값 적용) RequestConfig config = RequestConfig.custom() @@ -109,7 +89,7 @@ public class UmsService { } // 4. 실행 (HttpClient 재사용) - try { + try (CloseableHttpClient httpClient = HttpClients.createDefault()) { return httpClient.execute(httpPost, response -> { String body = EntityUtils.toString(response.getEntity(), StandardCharsets.UTF_8); @@ -140,15 +120,4 @@ public class UmsService { } } - @PreDestroy - public void destroy() { - try { - if (httpClient != null) { - httpClient.close(); - logger.info("UMS HttpClient closed."); - } - } catch (IOException e) { - logger.error("Error closing UMS HttpClient", e); - } - } } \ No newline at end of file From 78bc0cb6cd3c6b42da4d143baad0aeefced8857a Mon Sep 17 00:00:00 2001 From: cho Date: Fri, 27 Feb 2026 15:51:41 +0900 Subject: [PATCH 152/159] =?UTF-8?q?JavaSecurityProvider=20=EC=9A=B0?= =?UTF-8?q?=EC=84=A0=EC=88=9C=EC=9C=84=20=ED=99=95=EC=9D=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/com/eactive/eai/common/web/AppInitializer.java | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/main/java/com/eactive/eai/common/web/AppInitializer.java b/src/main/java/com/eactive/eai/common/web/AppInitializer.java index 7b1e723..8824c1f 100644 --- a/src/main/java/com/eactive/eai/common/web/AppInitializer.java +++ b/src/main/java/com/eactive/eai/common/web/AppInitializer.java @@ -6,6 +6,8 @@ import java.lang.reflect.Method; import java.net.InetAddress; import java.nio.charset.Charset; import java.rmi.RemoteException; +import java.security.Security; +import java.util.Arrays; import javax.sql.DataSource; @@ -399,6 +401,9 @@ public class AppInitializer implements InitializingBean, DisposableBean { if (pRmiServicePort != null) { this.rmiServicePort = pRmiServicePort; } + + Arrays.stream(Security.getProviders()) + .forEach(p -> System.out.println("JavaSecurityProviders=" + p.getName())); try { logger.warn("\n@@ eLink RMI Register Port : " + rmiPort + ", Service Port : " + rmiServicePort); From 3957e4559e950b1d199073987bcf813a4f7348f4 Mon Sep 17 00:00:00 2001 From: cho Date: Fri, 27 Feb 2026 15:53:32 +0900 Subject: [PATCH 153/159] =?UTF-8?q?=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/com/eactive/eai/common/web/AppInitializer.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/main/java/com/eactive/eai/common/web/AppInitializer.java b/src/main/java/com/eactive/eai/common/web/AppInitializer.java index 8824c1f..3bbb382 100644 --- a/src/main/java/com/eactive/eai/common/web/AppInitializer.java +++ b/src/main/java/com/eactive/eai/common/web/AppInitializer.java @@ -205,6 +205,8 @@ public class AppInitializer implements InitializingBean, DisposableBean { * eLink FrameWork의 웹어플리케이션이 될 때 초기화 작업을 수행 **/ private void init() { + + ElinkStateManager.getInstance().setWaitMaxMs(shutdownWaitSecs * 1000); ElinkStateManager.getInstance().setSleepIntervalMs(shutdownWaitIntervalMs); ElinkStateManager.getInstance().starting(); @@ -403,7 +405,7 @@ public class AppInitializer implements InitializingBean, DisposableBean { } Arrays.stream(Security.getProviders()) - .forEach(p -> System.out.println("JavaSecurityProviders=" + p.getName())); + .forEach(p -> System.out.println("JavaSecurityProviders name=" + p.getName() +" / info="+ p.getInfo() +" / version="+ p.getVersion())); try { logger.warn("\n@@ eLink RMI Register Port : " + rmiPort + ", Service Port : " + rmiServicePort); From dfcec99576a2b517aa2200986fcbf065f7349d49 Mon Sep 17 00:00:00 2001 From: cho Date: Fri, 27 Feb 2026 16:00:25 +0900 Subject: [PATCH 154/159] =?UTF-8?q?bouncycastle=20=EC=A0=9C=EA=B1=B0.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/com/eactive/eai/common/web/AppInitializer.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/main/java/com/eactive/eai/common/web/AppInitializer.java b/src/main/java/com/eactive/eai/common/web/AppInitializer.java index 3bbb382..e10fcb4 100644 --- a/src/main/java/com/eactive/eai/common/web/AppInitializer.java +++ b/src/main/java/com/eactive/eai/common/web/AppInitializer.java @@ -406,6 +406,8 @@ public class AppInitializer implements InitializingBean, DisposableBean { Arrays.stream(Security.getProviders()) .forEach(p -> System.out.println("JavaSecurityProviders name=" + p.getName() +" / info="+ p.getInfo() +" / version="+ p.getVersion())); + + Security.removeProvider("BC"); try { logger.warn("\n@@ eLink RMI Register Port : " + rmiPort + ", Service Port : " + rmiServicePort); From 8b722996895ead9ec42b445f1652fb08c98fe132 Mon Sep 17 00:00:00 2001 From: cho Date: Tue, 3 Mar 2026 14:09:55 +0900 Subject: [PATCH 155/159] =?UTF-8?q?system=5Fout=5F=EC=A0=9C=EA=B1=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- settings.gradle | 4 +- .../eai/adapter/db/sql/AdapterUtils.java | 4 +- .../adapter/db/sql/DBInboudSqlAdapter.java | 2 +- .../impl/HttpClient5AdapterServiceRest.java | 4 +- .../impl/HttpAdapterServiceBypass.java | 2 +- .../dynamic/wrapper/KeepAliveTrueWrapper.java | 2 +- .../eai/adapter/jtc/JtcBeanSample.java | 10 ++-- .../eai/adapter/jtc/JtcClientSample.java | 6 +- .../eai/adapter/jtc/JtcServerAdapterBean.java | 2 +- .../eai/adapter/jtc/TestMsgListener.java | 5 +- .../adapter/socket2/app/dump/DumpServer.java | 6 +- .../adapter/socket2/app/echo/EchoServer.java | 4 +- .../eai/adapter/socket2/app/muxer/Muxer.java | 14 ++--- .../socket2/app/proxy/ProxyServer.java | 2 +- .../socket2/app/tester/LoadRunner.java | 56 +++++++++--------- .../socket2/app/tester/LoadRunner2.java | 58 +++++++++---------- .../adapter/socket2/common/ExpiringMap.java | 10 ++-- .../protocol/admin/TelnetAdminHandler.java | 2 +- .../adapter/socket2/protocol/http/Server.java | 4 +- .../protocol/http/codec/HttpResponse.java | 4 +- .../adapter/socket2/tool/admin/NetAdmin.java | 6 +- .../eai/adapter/socket2/tool/admin/Shell.java | 10 ++-- .../eai/adapter/wca/WCASessionThread.java | 4 +- .../eai/adapter/wca/data/WCAQueue.java | 2 +- .../eactive/eai/adapter/wca/util/MyLog.java | 4 +- ...HttpClientAccessTokenServiceWithParam.java | 4 +- .../circuitBreaker/PrometheusController.java | 2 +- .../eactive/eai/common/logger/EAILogDAO.java | 4 +- .../eai/common/state/ElinkStateManager.java | 2 +- .../com/eactive/eai/env/SystemPropConfig.java | 4 +- .../eai/flowcontroller/C2RFCProcess.java | 2 +- .../inbound/processor/RequestProcessor.java | 2 +- .../eai/message/StandardMessageUtil.java | 16 ++--- .../eactive/eai/util/ByteCharSequence.java | 2 +- .../java/com/eactive/eai/util/CryptoUtil.java | 10 ++-- .../java/com/eactive/eai/util/IpUtil.java | 4 +- .../com/eactive/eai/util/JsonBeatiUtil.java | 2 +- .../com/eactive/eai/util/JsonPathUtil.java | 12 ++-- .../eai/util/json/JsonPathsTransform.java | 2 +- .../util/json/JsonSimplePathsTransform.java | 2 +- .../eai/common/header/SHINBOHeaderAction.java | 2 +- .../eai/common/loader/EAILogFIleLoader.java | 46 +++++++-------- 42 files changed, 173 insertions(+), 172 deletions(-) diff --git a/settings.gradle b/settings.gradle index 0791851..082155b 100644 --- a/settings.gradle +++ b/settings.gradle @@ -3,7 +3,9 @@ rootProject.name = 'elink-online-common' include 'elink-online-core-jpa' include 'elink-online-core' include 'elink-online-transformer' +include 'elink-online-alarm' project (':elink-online-core-jpa').projectDir = new File(settingsDir, "../elink-online-core-jpa") project (':elink-online-core').projectDir = new File(settingsDir, "../elink-online-core") -project (':elink-online-transformer').projectDir = new File(settingsDir, "../elink-online-transformer") \ No newline at end of file +project (':elink-online-transformer').projectDir = new File(settingsDir, "../elink-online-transformer") +project (':elink-online-alarm').projectDir = new File(settingsDir, "../elink-online-alarm") \ No newline at end of file diff --git a/src/main/java/com/eactive/eai/adapter/db/sql/AdapterUtils.java b/src/main/java/com/eactive/eai/adapter/db/sql/AdapterUtils.java index 28279ec..2da8689 100644 --- a/src/main/java/com/eactive/eai/adapter/db/sql/AdapterUtils.java +++ b/src/main/java/com/eactive/eai/adapter/db/sql/AdapterUtils.java @@ -14,8 +14,8 @@ public class AdapterUtils { map.put("Unid", "ID00000001"); String prefix = "%", surfix = "%"; - System.out.println(updateSql); - System.out.println(getUpdateQuery(updateSql, map, prefix, surfix)); + // System.out.println(updateSql); + // System.out.println(getUpdateQuery(updateSql, map, prefix, surfix)); } public static Properties getAdapterProerties(String propGroupName) { diff --git a/src/main/java/com/eactive/eai/adapter/db/sql/DBInboudSqlAdapter.java b/src/main/java/com/eactive/eai/adapter/db/sql/DBInboudSqlAdapter.java index 7a4797b..050c3ac 100644 --- a/src/main/java/com/eactive/eai/adapter/db/sql/DBInboudSqlAdapter.java +++ b/src/main/java/com/eactive/eai/adapter/db/sql/DBInboudSqlAdapter.java @@ -56,7 +56,7 @@ public class DBInboudSqlAdapter { if(isLocal != null && "true".equalsIgnoreCase(isLocal)) { isLocalTest = true; } - System.out.println("$$$ DBInboudSqlAdapter] isLocalTest = " + isLocalTest); + // System.out.println("$$$ DBInboudSqlAdapter] isLocalTest = " + isLocalTest); } public boolean execute() { diff --git a/src/main/java/com/eactive/eai/adapter/http/client/impl/HttpClient5AdapterServiceRest.java b/src/main/java/com/eactive/eai/adapter/http/client/impl/HttpClient5AdapterServiceRest.java index ef810ae..2b699de 100644 --- a/src/main/java/com/eactive/eai/adapter/http/client/impl/HttpClient5AdapterServiceRest.java +++ b/src/main/java/com/eactive/eai/adapter/http/client/impl/HttpClient5AdapterServiceRest.java @@ -1122,10 +1122,10 @@ public class HttpClient5AdapterServiceRest extends HttpClient5AdapterServiceSupp ECDHESA256Cipher cipher = new ECDHESA256Cipher(); encryptedMessage = cipher.encrypt(eaiBody.toString()); - System.out.println("Encrypted JWE: " + encryptedMessage); + // System.out.println("Encrypted JWE: " + encryptedMessage); String decrypted = cipher.decrypt(encryptedMessage); - System.out.println("Decrypted Payload: " + decrypted); + // System.out.println("Decrypted Payload: " + decrypted); //아래 인증서로 테스트 ECDHESA256Cipher cipherCert = new ECDHESA256Cipher(certPath); diff --git a/src/main/java/com/eactive/eai/adapter/http/dynamic/impl/HttpAdapterServiceBypass.java b/src/main/java/com/eactive/eai/adapter/http/dynamic/impl/HttpAdapterServiceBypass.java index 7cf71d2..dd5ab69 100644 --- a/src/main/java/com/eactive/eai/adapter/http/dynamic/impl/HttpAdapterServiceBypass.java +++ b/src/main/java/com/eactive/eai/adapter/http/dynamic/impl/HttpAdapterServiceBypass.java @@ -504,6 +504,6 @@ public class HttpAdapterServiceBypass extends HttpAdapterServiceSupport { String orgUri = "/HTT/CbsInNetSys/abcd/123456"; String result = ""; result = getExtUri(orgUri, 3); - System.out.println(result); + // System.out.println(result); } } diff --git a/src/main/java/com/eactive/eai/adapter/http/dynamic/wrapper/KeepAliveTrueWrapper.java b/src/main/java/com/eactive/eai/adapter/http/dynamic/wrapper/KeepAliveTrueWrapper.java index ae9e4fc..4364ead 100644 --- a/src/main/java/com/eactive/eai/adapter/http/dynamic/wrapper/KeepAliveTrueWrapper.java +++ b/src/main/java/com/eactive/eai/adapter/http/dynamic/wrapper/KeepAliveTrueWrapper.java @@ -54,7 +54,7 @@ public class KeepAliveTrueWrapper implements HandlerWrapper { // 최대 요청 횟수를 초과한 경우 연결을 종료하고 로그를 출력 if (count > maxRequestCount) { exchange.getConnection().close(); - System.out.println("Connection closed due to exceeding max requests limit."); + // System.out.println("Connection closed due to exceeding max requests limit."); return; } handler.handleRequest(exchange); diff --git a/src/main/java/com/eactive/eai/adapter/jtc/JtcBeanSample.java b/src/main/java/com/eactive/eai/adapter/jtc/JtcBeanSample.java index 705afc9..87a1d47 100644 --- a/src/main/java/com/eactive/eai/adapter/jtc/JtcBeanSample.java +++ b/src/main/java/com/eactive/eai/adapter/jtc/JtcBeanSample.java @@ -45,7 +45,7 @@ public class JtcBeanSample implements JtmaxService { String bufferType = tux.getBufferTypeString(); if ("STRING".equals(bufferType)) { TuxStringBuffer tuxbuf = (TuxStringBuffer) tux; - System.out.println("received string value : " + tuxbuf.getString()); + // System.out.println("received string value : " + tuxbuf.getString()); TuxStringBuffer ret = new TuxStringBuffer(WebtSystem.getDefaultCharset()); ret.setString(tuxbuf.getString().toUpperCase()); return ret; @@ -60,8 +60,8 @@ public class JtcBeanSample implements JtmaxService { } String rtnstr = rcvstr.toUpperCase(); - System.out.println("received string value : " + rcvstr); - System.out.println("return string value : " + rtnstr); + // System.out.println("received string value : " + rcvstr); + // System.out.println("return string value : " + rtnstr); TuxCarrayBuffer ret = new TuxCarrayBuffer(WebtSystem.getDefaultCharset()); ret.setBytes(rtnstr.getBytes());; return ret; @@ -73,8 +73,8 @@ public class JtcBeanSample implements JtmaxService { String rcvstr = tuxbuf.getField("SEC100").get().stringValue(); String rtnstr = rcvstr.toUpperCase(); - System.out.println("received string value : " + rcvstr); - System.out.println("return string value : " + rtnstr); + // System.out.println("received string value : " + rcvstr); + // System.out.println("return string value : " + rtnstr); TuxFieldBuffer ret = new TuxFieldBuffer(false); // FML 16임으로 false로 // ret.createField(sample.fml_sec2).add(rtnstr); ret.createField("SEC2").add(rtnstr); diff --git a/src/main/java/com/eactive/eai/adapter/jtc/JtcClientSample.java b/src/main/java/com/eactive/eai/adapter/jtc/JtcClientSample.java index dd90520..cf80d3e 100644 --- a/src/main/java/com/eactive/eai/adapter/jtc/JtcClientSample.java +++ b/src/main/java/com/eactive/eai/adapter/jtc/JtcClientSample.java @@ -73,7 +73,7 @@ public class JtcClientSample { try { // if(cd == null) { - System.out.println("tpconnect failed!"); + // System.out.println("tpconnect failed!"); // } // else { @@ -84,12 +84,12 @@ public class JtcClientSample { sndbuf.setString("conversation service"); TuxBuffer rcvbuf = service.tpcall(sndbuf); - System.out.println(rcvbuf.getString()); + // System.out.println(rcvbuf.getString()); // } } catch (WebtException e) { e.printStackTrace(); - System.out.println("error Occurred"); + // System.out.println("error Occurred"); } finally { diff --git a/src/main/java/com/eactive/eai/adapter/jtc/JtcServerAdapterBean.java b/src/main/java/com/eactive/eai/adapter/jtc/JtcServerAdapterBean.java index 74ccd59..211cf54 100644 --- a/src/main/java/com/eactive/eai/adapter/jtc/JtcServerAdapterBean.java +++ b/src/main/java/com/eactive/eai/adapter/jtc/JtcServerAdapterBean.java @@ -58,7 +58,7 @@ public class JtcServerAdapterBean implements JtmaxService { try { if ("STRING".equals(bufferType)) { TuxStringBuffer tuxbuf = (TuxStringBuffer) tux; - System.out.println("received string value : " + tuxbuf.getString()); + // System.out.println("received string value : " + tuxbuf.getString()); byte[] request = tuxbuf.getString().getBytes(); RequestDispatcher dispatcher = RequestDispatcher.getRequestDispatcher(adapterGroupName); byte[] response = (byte[]) dispatcher.handle(adapterName, request, prop); diff --git a/src/main/java/com/eactive/eai/adapter/jtc/TestMsgListener.java b/src/main/java/com/eactive/eai/adapter/jtc/TestMsgListener.java index 6ed12d0..46fcd28 100644 --- a/src/main/java/com/eactive/eai/adapter/jtc/TestMsgListener.java +++ b/src/main/java/com/eactive/eai/adapter/jtc/TestMsgListener.java @@ -31,12 +31,11 @@ public class TestMsgListener implements TuxAsyncMsgListener { } public void handleError(Exception e) { - System.out.println(e); + // System.out.println(e); } public void handleEvent(TuxBuffer rcvBuffer) { - System.out.println(Thread.currentThread().getName() - +" ] rcv " + rcvBuffer); + // System.out.println(Thread.currentThread().getName()+" ] rcv " + rcvBuffer); try { // TODO : Call Internal service } diff --git a/src/main/java/com/eactive/eai/adapter/socket2/app/dump/DumpServer.java b/src/main/java/com/eactive/eai/adapter/socket2/app/dump/DumpServer.java index 707db00..5004e19 100644 --- a/src/main/java/com/eactive/eai/adapter/socket2/app/dump/DumpServer.java +++ b/src/main/java/com/eactive/eai/adapter/socket2/app/dump/DumpServer.java @@ -9,7 +9,7 @@ import com.eactive.eai.adapter.socket2.protocol.ISocketAdapter; public class DumpServer { static public void main(String[] args) throws Exception { if (args.length != 1) { - System.out.println("Usage : dump "); + // System.out.println("Usage : dump "); return; } int port = Integer.parseInt(args[0]); @@ -53,12 +53,12 @@ public class DumpServer { System.out.print("> "); String cmd = (new java.io.BufferedReader(new java.io.InputStreamReader(System.in))).readLine(); if ("".equals(cmd)) { - System.out.println(SocketAdapterManager.getInstance()); + // System.out.println(SocketAdapterManager.getInstance()); } else if ("exit".equals(cmd)) { System.exit(1); } } catch(Exception e) { - System.out.println(e.toString()); + // System.out.println(e.toString()); } } } diff --git a/src/main/java/com/eactive/eai/adapter/socket2/app/echo/EchoServer.java b/src/main/java/com/eactive/eai/adapter/socket2/app/echo/EchoServer.java index 7f7d510..dba092a 100644 --- a/src/main/java/com/eactive/eai/adapter/socket2/app/echo/EchoServer.java +++ b/src/main/java/com/eactive/eai/adapter/socket2/app/echo/EchoServer.java @@ -46,12 +46,12 @@ public class EchoServer { System.out.print("> "); String cmd = (new java.io.BufferedReader(new java.io.InputStreamReader(System.in))).readLine(); if ("".equals(cmd)) { - System.out.println(SocketAdapterManager.getInstance()); + // System.out.println(SocketAdapterManager.getInstance()); } else if ("exit".equals(cmd)) { System.exit(1); } } catch(Exception e) { - System.out.println("processCommand errpr "+ e.toString()); + // System.out.println("processCommand errpr "+ e.toString()); } } } diff --git a/src/main/java/com/eactive/eai/adapter/socket2/app/muxer/Muxer.java b/src/main/java/com/eactive/eai/adapter/socket2/app/muxer/Muxer.java index d69560e..ca4ccbe 100644 --- a/src/main/java/com/eactive/eai/adapter/socket2/app/muxer/Muxer.java +++ b/src/main/java/com/eactive/eai/adapter/socket2/app/muxer/Muxer.java @@ -49,15 +49,15 @@ public class Muxer { } public synchronized byte[] handle(byte[] message) { - System.out.println("##############################################################"); - System.out.println("CiscoListener | message received : " + new String(message)); - System.out.println("##############################################################"); + // System.out.println("##############################################################"); + // System.out.println("CiscoListener | message received : " + new String(message)); + // System.out.println("##############################################################"); return message; } static public void main(String[] args) throws Exception { if (args.length != 3) { - System.out.println("java " + Muxer.class.getName() + " "); + // System.out.println("java " + Muxer.class.getName() + " "); return; } @@ -77,9 +77,9 @@ class MuxerRequestProcessor implements IRequestProcessor { } public synchronized byte[] handle(byte[] message) throws EAIException { - System.out.println("##############################################################"); - System.out.println("MuxerRequestProcessor | message received : " + new String(message)); - System.out.println("##############################################################"); + // System.out.println("##############################################################"); + // System.out.println("MuxerRequestProcessor | message received : " + new String(message)); + // System.out.println("##############################################################"); return (byte[]) outboundAdapter.sendMessage(message); } diff --git a/src/main/java/com/eactive/eai/adapter/socket2/app/proxy/ProxyServer.java b/src/main/java/com/eactive/eai/adapter/socket2/app/proxy/ProxyServer.java index 38f238a..d4114f3 100644 --- a/src/main/java/com/eactive/eai/adapter/socket2/app/proxy/ProxyServer.java +++ b/src/main/java/com/eactive/eai/adapter/socket2/app/proxy/ProxyServer.java @@ -34,7 +34,7 @@ public class ProxyServer { static public void main(String[] args) throws Exception { if (args.length != 3) { - System.out.println("java " + ProxyServer.class.getName() + " "); + // System.out.println("java " + ProxyServer.class.getName() + " "); return; } diff --git a/src/main/java/com/eactive/eai/adapter/socket2/app/tester/LoadRunner.java b/src/main/java/com/eactive/eai/adapter/socket2/app/tester/LoadRunner.java index 4d2ca64..2fb9795 100644 --- a/src/main/java/com/eactive/eai/adapter/socket2/app/tester/LoadRunner.java +++ b/src/main/java/com/eactive/eai/adapter/socket2/app/tester/LoadRunner.java @@ -188,9 +188,9 @@ public class LoadRunner { } stopLatch.countDown(); } catch (Exception e) { - System.out.println(e.toString()); + // System.out.println(e.toString()); } catch (Error e) { - System.out.println(e.toString()); + // System.out.println(e.toString()); } } }); @@ -202,7 +202,7 @@ public class LoadRunner { stopLatch.await(); } catch (InterruptedException ex) { //ex.printStackTrace(); - System.out.println("wait error"); + // System.out.println("wait error"); } executor.shutdown(); @@ -211,27 +211,27 @@ public class LoadRunner { boolean result = executor.awaitTermination(1000, TimeUnit.MILLISECONDS); if (result) break; - System.out.println("[LoadRunner] shutdown() progressing ... await 1 seconds more"); + // System.out.println("[LoadRunner] shutdown() progressing ... await 1 seconds more"); } catch (InterruptedException e) { //e.printStackTrace(); - System.out.println("awaitTermination error"); + // System.out.println("awaitTermination error"); } } latch.await(); stopWatch.stop(); - System.out.println(); - System.out.println(); - System.out.println("==============================================================="); - System.out.println(" think time : " + thinkTime + " ms"); - System.out.println(" thread count : " + threadCount); - System.out.println(" loop count : " + loopCount); - System.out.println(" total request : " + (threadCount * loopCount)); - System.out.println(" elapsed : " + stopWatch.toString()); - System.out.println(" tps : " + new Integer(threadCount * loopCount * 1000).longValue() / stopWatch.getTime()); - System.out.println("==============================================================="); - System.out.println(); + // System.out.println(); + // System.out.println(); + // System.out.println("==============================================================="); + // System.out.println(" think time : " + thinkTime + " ms"); + // System.out.println(" thread count : " + threadCount); + // System.out.println(" loop count : " + loopCount); + // System.out.println(" total request : " + (threadCount * loopCount)); + // System.out.println(" elapsed : " + stopWatch.toString()); + // System.out.println(" tps : " + new Integer(threadCount * loopCount * 1000).longValue() / stopWatch.getTime()); + // System.out.println("==============================================================="); + // System.out.println(); } @@ -245,13 +245,13 @@ public class LoadRunner { break; } else if ("".equals(line.trim())) { } else if ("help".equals(line.trim())) { - System.out.println("==============================================================="); - System.out.println("LoadRunner v1.0 (http port = 8282)"); - System.out.println("==============================================================="); - System.out.println(" help : help"); - System.out.println(" start : start [thread count] [loop count] [think time]"); - System.out.println(" exit : exit"); - System.out.println(""); + // System.out.println("==============================================================="); + // System.out.println("LoadRunner v1.0 (http port = 8282)"); + // System.out.println("==============================================================="); + // System.out.println(" help : help"); + // System.out.println(" start : start [thread count] [loop count] [think time]"); + // System.out.println(" exit : exit"); + // System.out.println(""); } else if (line.trim().startsWith("start")) { String[] tokens = line.trim().split("[ ]+"); if (tokens.length > 1) @@ -264,10 +264,10 @@ public class LoadRunner { } else if ("exit".equals(line.trim())) { System.exit(1); } else { - System.out.println("Unknow command. type help."); + // System.out.println("Unknow command. type help."); } } catch(Exception e) { - System.out.println("Error " + e.toString()); + // System.out.println("Error " + e.toString()); } } } @@ -298,7 +298,7 @@ public class LoadRunner { if(br != null) br.close(); } catch(Exception ee) { - System.out.println("close error"); + // System.out.println("close error"); } } @@ -369,10 +369,10 @@ public class LoadRunner { if (args.length == 2) { hostname = args[0]; - System.out.println("remote host : " + hostname); + // System.out.println("remote host : " + hostname); filename = args[1]; } else { - System.out.println("Usage : loadrunner [ip] [file]"); + // System.out.println("Usage : loadrunner [ip] [file]"); return; } diff --git a/src/main/java/com/eactive/eai/adapter/socket2/app/tester/LoadRunner2.java b/src/main/java/com/eactive/eai/adapter/socket2/app/tester/LoadRunner2.java index 2248622..a2724f5 100644 --- a/src/main/java/com/eactive/eai/adapter/socket2/app/tester/LoadRunner2.java +++ b/src/main/java/com/eactive/eai/adapter/socket2/app/tester/LoadRunner2.java @@ -189,10 +189,10 @@ public class LoadRunner2 { stopLatch.countDown(); } catch (Exception e) { // e.printStackTrace(); - System.out.println("executor.execute Exception"); + // System.out.println("executor.execute Exception"); } catch (Error e) { // e.printStackTrace(); - System.out.println("executor.execute error"); + // System.out.println("executor.execute error"); } } }); @@ -204,7 +204,7 @@ public class LoadRunner2 { stopLatch.await(); } catch (InterruptedException ex) { // ex.printStackTrace(); - System.out.println("InterruptedException"); + // System.out.println("InterruptedException"); } executor.shutdown(); @@ -213,27 +213,27 @@ public class LoadRunner2 { boolean result = executor.awaitTermination(1000, TimeUnit.MILLISECONDS); if (result) break; - System.out.println("[LoadRunner] shutdown() progressing ... await 1 seconds more"); + // System.out.println("[LoadRunner] shutdown() progressing ... await 1 seconds more"); } catch (InterruptedException e) { // e.printStackTrace(); - System.out.println("[LoadRunner] shutdown() progressing ...InterruptedException"); + // System.out.println("[LoadRunner] shutdown() progressing ...InterruptedException"); } } latch.await(); stopWatch.stop(); - System.out.println(); - System.out.println(); - System.out.println("==============================================================="); - System.out.println(" think time : " + thinkTime + " ms"); - System.out.println(" thread count : " + threadCount); - System.out.println(" loop count : " + loopCount); - System.out.println(" total request : " + (threadCount * loopCount)); - System.out.println(" elapsed : " + stopWatch.toString()); - System.out.println(" tps : " + new Integer(threadCount * loopCount * 1000).longValue() / stopWatch.getTime()); - System.out.println("==============================================================="); - System.out.println(); + // System.out.println(); + // System.out.println(); + // System.out.println("==============================================================="); + // System.out.println(" think time : " + thinkTime + " ms"); + // System.out.println(" thread count : " + threadCount); + // System.out.println(" loop count : " + loopCount); + // System.out.println(" total request : " + (threadCount * loopCount)); + // System.out.println(" elapsed : " + stopWatch.toString()); + // System.out.println(" tps : " + new Integer(threadCount * loopCount * 1000).longValue() / stopWatch.getTime()); + // System.out.println("==============================================================="); + // System.out.println(); } @@ -247,13 +247,13 @@ public class LoadRunner2 { break; } else if ("".equals(line.trim())) { } else if ("help".equals(line.trim())) { - System.out.println("==============================================================="); - System.out.println("LoadRunner v1.0 (http port = 8282)"); - System.out.println("==============================================================="); - System.out.println(" help : help"); - System.out.println(" start : start [thread count] [loop count] [think time]"); - System.out.println(" exit : exit"); - System.out.println(""); + // System.out.println("==============================================================="); + // System.out.println("LoadRunner v1.0 (http port = 8282)"); + // System.out.println("==============================================================="); + // System.out.println(" help : help"); + // System.out.println(" start : start [thread count] [loop count] [think time]"); + // System.out.println(" exit : exit"); + // System.out.println(""); } else if (line.trim().startsWith("start")) { String[] tokens = line.trim().split("[ ]+"); if (tokens.length > 1) @@ -266,11 +266,11 @@ public class LoadRunner2 { } else if ("exit".equals(line.trim())) { System.exit(1); } else { - System.out.println("Unknow command. type help."); + // System.out.println("Unknow command. type help."); } } catch(Exception e) { // e.printStackTrace(); - System.out.println("Exception"); + // System.out.println("Exception"); } } } @@ -293,14 +293,14 @@ public class LoadRunner2 { } } catch(Exception e) { - System.out.println(e.toString()); + // System.out.println(e.toString()); } finally { try { br.close(); } catch(Exception e) { - System.out.println(e.toString()); + // System.out.println(e.toString()); } } @@ -371,10 +371,10 @@ public class LoadRunner2 { if (args.length == 2) { hostname = args[0]; - System.out.println("remote host : " + hostname); + // System.out.println("remote host : " + hostname); filename = args[1]; } else { - System.out.println("Usage : loadrunner [ip] [file]"); + // System.out.println("Usage : loadrunner [ip] [file]"); return; } diff --git a/src/main/java/com/eactive/eai/adapter/socket2/common/ExpiringMap.java b/src/main/java/com/eactive/eai/adapter/socket2/common/ExpiringMap.java index f1cc512..f267d00 100644 --- a/src/main/java/com/eactive/eai/adapter/socket2/common/ExpiringMap.java +++ b/src/main/java/com/eactive/eai/adapter/socket2/common/ExpiringMap.java @@ -623,14 +623,14 @@ public class ExpiringMap implements Map { ExpiringMap m = new ExpiringMap(1); String key ="aaaaaaa"; m.put(key,key); - System.out.println(m.get(key)); + // System.out.println(m.get(key)); Thread.sleep(1 * 1000L); - System.out.println(m.get(key)); + // System.out.println(m.get(key)); Thread.sleep(1 * 1000L); - System.out.println(m.get(key)); + // System.out.println(m.get(key)); Thread.sleep(1 * 1000L); - System.out.println(m.get(key)); + // System.out.println(m.get(key)); Thread.sleep(1 * 1000L); - System.out.println(m.get(key)); + // System.out.println(m.get(key)); } } diff --git a/src/main/java/com/eactive/eai/adapter/socket2/protocol/admin/TelnetAdminHandler.java b/src/main/java/com/eactive/eai/adapter/socket2/protocol/admin/TelnetAdminHandler.java index 590feb2..7caba50 100644 --- a/src/main/java/com/eactive/eai/adapter/socket2/protocol/admin/TelnetAdminHandler.java +++ b/src/main/java/com/eactive/eai/adapter/socket2/protocol/admin/TelnetAdminHandler.java @@ -18,7 +18,7 @@ public class TelnetAdminHandler extends ProtocolHandler { @Override public void messageReceived(IoSession session, Object message) throws Exception { String msg = message.toString().trim(); - System.out.println(" " + msg); + // System.out.println(" " + msg); if ("quit".equals(msg) || "exit".equals(msg)) { session.write("bye......"); diff --git a/src/main/java/com/eactive/eai/adapter/socket2/protocol/http/Server.java b/src/main/java/com/eactive/eai/adapter/socket2/protocol/http/Server.java index d093d96..8720275 100644 --- a/src/main/java/com/eactive/eai/adapter/socket2/protocol/http/Server.java +++ b/src/main/java/com/eactive/eai/adapter/socket2/protocol/http/Server.java @@ -42,10 +42,10 @@ public class Server { acceptor .bind(new InetSocketAddress(port), new ServerHandler(), cfg); - System.out.println("Server now listening on port " + port); + // System.out.println("Server now listening on port " + port); } catch (Exception ex) { // ex.printStackTrace(); - System.out.println("Error" + ex.toString()); + // System.out.println("Error" + ex.toString()); } } } diff --git a/src/main/java/com/eactive/eai/adapter/socket2/protocol/http/codec/HttpResponse.java b/src/main/java/com/eactive/eai/adapter/socket2/protocol/http/codec/HttpResponse.java index 84362ed..b9e0ef6 100644 --- a/src/main/java/com/eactive/eai/adapter/socket2/protocol/http/codec/HttpResponse.java +++ b/src/main/java/com/eactive/eai/adapter/socket2/protocol/http/codec/HttpResponse.java @@ -61,7 +61,7 @@ public class HttpResponse { try { body.write(b); } catch (IOException ex) { - System.out.println("appendBody error"); + // System.out.println("appendBody error"); } } @@ -69,7 +69,7 @@ public class HttpResponse { try { body.write(s.getBytes()); } catch (IOException ex) { - System.out.println("appendBody string error"); + // System.out.println("appendBody string error"); } } diff --git a/src/main/java/com/eactive/eai/adapter/socket2/tool/admin/NetAdmin.java b/src/main/java/com/eactive/eai/adapter/socket2/tool/admin/NetAdmin.java index bcb0491..dffe926 100644 --- a/src/main/java/com/eactive/eai/adapter/socket2/tool/admin/NetAdmin.java +++ b/src/main/java/com/eactive/eai/adapter/socket2/tool/admin/NetAdmin.java @@ -10,8 +10,8 @@ public class NetAdmin { if (args.length == 1) { hostname = args[0]; } else if (args.length == 2) { - System.out.println("args[0] " + args[0]); - System.out.println("args[1] " + args[1]); + // System.out.println("args[0] " + args[0]); + // System.out.println("args[1] " + args[1]); hostname = args[0]; port = Integer.parseInt(args[1]); } @@ -32,6 +32,6 @@ public class NetAdmin { sb.append("set connection - Max Connection 수 조정 ( netadmin set connection adapterName #OfConnection )"); sb.append("set thread - Max Thread 수 조정 ( netadmin set thread adapterName #OfSession )"); sb.append("set trace - 소켓어뎁터 추적관리 레벨 조정 ( netadmin set trace adapterName [ 0 | 1 | 2] )\n"); - System.out.println(sb.toString()); + // System.out.println(sb.toString()); } } diff --git a/src/main/java/com/eactive/eai/adapter/socket2/tool/admin/Shell.java b/src/main/java/com/eactive/eai/adapter/socket2/tool/admin/Shell.java index 75b6b71..3e7fe11 100644 --- a/src/main/java/com/eactive/eai/adapter/socket2/tool/admin/Shell.java +++ b/src/main/java/com/eactive/eai/adapter/socket2/tool/admin/Shell.java @@ -64,7 +64,7 @@ public class Shell { public void loop() throws Exception { BufferedReader in = new BufferedReader(new InputStreamReader(System.in)); - System.out.println(welcomeMsg); + // System.out.println(welcomeMsg); do { // set prompt prompt = "\nnetadmin-" + hostname + ":" + port + "| " + context + "> "; @@ -74,7 +74,7 @@ public class Shell { try { if(line != null) process(line); } catch(Exception e) { - System.out.println("loop error "+ e.toString()); + // System.out.println("loop error "+ e.toString()); } } while(true); } @@ -87,9 +87,9 @@ public class Shell { SimpleFuture future = admin.stop(); future.join(); } catch(Exception e) { - System.out.println("stop error"); + // System.out.println("stop error"); } - System.out.println(byeMsg); + // System.out.println(byeMsg); System.exit(1); } @@ -103,6 +103,6 @@ public class Shell { context = res; } } - System.out.println(new String(response)); + // System.out.println(new String(response)); } } diff --git a/src/main/java/com/eactive/eai/adapter/wca/WCASessionThread.java b/src/main/java/com/eactive/eai/adapter/wca/WCASessionThread.java index 2536f9f..9bd65fe 100644 --- a/src/main/java/com/eactive/eai/adapter/wca/WCASessionThread.java +++ b/src/main/java/com/eactive/eai/adapter/wca/WCASessionThread.java @@ -393,7 +393,7 @@ public class WCASessionThread implements Runnable { myLog.logMsg(MyLog.WARN, "myLog Path : " + sMyLogPath); } catch(Exception ignore) { - System.out.println("WCASessionThread> Exception Msg = " + ignore.toString()); + // System.out.println("WCASessionThread> Exception Msg = " + ignore.toString()); } /* 20080523 End */ } @@ -739,7 +739,7 @@ public class WCASessionThread implements Runnable { } } catch (Exception ignore) { - System.out.println("WCASessionThread:run> Exception Msg = " + ignore.toString()); + // System.out.println("WCASessionThread:run> Exception Msg = " + ignore.toString()); } /* 20080523 SMS 로그 추가 끝 */ } diff --git a/src/main/java/com/eactive/eai/adapter/wca/data/WCAQueue.java b/src/main/java/com/eactive/eai/adapter/wca/data/WCAQueue.java index d4872b0..47fe9e6 100644 --- a/src/main/java/com/eactive/eai/adapter/wca/data/WCAQueue.java +++ b/src/main/java/com/eactive/eai/adapter/wca/data/WCAQueue.java @@ -382,7 +382,7 @@ public class WCAQueue { if (pBuff.length >= WCAHeader.WCA_HEADER_LEN + 3) System.arraycopy(pBuff, WCAHeader.WCA_HEADER_LEN, pDFSBuff, 0, pDFSBuff.length); - System.out.println("------> DFS : " + new String(pDFSBuff)); + // System.out.println("------> DFS : " + new String(pDFSBuff)); if((new String(pDFSBuff)).equals(new String(WCADefine.DFS_MSG))) bDFSFlag = true; else bDFSFlag = false; diff --git a/src/main/java/com/eactive/eai/adapter/wca/util/MyLog.java b/src/main/java/com/eactive/eai/adapter/wca/util/MyLog.java index 243b102..def9be8 100644 --- a/src/main/java/com/eactive/eai/adapter/wca/util/MyLog.java +++ b/src/main/java/com/eactive/eai/adapter/wca/util/MyLog.java @@ -544,7 +544,7 @@ public class MyLog { logMsg("LOG LEVLE = " + nLogLevel + ", LOG SIZE = " + MAX_LOG_FILE_SIZE + "M"); } catch (Exception e) { - System.out.println("openLogStream error -"+e.toString()); + // System.out.println("openLogStream error -"+e.toString()); } } @@ -559,7 +559,7 @@ public class MyLog { } } catch (Exception e) { - System.out.println("closeLogStream error -"+e.toString()); + // System.out.println("closeLogStream error -"+e.toString()); } } diff --git a/src/main/java/com/eactive/eai/authoutbound/client/impl/HttpClientAccessTokenServiceWithParam.java b/src/main/java/com/eactive/eai/authoutbound/client/impl/HttpClientAccessTokenServiceWithParam.java index c2a6dd1..5eb9f07 100644 --- a/src/main/java/com/eactive/eai/authoutbound/client/impl/HttpClientAccessTokenServiceWithParam.java +++ b/src/main/java/com/eactive/eai/authoutbound/client/impl/HttpClientAccessTokenServiceWithParam.java @@ -228,10 +228,10 @@ public class HttpClientAccessTokenServiceWithParam implements HttpClientAccessTo OAuth2AccessTokenVO accessToken = new OAuth2AccessTokenVO(); try (CloseableHttpResponse response = httpClient.execute(httpPost)) { if (response.getCode() != 200) { - System.out.println("OAuth token receive status fail value= "+ response.getCode()); + logger.info("OAuth token receive status fail value= " + response.getCode()); throw new Exception("OAuth token receive status fail value= " + response.getCode()); } - System.out.println("OAuth token receive status SUCCESS value= "+ response.getCode()); + logger.info("OAuth token receive status SUCCESS value= "+ response.getCode()); HttpEntity entity = response.getEntity(); String responseString = EntityUtils.toString(entity, encode); diff --git a/src/main/java/com/eactive/eai/common/circuitBreaker/PrometheusController.java b/src/main/java/com/eactive/eai/common/circuitBreaker/PrometheusController.java index 4364a38..4df265a 100644 --- a/src/main/java/com/eactive/eai/common/circuitBreaker/PrometheusController.java +++ b/src/main/java/com/eactive/eai/common/circuitBreaker/PrometheusController.java @@ -7,7 +7,7 @@ public class PrometheusController { public PrometheusController() { - System.out.println("init"); + // System.out.println("init"); } // @GetMapping("/prometheus") diff --git a/src/main/java/com/eactive/eai/common/logger/EAILogDAO.java b/src/main/java/com/eactive/eai/common/logger/EAILogDAO.java index e8509f1..55b386f 100644 --- a/src/main/java/com/eactive/eai/common/logger/EAILogDAO.java +++ b/src/main/java/com/eactive/eai/common/logger/EAILogDAO.java @@ -880,7 +880,7 @@ public class EAILogDAO { } originalAttribute = sb.toString(); - System.out.println("DB 암호화 #2 : {"+ originalAttribute +"} -> {"+attribute+"}"); + // System.out.println("DB 암호화 #2 : {"+ originalAttribute +"} -> {"+attribute+"}"); //logger.debug("DB 암호화 #2 : {} -> {}", originalAttribute, attribute); } } @@ -964,7 +964,7 @@ public class EAILogDAO { try { encryptedBytes1 = safedb.encrypt(userName, tableName, columnName1, byteMsg); - System.out.println("Encrypted Data : [" + new String(encryptedBytes1) + "]"); + // System.out.println("Encrypted Data : [" + new String(encryptedBytes1) + "]"); byte[] decryptedBytes1 = safedb.decrypt(userName, tableName, columnName1, encryptedBytes1); diff --git a/src/main/java/com/eactive/eai/common/state/ElinkStateManager.java b/src/main/java/com/eactive/eai/common/state/ElinkStateManager.java index 7f69873..31823bc 100644 --- a/src/main/java/com/eactive/eai/common/state/ElinkStateManager.java +++ b/src/main/java/com/eactive/eai/common/state/ElinkStateManager.java @@ -19,7 +19,7 @@ public class ElinkStateManager { if (logger != null) { logger.warn(message); } - System.out.println(DatetimeUtil.getCurrentTime() + " " + LOG_PREFIX + message); + // System.out.println(DatetimeUtil.getCurrentTime() + " " + LOG_PREFIX + message); } public static synchronized ElinkStateManager getInstance() { diff --git a/src/main/java/com/eactive/eai/env/SystemPropConfig.java b/src/main/java/com/eactive/eai/env/SystemPropConfig.java index 48eb84a..4c7cf0c 100644 --- a/src/main/java/com/eactive/eai/env/SystemPropConfig.java +++ b/src/main/java/com/eactive/eai/env/SystemPropConfig.java @@ -25,14 +25,14 @@ public class SystemPropConfig implements ServletContextAware { @PostConstruct public void loadlPropertiesToSystemProp() { - System.out.println("loadPropertiesToSystemProp: "+SYSTEM_PROP_FILE_PATH); + // System.out.println("loadPropertiesToSystemProp: "+SYSTEM_PROP_FILE_PATH); Properties sysProp = new Properties(); try(InputStream is = servletContext.getResourceAsStream(SYSTEM_PROP_FILE_PATH)){ sysProp.load(is); sysProp.forEach((key, value) -> { if (StringUtils.isBlank(System.getProperty((String) key))) { System.setProperty((String) key, (String) value); - System.out.println("Set system prop: "+key+"="+value); + // System.out.println("Set system prop: "+key+"="+value); } }); } catch (Throwable th) { diff --git a/src/main/java/com/eactive/eai/flowcontroller/C2RFCProcess.java b/src/main/java/com/eactive/eai/flowcontroller/C2RFCProcess.java index 7808b59..76ed592 100644 --- a/src/main/java/com/eactive/eai/flowcontroller/C2RFCProcess.java +++ b/src/main/java/com/eactive/eai/flowcontroller/C2RFCProcess.java @@ -358,7 +358,7 @@ public class C2RFCProcess extends Process { if (this.callProp != null) { String mode = this.callProp.getProperty(EAIKeys.CALL_MODE_KEY); if (mode != null && EAIKeys.CALL_MODE_WARMUP.equals(mode)) { - System.out.println(guidLogPrefix + " Warming Up Called"); + // System.out.println(guidLogPrefix + " Warming Up Called"); return false; } else { return true; diff --git a/src/main/java/com/eactive/eai/inbound/processor/RequestProcessor.java b/src/main/java/com/eactive/eai/inbound/processor/RequestProcessor.java index 25d4c1d..b3f43c8 100644 --- a/src/main/java/com/eactive/eai/inbound/processor/RequestProcessor.java +++ b/src/main/java/com/eactive/eai/inbound/processor/RequestProcessor.java @@ -346,7 +346,7 @@ public class RequestProcessor extends RequestProcessorSupport { // 3. EAIMessage Object 생성 //String eaiSvcCd = mapper.getEaiSvcCode(standardMessage); // commnet by jwhong String eaiSvcCd = prop.getProperty("API_SERVICE_CODE"); - System.out.println("***** eaiSvcCd is"+ eaiSvcCd); + logger.info("eaiSvcCd = "+eaiSvcCd); if (StringUtils.isEmpty(eaiSvcCd)) eaiSvcCd = mapper.getEaiSvcCode(standardMessage); // HTT 어댑터로 들어오는거래는 Prop에 서비스코드가 없음. String guid = mapper.getGuid(standardMessage); String guidSeq = mapper.getGuidSeq(standardMessage); diff --git a/src/main/java/com/eactive/eai/message/StandardMessageUtil.java b/src/main/java/com/eactive/eai/message/StandardMessageUtil.java index ea503a3..996b58a 100644 --- a/src/main/java/com/eactive/eai/message/StandardMessageUtil.java +++ b/src/main/java/com/eactive/eai/message/StandardMessageUtil.java @@ -363,13 +363,13 @@ public class StandardMessageUtil { StandardMessage stdmsg = generateMessageFromCsvFile(filePath); - System.out.println("==========================================================================="); - System.out.println(stdmsg.getChilds().size()); - System.out.println(stdmsg); - System.out.println("==========================================================================="); - System.out.println(stdmsg.getLlDataPath()); - System.out.println(stdmsg.getBizDataPath()); - System.out.println(stdmsg.getZzDataPath()); - System.out.println("==========================================================================="); + // System.out.println("==========================================================================="); + // System.out.println(stdmsg.getChilds().size()); + // System.out.println(stdmsg); + // System.out.println("==========================================================================="); + // System.out.println(stdmsg.getLlDataPath()); + // System.out.println(stdmsg.getBizDataPath()); + // System.out.println(stdmsg.getZzDataPath()); + // System.out.println("==========================================================================="); } } diff --git a/src/main/java/com/eactive/eai/util/ByteCharSequence.java b/src/main/java/com/eactive/eai/util/ByteCharSequence.java index da287a1..b5e2a05 100644 --- a/src/main/java/com/eactive/eai/util/ByteCharSequence.java +++ b/src/main/java/com/eactive/eai/util/ByteCharSequence.java @@ -52,6 +52,6 @@ public class ByteCharSequence implements CharSequence{ if (m.find()){ index = m.start(); } - System.out.println("index = " + index); + // System.out.println("index = " + index); } } diff --git a/src/main/java/com/eactive/eai/util/CryptoUtil.java b/src/main/java/com/eactive/eai/util/CryptoUtil.java index d7849f1..8e331c0 100644 --- a/src/main/java/com/eactive/eai/util/CryptoUtil.java +++ b/src/main/java/com/eactive/eai/util/CryptoUtil.java @@ -51,20 +51,20 @@ public class CryptoUtil { String key = "ONAuROzlqWB4VuBwO5C/FA=="; String text = "Hello AES 한글"; - System.out.println("Original Text: " + text); + // System.out.println("Original Text: " + text); long startEncryptTime = System.nanoTime(); String enc = encryptAES(key, text); long endEncryptTime = System.nanoTime(); long encryptDuration = endEncryptTime - startEncryptTime; - System.out.println("Encrypted Text: " + enc); - System.out.println("Encryption took: " + encryptDuration + " nanoseconds"); + // System.out.println("Encrypted Text: " + enc); + // System.out.println("Encryption took: " + encryptDuration + " nanoseconds"); long startDecryptTime = System.nanoTime(); String dec = decryptAES(key, enc); long endDecryptTime = System.nanoTime(); long decryptDuration = endDecryptTime - startDecryptTime; - System.out.println("Decrypted Text: " + dec); - System.out.println("Decryption took: " + decryptDuration + " nanoseconds"); + // System.out.println("Decrypted Text: " + dec); + // System.out.println("Decryption took: " + decryptDuration + " nanoseconds"); } } \ No newline at end of file diff --git a/src/main/java/com/eactive/eai/util/IpUtil.java b/src/main/java/com/eactive/eai/util/IpUtil.java index 93c4e5a..a02fbf9 100644 --- a/src/main/java/com/eactive/eai/util/IpUtil.java +++ b/src/main/java/com/eactive/eai/util/IpUtil.java @@ -38,9 +38,9 @@ public class IpUtil { String matchdIps = "192.168.0.1,192.168.0.0/24,192.168.1.*"; String requestIp = "192.168.1.2"; if (IpUtil.isMatchIp(matchdIps, requestIp)) { - System.out.println(true); + // System.out.println(true); } else { - System.out.println(false); + // System.out.println(false); } } diff --git a/src/main/java/com/eactive/eai/util/JsonBeatiUtil.java b/src/main/java/com/eactive/eai/util/JsonBeatiUtil.java index 1066703..8322d15 100644 --- a/src/main/java/com/eactive/eai/util/JsonBeatiUtil.java +++ b/src/main/java/com/eactive/eai/util/JsonBeatiUtil.java @@ -135,7 +135,7 @@ public class JsonBeatiUtil { data += "} "; data = "{\"EAI_UJSON2DEPTHEXT_REQ1\":{\"abc\":\"cba \",\"grid1\":[{\"long1\":1,\"data2\":\" \",\"grid2\":[{\"data3\":\"12345\",\"big4\":\"14.00000\"},{\"data3\":\"13 \",\"big4\":\"14.00001\"}]},{\"long1\":10000,\"data2\":\" \",\"grid2\":[{\"data3\":\"23 \",\"big4\":\"24.00000\"}]},{\"long1\":1000000000,\"data2\":\" \",\"grid2\":[{\"data3\":\"33 \",\"big4\":\"0.00000\"},{\"data3\":\" \",\"big4\":\"0.00034\"},{\"data3\":\"35 \",\"big4\":\"0.00036\"}]}],\"abcd\":\"123\",\"grid3\":[{\"long1\":1,\"data2\":\" \",\"grid4\":[{\"data5\":\"00023\",\"big6\":\"24\"}]},{\"long1\":1000000000,\"data2\":\" \",\"grid4\":[{\"data5\":\"00033\",\"big6\":\"0\"},{\"data5\":\" \",\"big6\":\"34\"},{\"data5\":\"00035\",\"big6\":\"900000003600011\"}]}]}}"; - System.out.println(JsonBeatiUtil.SimpleBeautiful(data)); + // System.out.println(JsonBeatiUtil.SimpleBeautiful(data)); } } diff --git a/src/main/java/com/eactive/eai/util/JsonPathUtil.java b/src/main/java/com/eactive/eai/util/JsonPathUtil.java index 0f3e9b9..845d7af 100644 --- a/src/main/java/com/eactive/eai/util/JsonPathUtil.java +++ b/src/main/java/com/eactive/eai/util/JsonPathUtil.java @@ -104,22 +104,22 @@ public class JsonPathUtil { public static void main(String[] args) { String jsonString = "{ \"person\": { \"name\": \"John\", \"age\": 30, \"groups\": [ { \"id\": 1, \"name\": \"Group A\" }, { \"id\": 2, \"name\": \"Group B\" }, { \"id\": 3, \"name\": \"Group C\" } ] } }"; - System.out.println("Source JSON: \n" + jsonString); + // System.out.println("Source JSON: \n" + jsonString); // 경로를 사용하여 값 가져오기 (반복되는 그룹 포함) String getPath = "/person/groups/1/name"; String secondGroupName = getValueAtPath(jsonString, getPath); - System.out.println("getPath: " + getPath + " -> " + secondGroupName); + // System.out.println("getPath: " + getPath + " -> " + secondGroupName); // 경로를 사용하여 값 설정하기 (반복되는 그룹 포함) 및 Pretty 출력 String putPath = "/person/groups/2/name"; String updatedJsonString = setValueAtPath(jsonString, putPath, "Group Z", true); - System.out.println("putPath: " + putPath); - System.out.println("Updated JSON (Pretty): \n" + updatedJsonString); + // System.out.println("putPath: " + putPath); + // System.out.println("Updated JSON (Pretty): \n" + updatedJsonString); getPath = "/person/name"; - System.out.println("getPath: " + getPath + " -> " + getValueAtPath(jsonString, getPath)); + // System.out.println("getPath: " + getPath + " -> " + getValueAtPath(jsonString, getPath)); getPath = "/person/age"; - System.out.println("getPath: " + getPath + " -> " + getValueAtPath(jsonString, getPath)); + // System.out.println("getPath: " + getPath + " -> " + getValueAtPath(jsonString, getPath)); } } diff --git a/src/main/java/com/eactive/eai/util/json/JsonPathsTransform.java b/src/main/java/com/eactive/eai/util/json/JsonPathsTransform.java index dca2a3d..ca0600e 100644 --- a/src/main/java/com/eactive/eai/util/json/JsonPathsTransform.java +++ b/src/main/java/com/eactive/eai/util/json/JsonPathsTransform.java @@ -47,7 +47,7 @@ public class JsonPathsTransform { String encLog = transformer.getClass().getName() + " : " + String.format("path=%s, orgText[%s] plain[%s] newText[%s]", path, currentValue, transformer.getProperty("PLAIN_VALUE"), newValue); - System.out.println(encLog); + // System.out.println(encLog); logger.debug(encLog); } } catch (Exception e) { diff --git a/src/main/java/com/eactive/eai/util/json/JsonSimplePathsTransform.java b/src/main/java/com/eactive/eai/util/json/JsonSimplePathsTransform.java index 5e16ed9..2af3b2b 100644 --- a/src/main/java/com/eactive/eai/util/json/JsonSimplePathsTransform.java +++ b/src/main/java/com/eactive/eai/util/json/JsonSimplePathsTransform.java @@ -30,7 +30,7 @@ public class JsonSimplePathsTransform { if(logger.isDebug()) { // FIXME : kbank - 로그내용 수정 String encLog = transformer.getClass().getName() +" : "+ String.format("path=%s, orgText[%s] plain[%s] newText[%s]", path, currentValue, transformer.getProperty("PLAIN_VALUE"), newValue); - System.out.println(encLog); + // System.out.println(encLog); logger.debug(encLog); } setNodeValue(getParentNode(rootNode, getParentPath(path)), getFieldName(path), newValue); diff --git a/src/main/java/com/kbstar/eai/common/header/SHINBOHeaderAction.java b/src/main/java/com/kbstar/eai/common/header/SHINBOHeaderAction.java index 3b248db..dee555f 100644 --- a/src/main/java/com/kbstar/eai/common/header/SHINBOHeaderAction.java +++ b/src/main/java/com/kbstar/eai/common/header/SHINBOHeaderAction.java @@ -171,7 +171,7 @@ public class SHINBOHeaderAction extends HeaderActionSupport SHINBOHeaderAction sha = new SHINBOHeaderAction(); byte[] res = sha.addHeaderAD(orgData, message); - System.out.println("res]" +new String(res)); + // System.out.println("res]" +new String(res)); } */ } diff --git a/src/main/java/com/kbstar/eai/common/loader/EAILogFIleLoader.java b/src/main/java/com/kbstar/eai/common/loader/EAILogFIleLoader.java index c0a2b9f..d65885c 100644 --- a/src/main/java/com/kbstar/eai/common/loader/EAILogFIleLoader.java +++ b/src/main/java/com/kbstar/eai/common/loader/EAILogFIleLoader.java @@ -202,7 +202,7 @@ public class EAILogFIleLoader { in = new FileInputStream(configPath); p.load(in); } catch (Exception e){ - System.out.println("환경설정 파일이 없습니다. - 파일명 : " + configPath); + // System.out.println("환경설정 파일이 없습니다. - 파일명 : " + configPath); throw e; } finally{ @@ -211,7 +211,7 @@ public class EAILogFIleLoader { in.close(); } catch(Exception e) { - System.out.println("close error"); + // System.out.println("close error"); } } } @@ -225,16 +225,16 @@ public class EAILogFIleLoader { // String iniKey = p.getProperty("ini.key"); String encpval = p.getProperty("jdbc.pvalue"); - System.out.println("========================================================="); - System.out.println(" EAILogFileLoader Configuration - "+ new Date()); - System.out.println("========================================================="); + // System.out.println("========================================================="); + // System.out.println(" EAILogFileLoader Configuration - "+ new Date()); + // System.out.println("========================================================="); // System.out.println("driver = " + driver); // System.out.println("url = " + url); // System.out.println("ivalue = " + ival); // System.out.println("pvalue = " + encpval); // System.out.println("Table Owner = " + tableOwner); // System.out.println("iniFilePath = " + iniFilePath); - System.out.println("========================================================="); + // System.out.println("========================================================="); // ScpDbAgent agt = new ScpDbAgent(); // try { @@ -256,7 +256,7 @@ public class EAILogFIleLoader { try { date = new SimpleDateFormat("yyyyMMdd").parse(timeStr); // "yyyyMMddHHmmssSSS" } catch (ParseException e) { - System.out.println("getDayOfWeekNum error - "+timeStr); + // System.out.println("getDayOfWeekNum error - "+timeStr); // e.printStackTrace(); } long time = date.getTime(); @@ -281,7 +281,7 @@ public class EAILogFIleLoader { String[] info = null; try { - System.out.println(">> Log Date : " + cDay + ", rows=" + list.size()); + // System.out.println(">> Log Date : " + cDay + ", rows=" + list.size()); if( driver != null ) { Class.forName(driver); @@ -601,7 +601,7 @@ public class EAILogFIleLoader { // conn.commit(); } catch(Exception ex) { - System.out.println("ERROR SKIP INSERT - row : "+ position +", Error : " + ex.toString()); + // System.out.println("ERROR SKIP INSERT - row : "+ position +", Error : " + ex.toString()); // ex.printStackTrace(); if(!isForce) throw ex; } @@ -611,17 +611,17 @@ public class EAILogFIleLoader { catch(SQLException se) { // if(conn != null) conn.rollback(); if(info!=null) { - System.out.println("ERROR : DB 오류 - " + info.toString()); + // System.out.println("ERROR : DB 오류 - " + info.toString()); } else { - System.out.println("ERROR : DB 오류 - " + se.toString()); + // System.out.println("ERROR : DB 오류 - " + se.toString()); } // se.printStackTrace(); throw se; } catch(Exception e) { // if(conn != null) conn.rollback(); - System.out.println(e.toString()); + // System.out.println(e.toString()); // e.printStackTrace(); throw e; } @@ -630,13 +630,13 @@ public class EAILogFIleLoader { if(preparedStatement != null) preparedStatement.close(); } catch (SQLException sqle) { - System.out.println("SQLException was thrown: " + sqle.toString()); + // System.out.println("SQLException was thrown: " + sqle.toString()); } try { if(conn != null) conn.close(); } catch (SQLException sqle) { - System.out.println("SQLException was thrown: " + sqle.toString()); + // System.out.println("SQLException was thrown: " + sqle.toString()); } } } @@ -666,14 +666,14 @@ public class EAILogFIleLoader { } while (!"".equals(subMsgStr) && seq < 99); // TSEAILG02.BzwkDataSerno : NUMBER(2) } catch(Exception e) { - System.out.println("DB Logging[SLAVE] Failed - " + info[0] + "|" + info[1] + "|" + info[2] +"|seq="+seq); + // System.out.println("DB Logging[SLAVE] Failed - " + info[0] + "|" + info[1] + "|" + info[2] +"|seq="+seq); throw e; } finally { if(preparedStatement != null) { try { preparedStatement.close(); } catch (SQLException e) { - System.out.println("SQLException was thrown: " + e.toString()); + // System.out.println("SQLException was thrown: " + e.toString()); } } } @@ -729,21 +729,21 @@ public class EAILogFIleLoader { } } catch(Exception e) { - System.out.println(e.toString()); + // System.out.println(e.toString()); } finally { try { if(br != null) br.close(); } catch(Exception e) { - System.out.println(e.toString()); + // System.out.println(e.toString()); } } if(count > 0) { loadLog(cDay, list, true); } - System.out.println(String.format("## FILE=%s, INSERT ROW COUNTS : (%d/%d)", filePath, insertCount, totalCount)); + // System.out.println(String.format("## FILE=%s, INSERT ROW COUNTS : (%d/%d)", filePath, insertCount, totalCount)); } private String[] split(String data, String deli) { @@ -786,7 +786,7 @@ public class EAILogFIleLoader { String filePath = "C:\\trlog\\tran.log"; //args[1]; try { if(isReal && args.length < 2) { - System.out.println(getUsage()); + // System.out.println(getUsage()); System.exit(-1); } @@ -795,13 +795,13 @@ public class EAILogFIleLoader { filePath = args[1]; } - System.out.println("\n## START LOADING Infomation - " + configPath); + // System.out.println("\n## START LOADING Infomation - " + configPath); loader = new EAILogFIleLoader(); loader.init(configPath); loader.parse(filePath); } catch (Exception e) { - System.out.println("ERROR MAIN"); - System.out.println(e.toString()); + // System.out.println("ERROR MAIN"); + // System.out.println(e.toString()); System.exit(-2); } System.exit(0); From b6c2fde29b9bed7d2a9a8ac44c21595d4e1463f4 Mon Sep 17 00:00:00 2001 From: cho Date: Thu, 5 Mar 2026 11:52:11 +0900 Subject: [PATCH 156/159] =?UTF-8?q?=EB=A1=9C=EA=B7=B8=EB=A0=88=EB=B2=A8=20?= =?UTF-8?q?=EB=8F=99=EC=A0=81=EC=9C=BC=EB=A1=9C=20=EB=B3=80=EA=B2=BD?= =?UTF-8?q?=EB=90=98=EB=8F=84=EB=A1=9D....................................?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/eactive/eai/agent/property/ReloadPropertyCommand.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/main/java/com/eactive/eai/agent/property/ReloadPropertyCommand.java b/src/main/java/com/eactive/eai/agent/property/ReloadPropertyCommand.java index 23ae3f1..e4837e0 100644 --- a/src/main/java/com/eactive/eai/agent/property/ReloadPropertyCommand.java +++ b/src/main/java/com/eactive/eai/agent/property/ReloadPropertyCommand.java @@ -41,6 +41,10 @@ public class ReloadPropertyCommand extends Command { if (logger.isWarn()) logger.warn(this.name + "] " + keyName + " Reload."); } + + if (keyName.startsWith("FileLogger{")) { + com.eactive.eai.common.util.Logger.setLoggerLevel(keyName); + } } } catch (Exception e) { String rspErrorCode = "RECEAIMCM002"; From 7ac995e5efef7051ca7f29e2321525894b312fc0 Mon Sep 17 00:00:00 2001 From: cho Date: Thu, 5 Mar 2026 14:29:09 +0900 Subject: [PATCH 157/159] =?UTF-8?q?Revert=20"HttpClientConnectionManager?= =?UTF-8?q?=EC=97=90=EC=84=9C=20SSLContext=20=EC=83=9D=EC=84=B1=EC=8B=9C,?= =?UTF-8?q?=20entropy"?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This reverts commit 640f1e4f1e1b6751826923ebcf4481ce258ceecc. --- .../eai/custom/alarm/ums/UmsService.java | 41 ++++++++++++++++--- 1 file changed, 36 insertions(+), 5 deletions(-) diff --git a/src/main/java/com/eactive/eai/custom/alarm/ums/UmsService.java b/src/main/java/com/eactive/eai/custom/alarm/ums/UmsService.java index cc2b114..74777de 100644 --- a/src/main/java/com/eactive/eai/custom/alarm/ums/UmsService.java +++ b/src/main/java/com/eactive/eai/custom/alarm/ums/UmsService.java @@ -1,15 +1,20 @@ package com.eactive.eai.custom.alarm.ums; +import java.io.IOException; import java.nio.charset.StandardCharsets; +import javax.annotation.PreDestroy; + import org.apache.hc.client5.http.classic.methods.HttpPost; import org.apache.hc.client5.http.config.RequestConfig; import org.apache.hc.client5.http.entity.EntityBuilder; import org.apache.hc.client5.http.impl.classic.CloseableHttpClient; import org.apache.hc.client5.http.impl.classic.HttpClients; +import org.apache.hc.client5.http.impl.io.PoolingHttpClientConnectionManagerBuilder; +import org.apache.hc.client5.http.io.HttpClientConnectionManager; import org.apache.hc.core5.http.ContentType; -import org.apache.hc.core5.http.HttpVersion; import org.apache.hc.core5.http.io.entity.EntityUtils; +import org.apache.hc.core5.util.TimeValue; import org.apache.hc.core5.util.Timeout; import org.springframework.stereotype.Component; @@ -38,6 +43,24 @@ public class UmsService { private final static String DEFAULT_API_KEY = "7cca6d58-e4f7-474d-9edd-525806bc99ff"; private final static String AUTHORIZATION_FMT = "Bearer %s"; + // 재사용되는 HttpClient (Thread-Safe) + private final CloseableHttpClient httpClient; + + public UmsService() { + // 커넥션 풀 설정: 매번 소켓을 열고 닫지 않고 재사용함 + HttpClientConnectionManager cm = PoolingHttpClientConnectionManagerBuilder.create() + .setMaxConnTotal(100) // 전체 최대 커넥션 수 + .setMaxConnPerRoute(20) // 호스트당 최대 커넥션 수 + .setConnectionTimeToLive(TimeValue.ofMinutes(3)) // TTL + .setValidateAfterInactivity(TimeValue.ofSeconds(5)) // 🔥 중요 + .build(); + + this.httpClient = HttpClients.custom() + .setConnectionManager(cm) + .evictExpiredConnections() // 만료 제거 + .evictIdleConnections(TimeValue.ofSeconds(20)) // 20초 idle 제거 + .build(); + } public UmsCallResult send(UmsRequestPayload payload) throws Exception { if (payload.getContent() == null) { @@ -72,9 +95,6 @@ public class UmsService { .setContentType(ContentType.APPLICATION_JSON) .setContentEncoding("UTF-8") .build()); - - httpPost.setVersion(HttpVersion.HTTP_1_0); - httpPost.setHeader("Connection", "close"); // 3. 타임아웃 설정 (설정파일 값 적용) RequestConfig config = RequestConfig.custom() @@ -89,7 +109,7 @@ public class UmsService { } // 4. 실행 (HttpClient 재사용) - try (CloseableHttpClient httpClient = HttpClients.createDefault()) { + try { return httpClient.execute(httpPost, response -> { String body = EntityUtils.toString(response.getEntity(), StandardCharsets.UTF_8); @@ -120,4 +140,15 @@ public class UmsService { } } + @PreDestroy + public void destroy() { + try { + if (httpClient != null) { + httpClient.close(); + logger.info("UMS HttpClient closed."); + } + } catch (IOException e) { + logger.error("Error closing UMS HttpClient", e); + } + } } \ No newline at end of file From 4f5fa96ef521b16be24d567b7d987d8944877d16 Mon Sep 17 00:00:00 2001 From: cho Date: Thu, 5 Mar 2026 14:48:37 +0900 Subject: [PATCH 158/159] =?UTF-8?q?=EB=82=9C=EC=88=98=20=EC=83=9D=EC=84=B1?= =?UTF-8?q?=20=EB=AC=B8=EC=A0=9C=EB=A1=9C=20=ED=92=80=EB=A7=81=20=EC=A0=9C?= =?UTF-8?q?=EA=B1=B0=20=EC=9B=90=EB=B3=B5=20=EB=B0=8F=20=ED=81=90=20?= =?UTF-8?q?=EC=82=AC=EC=9A=A9=20=EB=B9=84=EB=8F=99=EA=B8=B0=EC=B2=98?= =?UTF-8?q?=EB=A6=AC.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../eai/custom/alarm/AlarmStateManager.java | 179 +++++++++--------- .../eai/custom/alarm/ums/UmsSendManager.java | 87 +++++---- 2 files changed, 140 insertions(+), 126 deletions(-) diff --git a/src/main/java/com/eactive/eai/custom/alarm/AlarmStateManager.java b/src/main/java/com/eactive/eai/custom/alarm/AlarmStateManager.java index 83e4e14..f03ae3b 100644 --- a/src/main/java/com/eactive/eai/custom/alarm/AlarmStateManager.java +++ b/src/main/java/com/eactive/eai/custom/alarm/AlarmStateManager.java @@ -18,6 +18,7 @@ import com.eactive.eai.custom.alarm.event.AlarmEvent; import com.eactive.eai.custom.alarm.key.AlarmKey; import com.eactive.eai.custom.alarm.policy.AlarmPolicy; import com.eactive.eai.custom.alarm.policy.SendPolicy; +import com.eactive.eai.custom.alarm.ums.UmsSendManager; import com.eactive.eai.custom.alarm.ums.UmsService; import com.eactive.eai.custom.alarm.ums.payload.ObpMonitoringUmsTemplate; import com.eactive.eai.custom.alarm.ums.payload.UmsRequestPayload; @@ -25,121 +26,121 @@ import com.eactive.eai.custom.alarm.ums.payload.UmsRequestPayload; @Component public class AlarmStateManager { - List registerAlarmList = new ArrayList(); + List registerAlarmList = new ArrayList(); - private final ScheduledExecutorService scheduler; + private final ScheduledExecutorService scheduler; - protected static Logger logger = Logger.getLogger(Logger.LOGGER_DEFAULT); + protected static Logger logger = Logger.getLogger(Logger.LOGGER_DEFAULT); - private static AlarmStateManager alarmStateManager; + private static AlarmStateManager alarmStateManager; - @Autowired - AlarmService alarmService; + @Autowired + AlarmService alarmService; - @Autowired - UmsService usmService; + @Autowired + UmsSendManager umsSendManager; - public static AlarmStateManager getAlarmStateManager() { - if (alarmStateManager == null) { - alarmStateManager = ApplicationContextProvider.getContext().getBean(AlarmStateManager.class); - } - return alarmStateManager; - } - - public AlarmStateManager() { - - this.scheduler = Executors.newSingleThreadScheduledExecutor(r -> { - Thread t = new Thread(r); - t.setName("AlarmStateManager-worker"); - t.setDaemon(false); - return t; - }); - - scheduler.scheduleWithFixedDelay(() -> { - - try { - // === 여기에 지속 실행할 로직 === - fireAlarm(); - - } catch (Throwable e) { - // 반드시 예외 잡기 (안 잡으면 스케줄 자체가 죽음) - logger.error("fireAlarm fail", e); - } - - }, 0, 5, TimeUnit.SECONDS); // 최초 0초, 이후 5초 간격 - } - - public void onEvnet(AlarmEvent alaramEvent) { - - Optional existEvent = registerAlarmList.stream().filter(e -> e.equals(alaramEvent)).findFirst(); - - if (existEvent.isPresent()) { - AlarmEvent event = existEvent.get(); - event.onOcurr(); - } else { - registerAlarmList.add(alaramEvent); + public static AlarmStateManager getAlarmStateManager() { + if (alarmStateManager == null) { + alarmStateManager = ApplicationContextProvider.getContext().getBean(AlarmStateManager.class); + } + return alarmStateManager; } - } + public AlarmStateManager() { - private void fireAlarm() { + this.scheduler = Executors.newSingleThreadScheduledExecutor(r -> { + Thread t = new Thread(r); + t.setName("AlarmStateManager-worker"); + t.setDaemon(false); + return t; + }); - Map alarmPolicyMap = alarmService.getAlarmPolicy(); + scheduler.scheduleWithFixedDelay(() -> { - Map sendPolicyMap = alarmService.getSendPolicy(); + try { + // === 여기에 지속 실행할 로직 === + fireAlarm(); - Iterator iterator = registerAlarmList.iterator(); + } catch (Throwable e) { + // 반드시 예외 잡기 (안 잡으면 스케줄 자체가 죽음) + logger.error("fireAlarm fail", e); + } - while (iterator.hasNext()) { - AlarmEvent event = iterator.next(); - AlarmPolicy alarmPolicy = alarmPolicyMap.get(event.getKey()); + }, 0, 5, TimeUnit.SECONDS); // 최초 0초, 이후 5초 간격 + } - if (alarmPolicy != null && alarmPolicy.isAlarmTriggered(event)) { - // 알람 발송 로직 - SendPolicy sendPolicy = sendPolicyMap.get(event.getKey()); - if (alarmService.isAlarmEnabled()) { - send(sendPolicy, event); + public void onEvnet(AlarmEvent alaramEvent) { + + Optional existEvent = registerAlarmList.stream().filter(e -> e.equals(alaramEvent)).findFirst(); + + if (existEvent.isPresent()) { + AlarmEvent event = existEvent.get(); + event.onOcurr(); } else { - logger.info("Alarm is disabled, event = {}, policy = {}", event, sendPolicy); + registerAlarmList.add(alaramEvent); } - // 리스트에서 안전하게 제거 - iterator.remove(); - }else { //트리거 조건이 안되더라도, 이벤트발생한지 오래 되었으면 제거하여 OOM 예방. - - - long firstOcurredAt = event.getCondition().getOcurredAt(); - - long diffInMs = System.currentTimeMillis() - firstOcurredAt; - - if ( diffInMs >= TimeUnit.MINUTES.toMillis(60) ) { //1시간 지난거면 삭제 - iterator.remove(); - } - } + } - } + private void fireAlarm() { - private void send(SendPolicy sendPolicy, AlarmEvent event) { + Map alarmPolicyMap = alarmService.getAlarmPolicy(); - UmsRequestPayload payload = null; + Map sendPolicyMap = alarmService.getSendPolicy(); - try { + Iterator iterator = registerAlarmList.iterator(); - List cellPhoneList = sendPolicy.getCellPhoneList(); + while (iterator.hasNext()) { + AlarmEvent event = iterator.next(); + AlarmPolicy alarmPolicy = alarmPolicyMap.get(event.getKey()); - for (String cellPhone : cellPhoneList) { + if (alarmPolicy != null && alarmPolicy.isAlarmTriggered(event)) { + // 알람 발송 로직 + SendPolicy sendPolicy = sendPolicyMap.get(event.getKey()); + if (alarmService.isAlarmEnabled()) { + send(sendPolicy, event); + } else { + logger.info("Alarm is disabled, event = {}, policy = {}", event, sendPolicy); + } + // 리스트에서 안전하게 제거 + iterator.remove(); + } else { // 트리거 조건이 안되더라도, 이벤트발생한지 오래 되었으면 제거하여 OOM 예방. - payload = UmsRequestPayload.builder() - .content(ObpMonitoringUmsTemplate.builder().message(event.getMessage()).build()) - .cellphone(cellPhone).build(); - logger.info("Alarm is disabled, UmsRequestPayload = {}", payload); - usmService.send(payload); - } + long firstOcurredAt = event.getCondition().getOcurredAt(); - } catch (Exception e) { - logger.error(String.format("Alarm message delivery failed (UMS), payload=%s", payload), e); + long diffInMs = System.currentTimeMillis() - firstOcurredAt; + + if (diffInMs >= TimeUnit.MINUTES.toMillis(60)) { // 1시간 지난거면 삭제 + iterator.remove(); + } + } + } } - } + + private void send(SendPolicy sendPolicy, AlarmEvent event) { + + UmsRequestPayload payload = null; + + try { + + List cellPhoneList = sendPolicy.getCellPhoneList(); + + for (String cellPhone : cellPhoneList) { + + payload = UmsRequestPayload.builder() + .content(ObpMonitoringUmsTemplate.builder().message(event.getMessage()).build()) + .cellphone(cellPhone).build(); + logger.info("Alarm is disabled, UmsRequestPayload = {}", payload); + + umsSendManager.enqueue(payload); + } + + } catch (Exception e) { + logger.error(String.format("Alarm message delivery failed (UMS), payload=%s", payload), e); + + } + } } \ No newline at end of file diff --git a/src/main/java/com/eactive/eai/custom/alarm/ums/UmsSendManager.java b/src/main/java/com/eactive/eai/custom/alarm/ums/UmsSendManager.java index 396705f..8e9c5d5 100644 --- a/src/main/java/com/eactive/eai/custom/alarm/ums/UmsSendManager.java +++ b/src/main/java/com/eactive/eai/custom/alarm/ums/UmsSendManager.java @@ -3,10 +3,13 @@ package com.eactive.eai.custom.alarm.ums; import java.util.Queue; import java.util.concurrent.CompletableFuture; import java.util.concurrent.ConcurrentLinkedQueue; +import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.TimeUnit; +import javax.annotation.PreDestroy; + import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; @@ -15,59 +18,69 @@ import com.eactive.eai.custom.alarm.ums.payload.UmsRequestPayload; @Component public class UmsSendManager { - + + protected static Logger logger = Logger.getLogger(Logger.LOGGER_DEFAULT); + // 1. I/O 처리를 위한 전용 스레드 풀 (예: 최대 10개 스레드) + private final ExecutorService ioExecutor = Executors.newFixedThreadPool(10); private final ScheduledExecutorService scheduler; - - protected static Logger logger = Logger.getLogger(Logger.LOGGER_DEFAULT); - Queue queue = new ConcurrentLinkedQueue(); - + // 2. 메모리 보호를 위해 크기 제한이 있는 큐 권장 (선택사항) + private final Queue queue = new ConcurrentLinkedQueue<>(); + @Autowired UmsService umsService; - + public UmsSendManager() { - this.scheduler = Executors.newSingleThreadScheduledExecutor(r -> { - Thread t = new Thread(r); - t.setName("AlarmStateManager-worker"); - t.setDaemon(false); - return t; - }); + this.scheduler = Executors.newSingleThreadScheduledExecutor(r -> { + Thread t = new Thread(r); + t.setName("UmsSendManager-worker"); + return t; + }); - scheduler.scheduleWithFixedDelay(() -> { - - try { - // === 여기에 지속 실행할 로직 === - sendMessage(); - - } catch (Throwable e) { - // 반드시 예외 잡기 (안 잡으면 스케줄 자체가 죽음) - logger.error("fireAlarm fail", e); - } - - }, 0, 5, TimeUnit.SECONDS); // 최초 0초, 이후 5초 간격 + scheduler.scheduleWithFixedDelay(() -> { + try { + sendMessage(); + } catch (Throwable e) { + logger.error("UMS 스케줄러 실행 중 오류", e); + } + }, 0, 30, TimeUnit.SECONDS); } - - void sendMessage() throws Exception { - UmsRequestPayload payload; - while ((payload = queue.poll()) != null) { + + void sendMessage() { + UmsRequestPayload payload; + // 3. 한 번의 주기당 최대 처리량 제한 (필요시) + int count = 0; + while ((payload = queue.poll()) != null && count < 1000) { final UmsRequestPayload finalPayload = payload; + + // 전용 Executor를 사용하여 공용 풀 보호 CompletableFuture.runAsync(() -> { - UmsCallResult result = null; try { - result = umsService.send(finalPayload); + umsService.send(finalPayload); } catch (Exception e) { logger.error("UMS 전송 실패", e); - }finally { - logger.info(result); } - }); + }, ioExecutor); + count++; } - } - + + // 4. 안전한 종료 처리 + @PreDestroy + public void stop() { + scheduler.shutdown(); + ioExecutor.shutdown(); + try { + if (!ioExecutor.awaitTermination(60, TimeUnit.SECONDS)) { + ioExecutor.shutdownNow(); + } + } catch (InterruptedException e) { + ioExecutor.shutdownNow(); + logger.error("UmsSendManager shutdownNow.", e); + } + } + public void enqueue(UmsRequestPayload payload) { queue.offer(payload); } - - } From 1ceb69ac1f1087ba11e38b7b0850e5bb90957545 Mon Sep 17 00:00:00 2001 From: cho Date: Fri, 6 Mar 2026 16:59:51 +0900 Subject: [PATCH 159/159] =?UTF-8?q?=EA=B4=91=EC=A3=BC=20=EB=B3=B4=EC=95=88?= =?UTF-8?q?=EC=B7=A8=EC=95=BD=EC=A0=90=20=EB=95=8C=EB=AC=B8=EC=97=90=20127?= =?UTF-8?q?.0.0.1=20=ED=86=B5=EC=8B=A0=20=EB=A7=89=EC=95=84=EC=84=9C,=20ig?= =?UTF-8?q?nite=EA=B8=B0=EB=8F=99=20=EC=95=88=EB=90=98=EB=8A=94=20?= =?UTF-8?q?=EC=9D=B4=EC=8A=88=EB=A1=9C=20=EC=88=98=EC=A0=95.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/eactive/eai/common/session/SessionManagerForIgnite.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/com/eactive/eai/common/session/SessionManagerForIgnite.java b/src/main/java/com/eactive/eai/common/session/SessionManagerForIgnite.java index b145f7f..e5c13b1 100644 --- a/src/main/java/com/eactive/eai/common/session/SessionManagerForIgnite.java +++ b/src/main/java/com/eactive/eai/common/session/SessionManagerForIgnite.java @@ -276,7 +276,7 @@ public class SessionManagerForIgnite extends SessionManager { String server = null; // 서버정보의 IP가 시스템과 다른 ip로 설정되면 기동이 안되는 문제 if (localServerName.equals(key) && !"GW".equals(System.getProperty("spring.profiles.active", ""))) { - server = "127.0.0.1:" + discoverPort; + server = vo.getAddress() + ":" + discoverPort; } else { server = vo.getAddress() + ":" + discoverPort; }