Produced by Araxis Merge on 6/5/2018 10:24:11 AM Central Daylight Time. See www.araxis.com for information about Merge. This report uses XHTML and CSS2, and is best viewed with a modern standards-compliant browser. For optimum results when printing this report, use landscape orientation and enable printing of background images and colours in your browser.
# | Location | File | Last Modified |
---|---|---|---|
1 | patch_205_build_9.zip\Java\ImagingRouter\main\src\java\gov\va\med\imaging\router\commands | GetInstanceByImageUrnCommandImpl.java | Wed May 30 14:35:25 2018 UTC |
2 | patch_205_build_9.zip\Java\ImagingRouter\main\src\java\gov\va\med\imaging\router\commands | GetInstanceByImageUrnCommandImpl.java | Mon Jun 4 15:36:40 2018 UTC |
Description | Between Files 1 and 2 |
|
---|---|---|
Text Blocks | Lines | |
Unchanged | 2 | 1584 |
Changed | 1 | 2 |
Inserted | 0 | 0 |
Removed | 0 | 0 |
Whitespace | |
---|---|
Character case | Differences in character case are significant |
Line endings | Differences in line endings (CR and LF characters) are ignored |
CR/LF characters | Not shown in the comparison detail |
No regular expressions were active.
1 | /** | |
2 | * | |
3 | */ | |
4 | package go v.va.med.i maging.rou ter.comman ds; | |
5 | ||
6 | import gov .va.med.im aging.Imag eURN; | |
7 | import gov .va.med.im aging.chan nels.ByteS treamPump; | |
8 | import gov .va.med.im aging.chan nels.Check sumValue; | |
9 | import gov .va.med.im aging.chan nels.Compo siteIOExce ption; | |
10 | import gov .va.med.im aging.chan nels.excep tions.Chec ksumFormat Exception; | |
11 | import gov .va.med.im aging.core .StreamIma geFromCach eResponse; | |
12 | import gov .va.med.im aging.core .interface s.ImageMet adataNotif ication; | |
13 | import gov .va.med.im aging.core .interface s.exceptio ns.ImageCo nversionEx ception; | |
14 | import gov .va.med.im aging.core .interface s.exceptio ns.ImageNe arLineExce ption; | |
15 | import gov .va.med.im aging.core .interface s.exceptio ns.ImageNo tFoundExce ption; | |
16 | import gov .va.med.im aging.core .interface s.exceptio ns.MethodE xception; | |
17 | import gov .va.med.im aging.exch ange.busin ess.Image; | |
18 | import gov .va.med.im aging.exch ange.busin ess.ImageF ormatQuali tyList; | |
19 | import gov .va.med.im aging.exch ange.busin ess.ImageS treamRespo nse; | |
20 | import gov .va.med.im aging.exch ange.busin ess.util.E xchangeUti l; | |
21 | import gov .va.med.im aging.exch ange.enums .ImageForm at; | |
22 | import gov .va.med.im aging.exch ange.enums .ImageQual ity; | |
23 | import gov .va.med.im aging.exch ange.stora ge.cache.I mmutableIn stance; | |
24 | import gov .va.med.im aging.rout er.facade. ImagingCon text; | |
25 | import gov .va.med.im aging.stor age.cache. InstanceWr itableByte Channel; | |
26 | import gov .va.med.im aging.stor age.cache. exceptions .CacheExce ption; | |
27 | import gov .va.med.im aging.stor age.cache. exceptions .InstanceI naccessibl eException ; | |
28 | import gov .va.med.im aging.stor age.cache. exceptions .Simultane ousWriteEx ception; | |
29 | import gov .va.med.im aging.stor age.cache. impl.sql.S qlImageLoc ation; | |
30 | import gov .va.med.im aging.stor age.cache. impl.sql.m odel.Image Location; | |
31 | import gov .va.med.im aging.tran sactioncon text.Trans actionCont ext; | |
32 | import gov .va.med.im aging.tran sactioncon text.Trans actionCont extFactory ; | |
33 | ||
34 | import jav a.io.IOExc eption; | |
35 | import jav a.io.Input Stream; | |
36 | import jav a.io.Outpu tStream; | |
37 | import jav a.nio.chan nels.Chann els; | |
38 | ||
39 | import jav ax.persist ence.Entit yManager; | |
40 | ||
41 | /** | |
42 | * @author PII | |
43 | * | |
44 | */ | |
45 | public cla ss GetInst anceByImag eUrnComman dImpl | |
46 | extends Ab stractImag eCommandIm pl<Long> | |
47 | { | |
48 | pr ivate stat ic final l ong serial VersionUID = 1969186 6197926736 57L; | |
49 | ||
50 | pr ivate fina l ImageURN imageUrn; | |
51 | pr ivate fina l ImageMet adataNotif ication im ageMetadat aNotificat ion; | |
52 | pr ivate fina l OutputSt ream outSt ream; | |
53 | pr ivate fina l ImageFor matQuality List image FormatQual ityList; | |
54 | ||
55 | pr ivate fina l static i nt prefetc hImageRetr yDelayMinu tes = 1; | |
56 | ||
57 | pu blic GetIn stanceByIm ageUrnComm andImpl( | |
58 | ImageU RN imageUr n, | |
59 | ImageF ormatQuali tyList ima geFormatQu alityList, | |
60 | Output Stream out Stream) | |
61 | { | |
62 | this (imageUrn, imageForm atQualityL ist, outSt ream, (Ima geMetadata Notificati on)null); | |
63 | } | |
64 | ||
65 | ||
66 | /* * | |
67 | * | |
68 | * @param co mmandConte xt - the c ontext ava ilable to the comman d | |
69 | * @param im ageUrn - t he univers al identif ier of the image | |
70 | * @param ou tStream - the Output Stream wh ere the im age text w ill be ava ilable | |
71 | * @param me tadataCall back - the listener to be noti fied when metadata i s availabl e | |
72 | * @param im ageFormatQ ualityList - a list of accepta ble format quality v alues | |
73 | * / | |
74 | pu blic GetIn stanceByIm ageUrnComm andImpl( | |
75 | ImageU RN imageUr n, | |
76 | ImageF ormatQuali tyList ima geFormatQu alityList, | |
77 | Output Stream out Stream, | |
78 | ImageM etadataNot ification imageMetad ataNotific ation) | |
79 | { | |
80 | supe r(); | |
81 | this .imageUrn = imageUrn ; | |
82 | this .imageMeta dataNotifi cation = i mageMetada taNotifica tion; | |
83 | this .outStream = outStre am; | |
84 | this .imageForm atQualityL ist = imag eFormatQua lityList; | |
85 | } | |
86 | ||
87 | /* (non-Java doc) | |
88 | * @see gov. va.med.ima ging.core. router.Abs tractComma ndImpl#par ameterToSt ring() | |
89 | * / | |
90 | @O verride | |
91 | pr otected St ring param eterToStri ng() | |
92 | { | |
93 | Stri ngBuffer s b = new St ringBuffer (); | |
94 | ||
95 | sb.a ppend(getI mageUrn()) ; | |
96 | sb.a ppend(',') ; | |
97 | sb.a ppend(getM etadataCal lback() == null ? "< null callb ack>" : ge tMetadataC allback(). toString() ); | |
98 | sb.a ppend(',') ; | |
99 | sb.a ppend(getO utStream() == null ? "<null ou t stream>" : getOutS tream()); | |
100 | sb.a ppend(',') ; | |
101 | sb.a ppend(getR equestedFo rmatQualit y() == nul l ? "<null image for mat>" : ge tRequested FormatQual ity().toSt ring()); | |
102 | ||
103 | retu rn sb.toSt ring(); | |
104 | } | |
105 | ||
106 | /* (non-Java doc) | |
107 | * @see gov. va.med.ima ging.core. interfaces .router.co mmands.Get InstanceBy ImageUrnCo mmand#getI mageUrn() | |
108 | * / | |
109 | pu blic Image URN getIma geUrn() | |
110 | { | |
111 | retu rn this.im ageUrn; | |
112 | } | |
113 | ||
114 | /* (non-Java doc) | |
115 | * @see gov. va.med.ima ging.core. interfaces .router.co mmands.Get InstanceBy ImageUrnCo mmand#getM etadataCal lback() | |
116 | * / | |
117 | pu blic Image MetadataNo tification getMetada taCallback () | |
118 | { | |
119 | retu rn this.im ageMetadat aNotificat ion; | |
120 | } | |
121 | ||
122 | /* (non-Java doc) | |
123 | * @see gov. va.med.ima ging.core. interfaces .router.co mmands.Get InstanceBy ImageUrnCo mmand#getO utStream() | |
124 | * / | |
125 | pu blic Outpu tStream ge tOutStream () | |
126 | { | |
127 | retu rn this.ou tStream; | |
128 | } | |
129 | ||
130 | /* (non-Java doc) | |
131 | * @see gov. va.med.ima ging.core. interfaces .router.co mmands.Get InstanceBy ImageUrnCo mmand#getR equestedFo rmatQualit y() | |
132 | * / | |
133 | pu blic Image FormatQual ityList ge tRequested FormatQual ity() | |
134 | { | |
135 | retu rn this.im ageFormatQ ualityList ; | |
136 | } | |
137 | ||
138 | /* (non-Java doc) | |
139 | * @see java .lang.Obje ct#hashCod e() | |
140 | * / | |
141 | @O verride | |
142 | pu blic int h ashCode() | |
143 | { | |
144 | fina l int prim e = 31; | |
145 | int result = 1 ; | |
146 | resu lt = prime | |
147 | * result | |
148 | + ((this .imageForm atQualityL ist == nul l) ? 0 | |
149 | : this.image FormatQual ityList.ha shCode()); | |
150 | resu lt = prime | |
151 | * result | |
152 | + ((this .imageMeta dataNotifi cation == null) ? 0 | |
153 | : this.image MetadataNo tification .hashCode( )); | |
154 | resu lt = prime * result | |
155 | + ((this .imageUrn == null) ? 0 : this. imageUrn.h ashCode()) ; | |
156 | retu rn result; | |
157 | } | |
158 | ||
159 | /* (non-Java doc) | |
160 | * @see java .lang.Obje ct#equals( java.lang. Object) | |
161 | * / | |
162 | @O verride | |
163 | pu blic boole an equals( Object obj ) | |
164 | { | |
165 | if ( this == ob j) | |
166 | return true; | |
167 | if ( getClass() != obj.ge tClass()) | |
168 | return false; | |
169 | fina l GetInsta nceByImage UrnCommand Impl other = (GetIns tanceByIma geUrnComma ndImpl) ob j; | |
170 | if ( this.image FormatQual ityList == null) | |
171 | { | |
172 | if (ot her.imageF ormatQuali tyList != null) | |
173 | return f alse; | |
174 | } el se if (!th is.imageFo rmatQualit yList | |
175 | .equals( other.imag eFormatQua lityList)) | |
176 | return false; | |
177 | if ( this.image MetadataNo tification == null) | |
178 | { | |
179 | if (ot her.imageM etadataNot ification != null) | |
180 | return f alse; | |
181 | } el se if (!th is.imageMe tadataNoti fication | |
182 | .equals( other.imag eMetadataN otificatio n)) | |
183 | return false; | |
184 | if ( this.image Urn == nul l) | |
185 | { | |
186 | if (ot her.imageU rn != null ) | |
187 | return f alse; | |
188 | } el se if (!th is.imageUr n.equals(o ther.image Urn)) | |
189 | return false; | |
190 | retu rn true; | |
191 | } | |
192 | ||
193 | /* (non-Java doc) | |
194 | * @see gov. va.med.ima ging.core. router.Abs tractComma ndImpl#cal lInTransac tionContex t() | |
195 | * / | |
196 | @O verride | |
197 | pu blic Long callSynchr onouslyInT ransaction Context() | |
198 | th rows Metho dException | |
199 | { | |
200 | int bytesRetur ned=0; | |
201 | Tran sactionCon text trans actionCont ext = Tran sactionCon textFactor y.get(); | |
202 | ||
203 | getL ogger().in fo("Router Impl.getIn stanceByIm ageURN(" + imageUrn. toString() + ", " + getRequest edFormatQu ality().ge tAcceptStr ing(true, true) + ") "); | |
204 | if(o utStream = = null) | |
205 | { | |
206 | throw new Method Exception( "Outputstr eam is nul l"); | |
207 | } | |
208 | ||
209 | // u se this im ageId to q uery the D OD | |
210 | Stri ng imageId = imageUr n.getImage Id(); | |
211 | Stri ng studyId = imageUr n.getStudy Id(); | |
212 | Stri ng siteNum ber = imag eUrn.getOr iginatingS iteId(); | |
213 | tran sactionCon text.setSe rvicedSour ce(imageUr n.toRoutin gTokenStri ng()); | |
214 | ||
215 | //By pass cachi ng if the image is i n local si te. | |
216 | bool ean isView erProcess = (transac tionContex t.isViewer Process() == null ? false : tr ansactionC ontext.isV iewerProce ss()); | |
217 | ||
218 | if ( isViewerPr ocess | |
219 | && trans actionCont ext.getSit eNumber(). equals(sit eNumber) | |
220 | && (SqlI mageLocati on.getEnti tyManager( ) == null) ) | |
221 | { | |
222 | getLog ger().info ("Image '" + imageUr n.toString () + " is in local s ite - bypa ss caching "); | |
223 | return streamLoc alImageFro mDataSourc e(); | |
224 | } | |
225 | ||
226 | // i f caching is enabled we will t ry to use the cache | |
227 | // c acheThisIn stance ind icates bot h that we write to a nd read fr om the cac he for thi s instance | |
228 | bool ean cacheT hisInstanc e = studyI d != null && image Id != null && getCo mmandConte xt().isCac hingEnable d(); | |
229 | ||
230 | // i f the Imag e URN was successful ly parsed and cachin g is enabl ed | |
231 | // t ry to retr ieve the i nstance fr om the cac he | |
232 | if( cacheThisI nstance ) | |
233 | { | |
234 | getLog ger().info ("Image '" + imageUr n.toString () + "' ca ching enab led."); | |
235 | ||
236 | try | |
237 | { | |
238 | //Stream Local Cac he | |
239 | StreamIm ageFromCac heResponse response = | |
240 | Co mmonImageC acheFuncti ons.stream ImageFromC ache( | |
241 | getCom mandContex t(), image Urn, | |
242 | getReq uestedForm atQuality( ), outStre am, | |
243 | getMet adataCallb ack()); | |
244 | if((resp onse != nu ll) && (re sponse.get BytesRetur nedFromDat aSource() > 0)) | |
245 | { | |
246 | transactio nContext.s etItemCach ed(Boolean .TRUE); | |
247 | getLogger( ).info("Im age '" + i mageUrn.to String() + "' found in the cac he and str eamed to t he destina tion."); | |
248 | Image imag e = findIm ageInCache dStudyGrap h(imageUrn ); | |
249 | if(image ! = null) | |
250 | { | |
251 | if ((image.ge tAlienSite Number() ! = null) && (image.ge tAlienSite Number().l ength() > 0)) | |
252 | { | |
253 | getL ogger().in fo("Found image meta data in ca che with a lien site number, up dating ser viced sour ce of imag e"); | |
254 | tran sactionCon text.setSe rvicedSour ce(image.g etSiteNumb er() + "(" + image.g etAlienSit eNumber() + ")"); | |
255 | } | |
256 | } | |
257 | ||
258 | return new Long(resp onse.getBy tesReturne dFromDataS ource()); | |
259 | // new Ima geMetadata (imageUrn, response. imageForma t, null, r esponse.by tesReturne dFromDataS ource, res ponse.byte sReturnedF romDataSou rce); | |
260 | } | |
261 | ||
262 | //Since it's not i n the loca l cache, t ry to stre am from Re mote Locat ion via Sq lImageLoca tion | |
263 | EntityMa nager em = SqlImageL ocation.ge tEntityMan ager(); | |
264 | if (em ! = null) | |
265 | { | |
266 | ImageLocat ion imageL ocation = CommonSqlI mageLocati onFunction s.getImage Location( | |
267 | em, imag eUrn, getR equestedFo rmatQualit y()); | |
268 | ||
269 | if ((image Location ! = null) && (imageLoc ation.getI mageSize() > 0)) | |
270 | { | |
271 | lo ng bytesRe turnedFrom Remote = C ommonSqlIm ageLocatio nFunctions .streamIma geFromImag eLocation( | |
272 | imageL ocation, i mageUrn, o utStream, getMetadat aCallback( )); | |
273 | if (bytesRet urnedFromR emote > 0) { | |
274 | retu rn bytesRe turnedFrom Remote; | |
275 | } | |
276 | } | |
277 | } | |
278 | ||
279 | getLogge r().info(" Did not ge t image [" + imageUr n.toString () + "] fr om local/r emote cach e"); | |
280 | } | |
281 | catch( CompositeI OException cioX) | |
282 | { | |
283 | // if we know that no bytes have been written th en we we c an continu e | |
284 | // other wise we ha ve to stop here and throw an e rror | |
285 | if( cioX .isBytesWr ittenKnown () && cioX .getBytesW ritten() = = 0 || cio X.getBytes Written() == -1 ) | |
286 | { | |
287 | getLogger( ).warn( | |
288 | "I O Exceptio n when rea ding from cache, con tinuing wi th direct data sourc e stream." + | |
289 | ci oX.getByte sWritten() + | |
290 | " bytes were indicated to have b een writte n." + | |
291 | "C aused by : [" + cioX .getMessag e() + | |
292 | "] at " + ge tClass().g etName() + ".callSyn chronously InTransact ionContext ()" | |
293 | ); | |
294 | return str eamFromDat aSource(); | |
295 | } | |
296 | else | |
297 | { | |
298 | // excepti on occurre d, we can' t continue because t he image m ay be part ially writ ten | |
299 | getLogger( ).error(ci oX); | |
300 | throw new MethodExce ption( | |
301 | "I O Exceptio n when rea ding from cache, can not contin ue because " + cioX. getBytesWr itten() + | |
302 | " bytes were known to have been written, c ontinuing could resu lt in corr upted imag e. " + | |
303 | "C aused by : [" + cioX .getMessag e() + | |
304 | "] at " + ge tClass().g etName() + ".callSyn chronously InTransact ionContext ()" | |
305 | ); | |
306 | } | |
307 | } | |
308 | catch( IOExceptio n ioX) | |
309 | { | |
310 | // excep tion occur red, we ca n't contin ue because the image may be pa rtially wr itten | |
311 | getLogge r().error( ioX); | |
312 | throw ne w MethodEx ception( | |
313 | "IO Except ion when r eading fro m cache, c annot cont inue becau se some by tes may be written, " + | |
314 | "continuin g could re sult in co rrupted im age. " + | |
315 | "Caused by : [" + io X.getMessa ge() + | |
316 | "] at " + getClass() .getName() + ".callS ynchronous lyInTransa ctionConte xt()" | |
317 | ); | |
318 | } | |
319 | ||
320 | ||
321 | // if we get her e then cac hing is en abled but the instan ce was not found | |
322 | // in the local cache nor remote cac he, we try to grab t he writabl e byte cha nnel | |
323 | // as soon as po ssible to lock other threads f rom writin g to it | |
324 | transa ctionConte xt.setItem Cached(Boo lean.FALSE ); | |
325 | Immuta bleInstanc e instance = null; | |
326 | Instan ceWritable ByteChanne l instance WritableCh annel = nu ll; | |
327 | Output Stream cac heOutStrea m = null; | |
328 | ||
329 | // JMW 9/5/08 - if the ima ge comes b ack from t he datasou rce, use t he propert ies of the | |
330 | // ima ge (format /quality) from the d atasource to find it in the ca che | |
331 | ImageF ormat data SourceImag eFormat = null; | |
332 | ImageQ uality dat aSourceIma geQuality = null; | |
333 | ||
334 | try | |
335 | { | |
336 | ImageStr eamRespons e datasour ceResponse = streamI mageFromDa taSource(i mageUrn, g etRequeste dFormatQua lity()); | |
337 | ImageFor mat imgFor mat = data sourceResp onse.getIm ageFormat( ); | |
338 | getLogge r().info(" Received r esponse fr om data so urce, putt ing into c ache"); | |
339 | // set t he data so urce image format an d image qu ality here | |
340 | // since it is now in the ca che. | |
341 | // JMW 1 0/6/2008 | |
342 | // moved this here , if we ge t the imag e from the DS, need to use the format/qu ality from the DS to put/get t he image f rom the ca che | |
343 | // only clear thes e values i f there is a cache e xception ( error writ ing to the cache) | |
344 | dataSour ceImageFor mat = imgF ormat; | |
345 | dataSour ceImageQua lity = dat asourceRes ponse.getI mageQualit y(); | |
346 | ||
347 | getLogge r().debug( "Attemptin g to creat e cache in stance wit h format [ " + dataS ourceImage Format + " ] and qual ity [" + d ataSourceI mageQualit y + "]"); | |
348 | if(Excha ngeUtil.is SiteDOD(si teNumber)) | |
349 | { | |
350 | instance = getComman dContext() .getExtraE nterpriseC ache().cre ateImage(i mageUrn, d ataSourceI mageQualit y.name(), dataSource ImageForma t.getMimeW ithEnclose dMime()); | |
351 | } | |
352 | else | |
353 | { | |
354 | instance = getComman dContext() .getIntraE nterpriseC acheCache( ).createIm age(imageU rn, dataSo urceImageQ uality.nam e(), dataS ourceImage Format.get MimeWithEn closedMime ()); | |
355 | } | |
356 | ||
357 | instance WritableCh annel = in stance.get WritableCh annel(); | |
358 | cacheOut Stream = C hannels.ne wOutputStr eam(instan ceWritable Channel); | |
359 | ||
360 | InputStr eam imageS tream = da tasourceRe sponse.get ImageStrea m().getInp utStream() ; | |
361 | ||
362 | if(cache OutStream != null) | |
363 | { | |
364 | getLogger( ).info("Pu mping stre am into ca che"); | |
365 | ByteStream Pump pump = ByteStre amPump.get ByteStream Pump(ByteS treamPump. TRANSFER_T YPE.Networ kToNetwork ); | |
366 | // if the cacheStrea m is null the ByteSt reamPump w ill ignore it | |
367 | bytesRetur ned = pump .xfer(imag eStream, c acheOutStr eam); | |
368 | ||
369 | ||
370 | }// not really sur e what to do in the alternativ e here... | |
371 | ||
372 | if(image Stream != null) | |
373 | { | |
374 | // close t he input s tream | |
375 | imageStrea m.close(); | |
376 | } | |
377 | String r esponseChe cksum = da tasourceRe sponse.get ProvidedIm ageChecksu m(); | |
378 | cacheOut Stream.clo se(); | |
379 | boolean noResponse Checksum = false; | |
380 | if(respo nseChecksu m != null) | |
381 | { | |
382 | noResponse Checksum = (response Checksum.e quals("ok" ) || respo nseChecksu m.equals(" not ok")); | |
383 | } | |
384 | String c acheChecks um = insta nce.getChe cksumValue (); | |
385 | if(respo nseChecksu m != null && cacheCh ecksum != null) | |
386 | { | |
387 | try | |
388 | { | |
389 | Ch ecksumValu e response CV; | |
390 | if (noRespon seChecksum ) response CV = new C hecksumVal ue(""); | |
391 | el se respons eCV = new ChecksumVa lue(respon seChecksum ); | |
392 | Ch ecksumValu e cacheCV = new Chec ksumValue( cacheCheck sum); | |
393 | ||
394 | if (noRespon seChecksum ) { | |
395 | ||
396 | if ( responseCh ecksum.equ als("ok")) | |
397 | getLog ger().info ("Checksum for inStr eam '" + i mageUrn + "' equals to data so urce cheks um."); | |
398 | else // "not o k" | |
399 | getLog ger().info ("Checksum for inStr eam '" + i mageUrn + "' IS Not Equal to d ata source cheksum." ); | |
400 | } | |
401 | el se if (res ponseCV.ge tAlgorithm ().equals( cacheCV.ge tAlgorithm ())) { | |
402 | ||
403 | if ( ! response CV.equals( cacheCV) ) | |
404 | getLog ger().erro r("Checksu ms for ins tance '" + imageUrn + "' ARE N OT EQUAL." ); | |
405 | else | |
406 | getLog ger().info ("Checksum s for inst ance '" + imageUrn + "' are eq ual."); | |
407 | } | |
408 | el se | |
409 | getL ogger().wa rn("Checks ums not co mpared for instance '" + image Urn + | |
410 | "' becau se respons e algorith m is '" + responseCV .getAlgori thm() + | |
411 | "' and c ache algor ithm is '" + cacheCV .getAlgori thm() + "' ."); | |
412 | } | |
413 | catch (Che cksumForma tException x) | |
414 | { | |
415 | ge tLogger(). error("Inv alidly for matted che cksum valu e, either response h eader chec ksum '" + responseCh ecksum + | |
416 | "' or cache calc ulated che cksum '" + cacheChec ksum + "'" ); | |
417 | } | |
418 | } | |
419 | } | |
420 | catch( InstanceIn accessible Exception iaX) | |
421 | { | |
422 | // speci al excepti on handlin g, another thread is requestin g to write to the in stance | |
423 | // just before we did. Try once again to read f rom the ca che, our t hread will be held u ntil | |
424 | // the w rite is co mplete | |
425 | try | |
426 | { | |
427 | getLogger( ).warn("In stanceInac cessibleEx ception ca used by im age [" + i mageUrn.to String() + "]", iaX) ; | |
428 | /* | |
429 | StreamImag eFromCache Response r esponse = streamImag eFromCache (imageUrn, | |
430 | requ estedForma tQuality, outStream, metadataC allback); | |
431 | */ | |
432 | StreamImag eFromCache Response r esponse = null; | |
433 | // if the image was from the d atasource, the dataS ourceImage Format and dataSourc eImageQual ity from t he data so urce | |
434 | // should be set, ge t that ins tance from the cache (since th e quality of the ima ge cached might be h igher | |
435 | // than th e image re quested). This preve nts puttin g an item into the c ache and t hen never retrieving it. | |
436 | if((dataSo urceImageF ormat != n ull) && | |
437 | (d ataSourceI mageQualit y != null) ) | |
438 | { | |
439 | ge tLogger(). debug("Fin ding cache d instance using for mat [" + d ataSourceI mageFormat + | |
440 | "] a nd quality [" + data SourceImag eQuality + "] from d ata source response. "); | |
441 | in t bytes = CommonImag eCacheFunc tions.stre amImageFro mCache(get CommandCon text(), | |
442 | imageU rn, dataSo urceImageF ormat, dat aSourceIma geQuality, outStream , getMetad ataCallbac k()); | |
443 | if (bytes > 0 ) | |
444 | { | |
445 | getL ogger().de bug("Found instance in cache u sing quali ty and for mat from d ata source response. "); | |
446 | resp onse = new StreamIma geFromCach eResponse( null, byte s, dataSou rceImageFo rmat, data SourceImag eQuality); | |
447 | } | |
448 | } | |
449 | else | |
450 | { | |
451 | re sponse = C ommonImage CacheFunct ions.strea mImageFrom Cache(getC ommandCont ext(), | |
452 | imageU rn, getReq uestedForm atQuality( ), outStre am, getMet adataCallb ack()); | |
453 | } | |
454 | ||
455 | if(respons e != null) | |
456 | { | |
457 | by tesReturne d = respon se.getByte sReturnedF romDataSou rce(); | |
458 | if ( bytesRet urned > 0 ) | |
459 | { | |
460 | getL ogger().in fo("Image '" + image Urn.toStri ng() + "' found in t he cache a nd streame d to the d estination ."); | |
461 | retu rn new Lon g(bytesRet urned); // new ImageM etadata(im ageUrn, re sponse.ima geFormat, null, byte sReturned, bytesRetu rned); | |
462 | } | |
463 | } | |
464 | getLogger( ).info("Di d not get image [" + imageUrn. toString() + "] from cache"); | |
465 | } | |
466 | catch(Co mpositeIOE xception c ioX) | |
467 | { | |
468 | // if we k now that n o bytes ha ve been wr itten then we we can continue | |
469 | // otherwi se we have to stop h ere and th row an err or | |
470 | if( cioX.i sBytesWrit tenKnown() && cioX.g etBytesWri tten() == 0 || cioX. getBytesWr itten() == -1 ) | |
471 | { | |
472 | ge tLogger(). warn( | |
473 | "IO Exception when readi ng from ca che, conti nuing with direct da ta source stream." + | |
474 | cioX .getBytesW ritten() + | |
475 | " by tes were i ndicated t o have bee n written. " + | |
476 | "Cau sed by : [ " + cioX.g etMessage( ) + | |
477 | "] a t " + getC lass().get Name() + " .callSynch ronouslyIn Transactio nContext() " | |
478 | ); | |
479 | re turn strea mFromDataS ource(); | |
480 | } | |
481 | else | |
482 | { | |
483 | // exception occurred, we can't continue b ecause the image may be partia lly writte n | |
484 | ge tLogger(). error(cioX ); | |
485 | th row new Me thodExcept ion( | |
486 | "IO Exception when readi ng from ca che, canno t continue because " + cioX.ge tBytesWrit ten() + | |
487 | " by tes were k nown to ha ve been wr itten, con tinuing co uld result in corrup ted image. " + | |
488 | "Cau sed by : [ " + cioX.g etMessage( ) + | |
489 | "] a t " + getC lass().get Name() + " .callSynch ronouslyIn Transactio nContext() " | |
490 | ); | |
491 | } | |
492 | } | |
493 | catch(IO Exception ioX) | |
494 | { | |
495 | // excepti on occured , we can't continue because th e image ma y be parti ally writt en | |
496 | getLogger( ).error(io X); | |
497 | throw new MethodExce ption( | |
498 | "I O Exceptio n when rea ding from cache, can not contin ue because some byte s may be w ritten, co ntinuing c ould resul t in corru pted image ." + | |
499 | "C aused by : [" + ioX. getMessage () + | |
500 | "] at " + ge tClass().g etName() + ".callSyn chronously InTransact ionContext () in Inst anceInacce ssibleExce ption hand ler" | |
501 | ); | |
502 | } | |
503 | } | |
504 | catch( Simultaneo usWriteExc eption swX ) | |
505 | { | |
506 | getLogge r().warn(" Simultaneo usWriteExc eption cau sed by ima ge [" + im ageUrn.toS tring() + "]", swX); | |
507 | // JMW 1 0/3/2008 | |
508 | // occur s if 2 thr eads are a ttempting to write t o the cach e at the s ame time, | |
509 | // this thread wil l try to g et the ima ge from th e cache wh ich should cause thi s | |
510 | // threa d to wait for the ot her thread to comple te before getting th e image | |
511 | try | |
512 | { | |
513 | ||
514 | StreamImag eFromCache Response r esponse = null; | |
515 | // if the image was from the d atasource, the dataS ourceImage Format and dataSourc eImageQual ity from t he data so urce | |
516 | // should be set, ge t that ins tance from the cache (since th e quality of the ima ge cached might be h igher | |
517 | // than th e image re quested). This preve nts puttin g an item into the c ache and t hen never retrieving it. | |
518 | if((dataSo urceImageF ormat != n ull) && | |
519 | (d ataSourceI mageQualit y != null) ) | |
520 | { | |
521 | ge tLogger(). debug("Fin ding cache d instance using for mat [" + d ataSourceI mageFormat + | |
522 | "] a nd quality [" + data SourceImag eQuality + "] from d ata source response. "); | |
523 | in t bytes = CommonImag eCacheFunc tions.stre amImageFro mCache(get CommandCon text(), | |
524 | imageU rn, dataSo urceImageF ormat, dat aSourceIma geQuality, outStream , getMetad ataCallbac k()); | |
525 | if (bytes > 0 ) | |
526 | { | |
527 | getL ogger().de bug("Found instance in cache u sing quali ty and for mat from d ata source response. "); | |
528 | resp onse = new StreamIma geFromCach eResponse( null, byte s, dataSou rceImageFo rmat, data SourceImag eQuality); | |
529 | } | |
530 | } | |
531 | else | |
532 | { | |
533 | re sponse = C ommonImage CacheFunct ions.strea mImageFrom Cache(getC ommandCont ext(), | |
534 | imageU rn, getReq uestedForm atQuality( ), outStre am, getMet adataCallb ack()); | |
535 | } | |
536 | if(respons e != null) | |
537 | { | |
538 | by tesReturne d = respon se.getByte sReturnedF romDataSou rce(); | |
539 | if ( bytesRet urned > 0 ) | |
540 | { | |
541 | getL ogger().in fo("Image '" + image Urn.toStri ng() + "' found in t he cache a nd streame d to the d estination ."); | |
542 | retu rn new Lon g(bytesRet urned); // new ImageM etadata(im ageUrn, re sponse.ima geFormat, null, byte sReturned, bytesRetu rned); | |
543 | } | |
544 | } | |
545 | getLogger( ).info("Di d not get image [" + imageUrn. toString() + "] from cache"); | |
546 | } | |
547 | catch(IO Exception ioX) | |
548 | { | |
549 | // excepti on occurre d, we can' t continue because t he image m ay be part ially writ ten | |
550 | getLogger( ).error(io X); | |
551 | throw new MethodExce ption( | |
552 | "I O Exceptio n when rea ding from cache, can not contin ue because some byte s may be w ritten, co ntinuing c ould resul t in corru pted image ." + | |
553 | "C aused by : [" + ioX. getMessage () + | |
554 | "] at " + ge tClass().g etName() + ".callSyn chronously InTransact ionContext () in Simu ltaneousWr iteExcepti on handler " | |
555 | ); | |
556 | } | |
557 | } | |
558 | catch( CacheExcep tion cX) | |
559 | { | |
560 | // any k ind of cac he excepti ons should be logged , but the image must still be retreived from the D oD | |
561 | // from here on if cacheOutS tream is n ot null we 'll write to it | |
562 | getLogge r().error( cX); | |
563 | instance = null; | |
564 | instance WritableCh annel= nul l; | |
565 | cacheOut Stream = n ull; | |
566 | dataSour ceImageFor mat = null ; | |
567 | dataSour ceImageQua lity = nul l; | |
568 | } | |
569 | catch( IOExceptio n ioX) | |
570 | { | |
571 | cacheOut Stream = n ull; | |
572 | try{inst anceWritab leChannel. error();}c atch(Throw able t){} | |
573 | getLogge r().error( ioX); | |
574 | } | |
575 | catch (ImageNotF oundExcept ion e) | |
576 | { | |
577 | //return null; | |
578 | throw e; | |
579 | } | |
580 | catch( ImageNearL ineExcepti on inlX) | |
581 | { | |
582 | schedule RequestOfN earlineIma ge(); | |
583 | throw in lX; | |
584 | } | |
585 | finall y | |
586 | { | |
587 | // the i nstance ab solutely p ositively must be cl osed | |
588 | if((inst anceWritab leChannel != null) & & (instanc eWritableC hannel.isO pen())) | |
589 | { | |
590 | getLogger( ).error("C ache insta nce writab le byte ch annel bein g closed w ith error on unknown exception "); | |
591 | try{instan ceWritable Channel.er ror();}cat ch(Throwab le t){} | |
592 | } | |
593 | } | |
594 | ||
595 | // the image is now in the cache, th e streams and channe ls are clo sed | |
596 | // now try to st ream from the cache | |
597 | try | |
598 | { | |
599 | StreamIm ageFromCac heResponse response = null; | |
600 | // if th e image wa s from the datasourc e, the dat aSourceIma geFormat a nd dataSou rceImageQu ality from the data source | |
601 | // shoul d be set, get that i nstance fr om the cac he (since the qualit y of the i mage cache d might be higher | |
602 | // than the image requested) . This pre vents putt ing an ite m into the cache and then neve r retrievi ng it. | |
603 | if((data SourceImag eFormat != null) && | |
604 | (dataSourc eImageQual ity != nul l)) | |
605 | { | |
606 | getLogger( ).debug("F inding cac hed instan ce using f ormat [" + dataSourc eImageForm at + | |
607 | "] and quali ty [" + da taSourceIm ageQuality + "] from data sour ce respons e."); | |
608 | int bytes = CommonIm ageCacheFu nctions.st reamImageF romCache(g etCommandC ontext(), | |
609 | imag eUrn, data SourceImag eFormat, d ataSourceI mageQualit y, outStre am, getMet adataCallb ack()); | |
610 | if(bytes > 0) | |
611 | { | |
612 | ge tLogger(). debug("Fou nd instanc e in cache using qua lity and f ormat from data sour ce respons e."); | |
613 | re sponse = n ew StreamI mageFromCa cheRespons e(null, by tes, dataS ourceImage Format, da taSourceIm ageQuality ); | |
614 | } | |
615 | } | |
616 | else | |
617 | { | |
618 | response = CommonIma geCacheFun ctions.str eamImageFr omCache(ge tCommandCo ntext(), | |
619 | imag eUrn, getR equestedFo rmatQualit y(), outSt ream, getM etadataCal lback()); | |
620 | } | |
621 | // if th e response is null, then didn' t get anyt hing from the cache (shouldn't happen) | |
622 | if(respo nse != nul l) | |
623 | { | |
624 | bytesRetur ned = resp onse.getBy tesReturne dFromDataS ource(); | |
625 | if( bytesR eturned > 0 ) | |
626 | { | |
627 | ge tLogger(). info("Imag e '" + ima geUrn.toSt ring() + " ' found in the cache and strea med to the destinati on."); | |
628 | re turn new L ong(bytesR eturned);/ / new Imag eMetadata( imageUrn, response.i mageFormat , null, by tesReturne d, bytesRe turned); | |
629 | } | |
630 | } | |
631 | getLogge r().info(" Did not ge t image [" + imageUr n.toString () + "] fr om cache") ; | |
632 | } | |
633 | catch( IOExceptio n ioX) | |
634 | { | |
635 | // excep tion occur ed, we can 't continu e because the image may be par tially wri tten | |
636 | getLogge r().error( ioX); | |
637 | throw ne w MethodEx ception( | |
638 | "IO Except ion when r eading fro m cache, c annot cont inue becau se some by tes may be written, continuing could res ult in cor rupted ima ge." + | |
639 | "Caused by : [" + io X.getMessa ge() + | |
640 | "] at " + getClass() .getName() + ".callS ynchronous lyInTransa ctionConte xt() strea ming from cache." | |
641 | ); | |
642 | } | |
643 | } | |
644 | ||
645 | // c aching is disabled o r unusable for this instance | |
646 | // s tream dire ctly from cache | |
647 | retu rn streamF romDataSou rce(); | |
648 | } | |
649 | ||
650 | /* * | |
651 | * Stream th e image fr om the dat a source a nd put it into the o utput stre am. This m ethod DOES NOT use t he | |
652 | * cache so it should only be ca lled after cache att empts have failed. | |
653 | * | |
654 | * @param by tesReturne d | |
655 | * @return | |
656 | * @throws M ethodExcep tion | |
657 | * @throws I mageConver sionExcept ion | |
658 | * @throws I mageNotFou ndExceptio n | |
659 | * @throws I mageNearLi neExceptio n | |
660 | * / | |
661 | pr ivate Long streamFro mDataSourc e() | |
662 | throws MethodExc eption, Im ageConvers ionExcepti on, | |
663 | ImageN otFoundExc eption, Im ageNearLin eException | |
664 | { | |
665 | getL ogger().in fo("Image '" + image Urn.toStri ng() + "' caching di sabled, ge tting imag e from sou rce."); | |
666 | ||
667 | Inpu tStream im ageStream = null; | |
668 | try | |
669 | { | |
670 | ImageS treamRespo nse stream Response = streamIma geFromData Source(ima geUrn, get RequestedF ormatQuali ty()); | |
671 | if(get MetadataCa llback() ! = null) | |
672 | { | |
673 | getMetad ataCallbac k().imageM etadata(st reamRespon se.getProv idedImageC hecksum(), | |
674 | streamResp onse.getIm ageFormat( ), 0, stre amResponse .getImageQ uality()); | |
675 | } | |
676 | getLog ger().info ("Pumping response t o client ( bypassing cache)"); | |
677 | ByteSt reamPump p ump = Byte StreamPump .getByteSt reamPump(B yteStreamP ump.TRANSF ER_TYPE.Ne tworkToNet work); | |
678 | // if the cacheS tream is n ull the By teStreamPu mp will ig nore it | |
679 | imageS tream = st reamRespon se.getImag eStream(). getInputSt ream(); | |
680 | long b ytesReturn ed = pump. xfer(image Stream, ou tStream); | |
681 | return new Long( bytesRetur ned);// ne w ImageMet adata(imag eUrn, stre amResponse .getImageF ormat(), n ull, bytes Returned, bytesRetur ned); | |
682 | } | |
683 | catc h (IOExcep tion ioX) | |
684 | { | |
685 | getLog ger().erro r(ioX); | |
686 | throw new Method Exception( ioX); | |
687 | } | |
688 | catc h (ImageNo tFoundExce ption e) | |
689 | { | |
690 | throw e; | |
691 | } | |
692 | catc h(ImageNea rLineExcep tion inlX) | |
693 | { | |
694 | schedu leRequestO fNearlineI mage(); | |
695 | throw inlX; | |
696 | } | |
697 | fina lly | |
698 | { | |
699 | if(ima geStream ! = null) | |
700 | { | |
701 | try{imag eStream.cl ose();} | |
702 | catch(IO Exception ioX){getLo gger().war n(ioX);} | |
703 | } | |
704 | } | |
705 | } | |
706 | ||
707 | pr ivate Long streamLoc alImageFro mDataSourc e() | |
708 | th rows Metho dException , ImageCon versionExc eption, | |
709 | ImageN otFoundExc eption, Im ageNearLin eException | |
710 | { | |
711 | getL ogger().in fo("Gettin g Local Im age '" + i mageUrn.to String() + "' from s ource."); | |
712 | ||
713 | Inpu tStream im ageStream = null; | |
714 | try | |
715 | { | |
716 | ImageS treamRespo nse stream Response = streamIma geFromData SourceWith outCache(i mageUrn, g etRequeste dFormatQua lity()); | |
717 | ||
718 | if(get MetadataCa llback() ! = null) | |
719 | { | |
720 | getMetad ataCallbac k().imageM etadata(st reamRespon se.getProv idedImageC hecksum(), | |
721 | streamResp onse.getIm ageFormat( ), 0, stre amResponse .getImageQ uality()); | |
722 | } | |
723 | ||
724 | Transa ctionConte xt transac tionContex t = Transa ctionConte xtFactory. get(); | |
725 | ||
726 | if ((t ransaction Context.ge tHttpServl etRequestM ethod() != null) && transactio nContext.g etHttpServ letRequest Method().e quals("HEA D")) | |
727 | { | |
728 | return n ew Long(0) ; | |
729 | } | |
730 | ||
731 | getLog ger().info ("Pumping response t o client ( bypassing cache)"); | |
732 | ByteSt reamPump p ump = Byte StreamPump .getByteSt reamPump(B yteStreamP ump.TRANSF ER_TYPE.Ne tworkToNet work); | |
733 | // if the cacheS tream is n ull the By teStreamPu mp will ig nore it | |
734 | imageS tream = st reamRespon se.getImag eStream(). getInputSt ream(); | |
735 | long b ytesReturn ed = pump. xfer(image Stream, ou tStream); | |
736 | return new Long( bytesRetur ned);// ne w ImageMet adata(imag eUrn, stre amResponse .getImageF ormat(), n ull, bytes Returned, bytesRetur ned); | |
737 | } | |
738 | catc h (IOExcep tion ioX) | |
739 | { | |
740 | getLog ger().erro r(ioX); | |
741 | throw new Method Exception( ioX); | |
742 | } | |
743 | catc h (ImageNo tFoundExce ption e) | |
744 | { | |
745 | throw e; | |
746 | } | |
747 | catc h(ImageNea rLineExcep tion inlX) | |
748 | { | |
749 | schedu leRequestO fNearlineI mage(); | |
750 | throw inlX; | |
751 | } | |
752 | fina lly | |
753 | { | |
754 | if(ima geStream ! = null) | |
755 | { | |
756 | try{imag eStream.cl ose();} | |
757 | catch(IO Exception ioX){getLo gger().war n(ioX);} | |
758 | } | |
759 | } | |
760 | } | |
761 | ||
762 | /* * | |
763 | * Schedule a subseque nt request of an ima ge after a near-line exception has occur red. A ne ar-line ex ception | |
764 | * implies t he image i s not curr ently avai lable but will be sh ortly. Cal ling this function c reates a n ew | |
765 | * prefetch request fo r the imag e and sche dules it t o execute after 1 mi nute at wh ich point the hope i s the | |
766 | * image is available from the d atasource. Because a prefetch command is used, thi s will onl y be attem pted | |
767 | * once. | |
768 | * / | |
769 | pr ivate void scheduleR equestOfNe arlineImag e() | |
770 | { | |
771 | try | |
772 | { | |
773 | getLog ger().info ("Image '" + getImag eUrn().toS tring() + "' returne d nearline , requesti ng image a gain in " + prefetch ImageRetry DelayMinut es + " min ute"); | |
774 | Imagin gContext.g etRouter() .prefetchI nstanceByI mageUrnDel ayOneMinut e(getImage Urn(), | |
775 | getReque stedFormat Quality()) ; | |
776 | /* | |
777 | Comman d<java.lan g.Void> cm d = | |
778 | getComma ndContext( ).getComma ndFactory( ).createCo mmand(null , | |
779 | "PrefetchI nstanceByI mageUrnCom mand", new Object[] {getImageU rn(), getR equestedFo rmatQualit y()}); | |
780 | Calend ar now = C alendar.ge tInstance( ); | |
781 | now.ad d(Calendar .MINUTE, p refetchIma geRetryDel ayMinutes) ; // set t o request again in 1 minute | |
782 | cmd.se tAccessibi lityDate(n ow.getTime ()); | |
783 | cmd.se tPriority( ScheduledP riorityQue ueElement. Priority.N ORMAL.ordi nal()); | |
784 | getCom mandContex t().getRou ter().doAs ynchronous ly(cmd); | |
785 | */ | |
786 | } | |
787 | catc h(Exceptio n ex) | |
788 | { | |
789 | // jus t in case. .. | |
790 | getLog ger().erro r("Error s cheduling request of nearline image", ex ); | |
791 | } | |
792 | } | |
793 | } |
Araxis Merge (but not the data content of this report) is Copyright © 1993-2016 Araxis Ltd (www.araxis.com). All rights reserved.