From d38b1e9610db7b6b84c2830a004e7032b04b1a0b Mon Sep 17 00:00:00 2001 From: Martin Ritchie Date: Tue, 31 Jul 2007 15:53:37 +0000 Subject: Merged revisions 1-447993,447995-448007,448009-448141,448143-448157,448161-448194,448196-448210,448212-448218,448220-448223,448225-448233,448235,448237-448241,448243-448596,448598-448623,448625-448850,448852-448880,448882-448982,448984-449635,449637-449639,449641-449642,449644-449645,449647-449674,449676-449719,449721-449749,449751-449762,449764-449933,449935-449941,449943-450383,450385,450387-450400,450402-450433,450435-450503,450505-450555,450557-450860,450862-451024,451026-451149,451151-451316,451318-451931,451933-452139,452141-452162,452164-452320,452322,452324-452325,452327-452333,452335-452429,452431-452528,452530-452545,452547-453192,453194-453195,453197-453536,453538,453540-453656,453658-454676,454678-454735,454737,454739-454781,454783-462728,462730-462819,462821-462833,462835-462839,462841-463071,463073-463178,463180-463308,463310-463362,463364-463375,463377-463396,463398-463402,463404-463409,463411-463661,463663-463670,463672-463673,463675-464493,464495-464502,464504-464576,464578-464613,464615-464628,464630,464632-464866,464868-464899,464901-464942,464944-464949,464951-465004,465006-465016,465018-465053,465055-465165,465167-465321,465323-465406,465408-465427,465429-465431,465433-465548,465550-466044,466047-466075,466077,466079-466081,466083-466099,466101-466112,466114-466126,466128-466240,466242-466971,466973-466978,466980-467309,467311-467312,467316-467328,467330-467485,467487-467588,467590-467604,467606-467699,467701-467706,467708-467749,467751-468069,468071-468537,468539-469241,469244-469246,469248-469318,469320-469421,469423,469425-469429,469431-469435,469437-469462,469464-469469,469472-469477,469479-469490,469492-469503,469505-469529,469531-469598,469600-469624,469626-469737,469739-469752,469754-469806,469808-469928,469930-469953,469955-470011,470013-470109,470111-470335,470338-470339,470341-470379,470381,470383-470399,470401-470446,470448-470741,470743-470758,470760-470809,470811-470817,470819-470993,470995-471001,471003-471788,471790-471792,471794-472028,472030-472032,472034-472036,472038,472040,472043,472045-472059,472061,472063,472065-472066,472068,472070-472072,472074-472080,472082,472084-472092,472094-472107,472109-472123,472125-472158,472160-472165,472167-472172,472174-472457,472459-472460,472462-472464,472466-472470,472472-472483,472486-472491,472493-472494,472496-472497,472499,472501-472503,472505-472512,472514-472544,472546-472556,472558-472560,472562-472572,472574-472587,472589-472591,472593-472605,472607,472609-472731,472733-472786,472788-472843,472845-472849,472851-472859,472861-472878,472880-472903,472905,472907-472988,472990-472991,472993-473071,473073-473086,473088-473090,473093,473095-473096,473098-473106,473108-473110,473112-473185,473187-473260,473262,473268-473270,473275-473279,473281,473284-473287,473289-473295,473297-473306,473308-473330,473332-473335,473337,473339-473344,473346-473351,473353-473355,473357-473358,473361-473471,473473-473497,473499-473535,473537-473567,473569-473888,473890-474451,474454-474492,474494-474563,474565-474843,474845-474865,474867-474932,474934-475035,475037-475144,475146-475180,475182-475265,475267-475285,475287,475289-475293,475295-475296,475298-475302,475304-475631,475633-475649,475651-475748,475750-475752,475754-476107,476109-476302,476304-476413,476415-476430,476432-476700,476702-476868,476870-477147,477149-477213,477215-477263,477265-477340,477342-477635,477637-477789,477791-477825,477827-477841,477843,477846-477852,477854,477856,477858-477865,477867-477894,477896-478022,478024-478182,478184-478211,478213-478233,478235-478236,478238-478241,478243-478252,478254-478259,478261-478263,478265,478267-478269,478271-478286,478288-478342,478344-478379,478381-478412,478414-478443,478445-478636,478639-478658,478660-478821,478823-478853,478855-478922,478924-478962,478965-478974,478976-479029,479031-479049,479051-479210,479212-479214,479216-479407,479409-479415,479417-479425,479427-479559,479561-479639,479641-479676,479678-479685,479687-480030,480033-480086,480091-480093,480095-480118,480120-480139,480141,480143-480148,480150-480156,480158-480163,480165-480177,480179-480189,480191-480193,480195-480198,480200-480220,480222-480282,480284-480292,480294-480308,480310-480317,480320-480422,480424,480426-480581,480583-480656,480658-480692,480695-480702,480704,480706-480710,480712-480910,480913-480933,480935-480945,480947-480972,480974-480993,480995-481034,481036-481158,481161-481174,481176-481220,481222-481234,481236-481260,481263-481264,481266-481296,481298-481304,481306-481311,481313-481332,481334,481336-481380,481382-481441,481443-482144,482146-482180,482182-482193,482195-482232,482234-482236,482239,482241-482242,482244-482247,482250-482251,482253,482256-482261,482264-482288,482290-482364,482366,482368,482370-482554,482556,482558-482569,482572-482636,482638,482640-482696,482698-482722,482724-482732,482734-482771,482774-482957,482959-483045,483047-483105,483108,483110-483115,483117,483119-483127,483130-483134,483136-483148,483150-483158,483160-483164,483166-483178,483180-483391,483393-483400,483402-483403,483405-483418,483420-483421,483425-483436,483438-483470,483472-483502,483504-483558,483560-483599,483601-483637,483639-483644,483646-483659,483661-483670,483672-483878,483880-483910,483912-483915,483917-483940,483942,483944-483968,483970-483972,483974-483976,483978,483980-484612,484614-484657,484659-484693,484695-484718,484720-484842,484844-484847,484849-484986,484988-485019,485021-485489,485491-485544,485546-485591,485593,485595-485697,485699-485729,485731-485734,485736-485779,485781-485787,485789-485851,485853,485855-486007,486009,486011-486020,486022-486083,486085-486097,486099-486117,486120-486131,486133-486148,486150-486161,486163-486164,486166-486197,486199-486205,486208-486247,486249-486253,486256-486427,486429-486431,486433-486554,486556-486573,486575-486593,486595,486597-486609,486611-486619,486622,486625,486627-486641,486643-486645,486649-486687,486689-486721,486723-486730,486732-486746,486748-486759,486761,486763-486777,486779-486782,486784-486788,486790,486792,486794-486796,486798-487175,487178,487180-487213,487215,487217-487267,487269-487284,487286-487298,487300-487358,487360-487367,487369-487382,487384-487434,487436-487480,487482-487547,487549-487561,487563-487565,487567-487578,487580-487615,487617-487622,487624,487626,487628,487630-487635,487637-487703,487705-487777,487780-487781,487783-487800,487802-487803,487805-487820,487822-487848,487850-487902,487904-488103,488105-488133,488135-488158,488160-488163,488165-488187,488189-488216,488218-488248,488250-488278,488280,488282-488303,488305-488313,488315-488342,488344-488351,488353-488376,488378-488449,488451-488593,488595,488597-488623,488625-488700,488702-488704,488706-488710,488714,488716-488725,488727-488744,488746-488770,488772-488798,488800,488802-488807,488809,488811-488829,488831-488843,488845-488851,488853-489069,489071-489077,489079-489081,489084-489102,489104-489105,489107-489109,489111-489112,489114-489139,489141-489178,489181-489203,489205-489211,489213,489216-489329,489332-489402,489404-489417,489419-489421,489423-489643,489645-489690,489692-489703,489705-489714,489716-489747,489749-489753,489755-489803,489805-489904,489906-490372,490374-490504,490506-490604,490606-490707,490710-490733,490735-490871,490873-490984,490986-491028,491030,491032-491071,491073-491119,491121-491576,491578-491672,491674-491800,491802-491838,491840-491878,491880-492183,492185-492279,492281-492317,492319-492513,492515-492584,492586-492587,492589-492601,492603-492635,492637-492640,492642-492717,492719-492723,492725-492729,492731-492755,492757-492901,492903-492955,492957-492962,492964-492997,492999-493002,493004-493041,493043-493059,493062-493063,493065-493086,493088-493125,493127-493139,493141-493150,493152-493871,493873-494017,494019-494030,494032-494041,494043-494091,494093-494120,494122-494354,494356-494436,494438-494539,494541-494552,494554-494586,494588-494649,494651,494653-494654,494656-494657,494659-494764,494766-494768,494770-494796,494798-494799,494802,494804-494860,494862-494903,494905-494906,494908-495019,495021-495160,495162-495168,495171-495188,495190-495229,495231-495254,495256-495303,495305-495313,495315-495336,495338-495372,495374-495379,495381-495454,495457-495459,495462-495516,495518-495524,495526-495531,495533-495548,495551-495553,495555,495557-495558,495560,495562-495573,495575-495583,495585-495594,495596-495628,495630-495638,495640-495651,495653-495660,495662-495753,495755-496259,496261-496262,496264-496269,496271-496275,496277-496301,496303-496316,496318-496383,496385-496413,496415-496495,496497-496625,496627-496636,496638-496640,496642-496647,496650-496657,496659-496660,496663-496664,496666-496677,496679-496681,496683-496730,496732-496750,496752,496754-496784,496786-496832,496834-496840,496842-496990,496992-496995,496997-497340,497343-497351,497353-497403,497405-497424,497426-497438,497440-497481,497483-497497,497499-497765,497767-497769,497771-497775,497777-497778,497780,497782-497783,497785,497787-497812,497814-497871,497873-497877,497879-498573,498575-498588,498590,498592,498594-498636,498638-498669,498671-498686,498688-498689,498691-498719,498721-498964,498966-498969,498971-498973,498975-498982,498985-499035,499037-499040,499042,499044-499048,499050-499082,499084-499086,499088-499164,499167-499169,499171-499355,499357-499370,499372-499373,499375-499391,499393,499395-499425,499428,499430-499445,499447-499455,499457-499460,499462-499465,499467,499469-499489,499491-499492,499494-499531,499533-499562,499566-499627,499629-499715,499717-499732,499734-499755,499758-499763,499765-499780,499782-499795,499797-499802,499804-499844,499846,499848-499850,499852-499863,499865-499873,499875-499974,499976-499978,499980-500263,500265-500283,500285-500309,500311-501000,501002,501012-501057,501059-501095,501097-501390,501392-501410,501413-501447,501449-501454,501456,501458-501464,501466-501471,501473-501803,501805-501913,501915-501916,501918-501919,501921-501944,501946-502171,502173-502177,502181,502183-502247,502250-502252,502254-502260,502262-502267,502270,502272,502274-502575,502577-502609,502611-502619,502621-502626,502628-502654,502656-503592,503594-503603,503605-503608,503610-503636,503638-503645,503647-503705,503707-503789,503791-504024,504026-504111,504113-504506,504508-504735,504737-504863,504865-504867,504869-504914,504916-505241,505243-505254,505257-505267,505269-505354,505356-505891,505893-505971,505973-506400,506402-506404,506407-506438,506440-506516,506518-506541,506543-506966,506968-506971,506973-507095,507097-507108,507111-507454,507456,507459-507471,507473-507556,507558,507560-507581,507585-507594,507597,507599-507608,507610-507728,507730-507893,507895-507937,507940-508234,508236-508350,508352-508365,508367-508380,508383,508386-508415,508417-508648,508650-508941,508943-509146,509148-509171,509173-509175,509179-509201,509203-509207,509209-509215,509217-509222,509224-509477,509480-509627,509629-509634,509636-509641,509643-509736,509738-509931,509933-510059,510061-510075,510077-510158,510161-510896,510898-510938,510940-511388,511390-511922,511924-512287,512289-512698,512702-512813,512815-512817,512819-513359,513361-513370,513372-514702,514704-514886,514888-514902,514904-515126,515129-515141,515143-515516,515518-515534,515536-515538,515540-515648,515650-515651,515653-516070,516072-516411,516413-516448,516450,516452-517637,517639-517647,517649-517659,517661-517663,517665-517677,517679-517682,517684-517744,517746-518085,518087-518175,518177-518558,518560-518568,518571-518666,518668,518670-518699,518701-518987,518990-518992,518994-519908,519910-519932,519934-520414,520416-520842,520844-520937,520939-521362,521364-521681,521683-521704,521706-521709,521711-521714,521716-521781,521783-521792,521794-522462,522464-522527,522529-522534,522536-522566,522568-522958,522960,522962-522966,522968-522976,522978-522980,522982-522988,522992-522993,522995-523244,523246-523746,523748-524049,524051-524738,524741-524742,524744-524762,524764,524766,524768-525486,525488-525530,525532,525534,525537-525552,525554-525765,525767-525776,525778-525784,525789-525803,525805-525816,525818-525828,525830-525861,525863-525866,525868-526090,526092-526112,526114-526116,526119-526121,526123-526149,526151-526153,526155-526156,526160-526165,526167-526186,526188-526193,526196-526197,526200-526665,526667-526682,526686-526690,526693,526695-526708,526710-526713,526715-526775,526777-526802,526804-526806,526808-527048,527051-527052,527054-527181,527183-527486,527488-527492,527494-527498,527500-527508,527510-527517,527519-527536,527538-527555,527559-527802,527804-527842,527844-527847,527849-527875,527877-527940,527942-527958,527960-527971,527973-528002,528004,528006-528423,528425-529232,529234-529245,529247-529296,529298-529634,529636-529658,529660-529665,529667-529668,529670-530033,530035-530036,530038-530040,530045-530046,530050-530051,530053-530431,530433-530436,530439-530440,530443,530445-530446,530448,530450-530682,530684,530687-530696,530698-530733,530735-530776,530778-530795,530799,530801-530811,530813-530818,530820-530837,530839-531436,531438-531455,531457,531459-531511,531514,531516,531519-531523,531525,531528-531858,531860-531864,531866-531907,531909-531916,531918-531936,531938-531988,531990-532001,532003-532371,532373-532465,532467-532727,532729-532765,532767-532785,532788-532790,532792-532793,532795-533064,533066-533074,533076,533080-533130,533132-533139,533142-533703,533705-533720,533722-533763,533766-533818,533820-533839,533841-533859,533862-534035,534037-534112,534114-534116,534118-534472,534474-534477,534479-534762,534764-534896,534898-534902,534904-535253,535255-535308,535310-535808,535810-535873,535875-536007,536009-536140,536142-536162,536165-536242,536244-536252,536254-536278,536280-536338,536340-536448,536450-536479,536481-536482,536484-536485,536487-536495,536497,536500-536505,536507-536561,536563-536570,536572,536574-536583,536586-536823,536825-537014,537016-537018,537020-537025,537027-537028,537030-537160,537162-537170,537172-537672,537674-537781,537783-537833,537836-537840,537842-537844,537846-537953,537955-538034,538036-538078,538080-538083,538085-538097,538099-538108,538110-538239,538241-538881,538883-538906,538908-538911,538913-538921,538923-539177,539179-539190,539192-539469,539471-539475,539477-539480,539482-539483,539485-539500,539502-539593,539595-539782,539784-539787,539789-540106,540108-540168,540170-540510,540512-541246,541248-542483,542485-542788,542790-543495,543497-544108,544110-544421,544423-544507,544509-544865,544867-545145,545147-546095,546097-546189,546191-546440,546442-546457,546459-547177,547179-547626,547628-548275,548277-548278,548280-548301,548303-548307,548309-548311,548313-548314,548316,548318,548320-548380,548382-549010,549012-549529,549531-549848,549850-550508,550510-550747,550749-550772,550774-550848,550850-551116,551122-553446,553448-561282 via svnmerge from https://svn.apache.org/repos/asf/incubator/qpid/branches/M2 ........ r541920 | tomasr | 2007-05-26 18:35:51 +0100 (Sat, 26 May 2007) | 1 line QPID-136 Initial Prefetch Implementation ........ r549112 | arnaudsimon | 2007-06-20 15:11:03 +0100 (Wed, 20 Jun 2007) | 1 line changed setText to use UTF8 as default encoder ........ r551167 | arnaudsimon | 2007-06-27 15:08:50 +0100 (Wed, 27 Jun 2007) | 1 line added public void declareAndBind(AMQDestination amqd) ........ r551174 | ritchiem | 2007-06-27 15:23:21 +0100 (Wed, 27 Jun 2007) | 3 lines Caused each of these tests to run 10 times to help identify any race conditions that were occuring. Updated the CommitRollbackTest to be more robust in the detection of failure. ........ r551175 | ritchiem | 2007-06-27 15:23:52 +0100 (Wed, 27 Jun 2007) | 1 line Allowed more of the constants to be set via system properties. ........ r551176 | ritchiem | 2007-06-27 15:25:13 +0100 (Wed, 27 Jun 2007) | 1 line renamed the passwd programme qpid-passwd to match the change in bin directory. ........ r552441 | rupertlssmith | 2007-07-02 10:23:54 +0100 (Mon, 02 Jul 2007) | 1 line Added log4j as slfj logger for perftests. ........ r552499 | rupertlssmith | 2007-07-02 15:17:45 +0100 (Mon, 02 Jul 2007) | 1 line Added some documentation. ........ r553172 | rupertlssmith | 2007-07-04 12:11:04 +0100 (Wed, 04 Jul 2007) | 1 line Messages moved by management console now commited on the message store. ........ r553248 | ritchiem | 2007-07-04 17:05:55 +0100 (Wed, 04 Jul 2007) | 6 lines Addition of the MessageStore Tool. Small changes to the Exchanges to allow the extraction of currently listed items. Extracted initial broker configuration mechanism to a reusable class. Have modified broker to use it. Move the Passwd.java to new tools package structure on the broker. ........ r553265 | ritchiem | 2007-07-04 17:42:59 +0100 (Wed, 04 Jul 2007) | 1 line Tidied up some extranious logging. ........ r553432 | rupertlssmith | 2007-07-05 10:28:33 +0100 (Thu, 05 Jul 2007) | 1 line Fixed test state carrying over to mandatory message test from immediate. Also added in-vm clean up to other tests. ........ r553480 | ritchiem | 2007-07-05 13:40:50 +0100 (Thu, 05 Jul 2007) | 2 lines Minor changes and tidy up when running via command line. Added Copy command. ........ r553482 | ritchiem | 2007-07-05 13:44:42 +0100 (Thu, 05 Jul 2007) | 2 lines Forgot to compile before committing. Missed a method change in the Select command. ........ r554964 | rupertlssmith | 2007-07-10 15:40:04 +0100 (Tue, 10 Jul 2007) | 1 line Added message copy method. ........ r555249 | rupertlssmith | 2007-07-11 12:52:39 +0100 (Wed, 11 Jul 2007) | 1 line Update perftests to center better around current performance. ........ r556011 | rupertlssmith | 2007-07-13 15:24:03 +0100 (Fri, 13 Jul 2007) | 1 line Moved test framework into its own package and cleaned it up. ........ r556024 | rupertlssmith | 2007-07-13 16:02:06 +0100 (Fri, 13 Jul 2007) | 1 line Completed javadoc for test framework. ........ r556628 | rgodfrey | 2007-07-16 14:50:57 +0100 (Mon, 16 Jul 2007) | 1 line QPID-537 : Make AMQMessage.incrementReference public ........ r556675 | cctrieloff | 2007-07-16 18:36:21 +0100 (Mon, 16 Jul 2007) | 2 lines added notice entries ........ r556680 | cctrieloff | 2007-07-16 18:56:40 +0100 (Mon, 16 Jul 2007) | 2 lines clean up ........ r556682 | cctrieloff | 2007-07-16 18:58:37 +0100 (Mon, 16 Jul 2007) | 2 lines removed optional cppunit as not in distributed packages ........ r556845 | ritchiem | 2007-07-17 09:26:33 +0100 (Tue, 17 Jul 2007) | 3 lines Additional logging in case of broker failure at startup. Use broker logger at error level as well as System.out ........ r556847 | ritchiem | 2007-07-17 09:35:35 +0100 (Tue, 17 Jul 2007) | 3 lines Update to the MessageStore Tool to provide Move and Purge functionality. Updated to remove the AMQExceptions that will be removed from the Exchange class. ........ r556861 | ritchiem | 2007-07-17 10:26:47 +0100 (Tue, 17 Jul 2007) | 2 lines QPID-538 Check to ensure a duplicate binding is not created. ........ r556868 | ritchiem | 2007-07-17 10:55:56 +0100 (Tue, 17 Jul 2007) | 1 line Addition of simple pub/sub examples. ........ r556869 | ritchiem | 2007-07-17 10:56:17 +0100 (Tue, 17 Jul 2007) | 1 line QPID-540 Prevent NPE when purging message from the main _message queue in the ConcurrentSelectorDeliveryManager that have been delivered via a Subscribers _messageQueue. Ensuring that any expired messages are still correctly handled. i.e. the Queue size/depth is reduced and the message correctly dequeued from the underlying store. ........ r556871 | ritchiem | 2007-07-17 10:57:35 +0100 (Tue, 17 Jul 2007) | 1 line White space & code formatting change ........ r556872 | ritchiem | 2007-07-17 10:58:35 +0100 (Tue, 17 Jul 2007) | 3 lines Added additional information to hard-error logging in exceptionReceived. Fully expanded imports ........ r556888 | ritchiem | 2007-07-17 12:33:08 +0100 (Tue, 17 Jul 2007) | 1 line Change to allow the management port to be specified on the command line, via -m or --mport ........ r556890 | ritchiem | 2007-07-17 12:38:10 +0100 (Tue, 17 Jul 2007) | 4 lines QPID-541 A large portion of memory was being wasted in 32k ByteBuffers being held by the AMQShortStrings. Patch submitted by Robert Godfrey to intern() the AMQSSs to reduce memory usage. Current implementation *will* impact performance due to the usage of a static Map for storage. However, a thread local implementation is in the works. ........ r556898 | rgodfrey | 2007-07-17 13:00:57 +0100 (Tue, 17 Jul 2007) | 1 line QPID-541 : Change to use threadlocal maps for intern for the common case to avoid excessive synchronization. In the uncommon case will require more lookup. ........ r556958 | rupertlssmith | 2007-07-17 17:22:16 +0100 (Tue, 17 Jul 2007) | 1 line Refactored the distributed test clients and coordinator to support different distribution and sequencing engines. ........ r556967 | rupertlssmith | 2007-07-17 17:40:14 +0100 (Tue, 17 Jul 2007) | 1 line Removed unused package. ........ r556968 | rupertlssmith | 2007-07-17 17:42:00 +0100 (Tue, 17 Jul 2007) | 1 line Retired old interop tests. ........ r556969 | rupertlssmith | 2007-07-17 17:43:49 +0100 (Tue, 17 Jul 2007) | 1 line Properties file not needed any more. Test properties all driven from MessagingTestConfigProperties. ........ r557276 | ritchiem | 2007-07-18 15:36:11 +0100 (Wed, 18 Jul 2007) | 1 line Updates to pom files and Licensing/Notice files for M2 release. ........ r557279 | ritchiem | 2007-07-18 15:51:42 +0100 (Wed, 18 Jul 2007) | 1 line This is left over from ANT ........ r557281 | ritchiem | 2007-07-18 15:54:06 +0100 (Wed, 18 Jul 2007) | 1 line updated comment to refelect property values ........ r557286 | ritchiem | 2007-07-18 16:02:22 +0100 (Wed, 18 Jul 2007) | 1 line Set default mvn build to assembly:assembly ........ r557288 | ritchiem | 2007-07-18 16:09:07 +0100 (Wed, 18 Jul 2007) | 1 line Ensure the top level release-docs directory is included in the builds ........ r557306 | ritchiem | 2007-07-18 17:01:58 +0100 (Wed, 18 Jul 2007) | 1 line Update fix incorrect license headers. ........ r557312 | ritchiem | 2007-07-18 17:07:01 +0100 (Wed, 18 Jul 2007) | 1 line added license ........ r557314 | ritchiem | 2007-07-18 17:11:17 +0100 (Wed, 18 Jul 2007) | 1 line added license ........ r557452 | aconway | 2007-07-19 03:03:02 +0100 (Thu, 19 Jul 2007) | 14 lines * lib/broker/Daemon.cpp, .h - Rewrote to remove libdaemon dependency. - PID file stored in /var/run if root, /tmp otherwise. * src/qpidd.cpp: Use new Daemon.cpp. - lock files stored in /var/run (for root) or /tmp. - updated to trunk daemon flag behavior. * lib/broker/Makefile.am (libqpidbroker_la_LIBADD): - Daemon.cpp now needs -lboost_iostreams * NOTICE, README: Removed mention of libdaemon. ........ r558027 | ritchiem | 2007-07-20 17:08:05 +0100 (Fri, 20 Jul 2007) | 1 line Added a logger but only used to control the toString inclusion of password. If in debug mode it will include password otherwise the password is "********". ........ r558072 | astitcher | 2007-07-20 18:49:41 +0100 (Fri, 20 Jul 2007) | 2 lines Fixed the license from the "old" apache copyright notice ........ r558083 | aconway | 2007-07-20 19:29:08 +0100 (Fri, 20 Jul 2007) | 2 lines Remove -ldaemon, we no longer require libdaemon. ........ r558099 | aconway | 2007-07-20 20:20:01 +0100 (Fri, 20 Jul 2007) | 2 lines Ignore QPID_ env variables that don't correspond to known options. ........ r558108 | cctrieloff | 2007-07-20 20:55:40 +0100 (Fri, 20 Jul 2007) | 2 lines typo fix ........ r558114 | rajith | 2007-07-20 21:11:03 +0100 (Fri, 20 Jul 2007) | 1 line added release notes ........ r558115 | rajith | 2007-07-20 21:12:20 +0100 (Fri, 20 Jul 2007) | 1 line Checking in the release notes ........ r558116 | aconway | 2007-07-20 21:16:20 +0100 (Fri, 20 Jul 2007) | 3 lines Removed .txt from RELEASE_NOTES Added RELEASE_NOTES to EXTRA_DIST in Makefile.am ........ r558168 | rajith | 2007-07-20 23:03:42 +0100 (Fri, 20 Jul 2007) | 1 line added release notes ........ r558170 | rajith | 2007-07-20 23:04:11 +0100 (Fri, 20 Jul 2007) | 1 line added release notes ........ r558630 | gsim | 2007-07-23 08:21:49 +0100 (Mon, 23 Jul 2007) | 3 lines Revised release notes: removed bug fixed on this branch, removed outstanding feature lists as it is not terribly accurate or helpful. ........ r559419 | rupertlssmith | 2007-07-25 13:17:59 +0100 (Wed, 25 Jul 2007) | 1 line Refactored interop tests into general distributed test framework. Moved framework under systests from integrationtests. ........ r559427 | ritchiem | 2007-07-25 13:40:24 +0100 (Wed, 25 Jul 2007) | 2 lines AMQMessage - added //todo-s and removed unused parameter StoreContext from expired() method call. ConcurrentSelectorDeliveryManager - Update to reflect expired() call change. Created new _reaperContextStore to be used when performing reaper operations such as message dequeue due to expiration. Removed old commented code. ........ r559455 | rupertlssmith | 2007-07-25 14:40:16 +0100 (Wed, 25 Jul 2007) | 1 line Added to comments. ........ r559456 | rupertlssmith | 2007-07-25 14:41:21 +0100 (Wed, 25 Jul 2007) | 1 line Removed redundant method. ........ r559458 | rupertlssmith | 2007-07-25 14:57:21 +0100 (Wed, 25 Jul 2007) | 1 line Refactored packaging of test framework. ........ r559461 | rupertlssmith | 2007-07-25 15:00:16 +0100 (Wed, 25 Jul 2007) | 1 line Removed redundant packages. ........ r559943 | rhs | 2007-07-26 20:15:17 +0100 (Thu, 26 Jul 2007) | 1 line adding missing ack ........ r559944 | rhs | 2007-07-26 20:15:44 +0100 (Thu, 26 Jul 2007) | 1 line removed old script ........ r560198 | ritchiem | 2007-07-27 12:30:34 +0100 (Fri, 27 Jul 2007) | 1 line Added files to ignore list ........ r560225 | ritchiem | 2007-07-27 14:33:50 +0100 (Fri, 27 Jul 2007) | 1 line Converted namespaces from Qpid.* to Apache.Qpid.* ........ r560471 | tomasr | 2007-07-28 03:35:41 +0100 (Sat, 28 Jul 2007) | 1 line Removed using directives causing compilation failure in .NET 1.1 ........ r561278 | ritchiem | 2007-07-31 10:07:57 +0100 (Tue, 31 Jul 2007) | 8 lines Changes to POMs. Client pom now builds a single jar with all dependancies included in the single bundle. systests/pom.xml adjusted to include only *Test.class items. This will fix the current Error on OptOutTestCase management/eclipse-plugin/pom.xml - editied to include there required MANIFEST.MF to identify plugin to eclipse distribution/src/main/assembly/management-eclipse-plugin.xml editied to include there required MANIFEST.MF to identify the plugin distribution/pom.xml - white space Also updated log4j.xml default to create an alert.log file from the AMQQueue alerting. Added a debug.log4j.xml that gives example of debugging the broker via log4j. ........ git-svn-id: https://svn.apache.org/repos/asf/incubator/qpid/trunk/qpid@561365 13f79535-47bb-0310-9956-ffa450edef68 --- java/broker/bin/msTool.sh | 56 ++ java/broker/bin/qpid-passwd | 2 +- java/broker/bin/qpid-server | 6 +- .../distribution/src/main/assembly/broker-bin.xml | 4 +- java/broker/etc/debug.log4j.xml | 114 +++ java/broker/etc/log4j.xml | 36 +- java/broker/etc/messagestoretool-log4j.xml | 53 ++ java/broker/etc/mstool-log4j.xml | 54 ++ java/broker/pom.xml | 19 + .../apache/log4j/QpidCompositeRollingAppender.java | 3 - .../apache/qpid/configuration/Configuration.java | 188 +++++ .../java/org/apache/qpid/server/AMQChannel.java | 10 +- .../src/main/java/org/apache/qpid/server/Main.java | 56 +- .../qpid/server/exchange/AbstractExchange.java | 6 + .../server/exchange/DefaultExchangeRegistry.java | 19 +- .../qpid/server/exchange/DestNameExchange.java | 11 +- .../qpid/server/exchange/DestWildExchange.java | 21 +- .../org/apache/qpid/server/exchange/Exchange.java | 28 +- .../qpid/server/exchange/ExchangeRegistry.java | 4 + .../qpid/server/exchange/FanoutExchange.java | 29 +- .../qpid/server/exchange/HeadersExchange.java | 61 +- .../server/handler/BasicConsumeMethodHandler.java | 18 +- .../server/handler/BasicPublishMethodHandler.java | 10 + .../handler/ConnectionStartOkMethodHandler.java | 3 +- .../qpid/server/handler/ExchangeBoundHandler.java | 25 +- .../server/handler/ExchangeDeclareHandler.java | 4 +- .../qpid/server/handler/QueueBindHandler.java | 17 +- .../qpid/server/handler/QueueDeclareHandler.java | 7 + .../management/JMXManagedObjectRegistry.java | 44 +- .../management/MBeanInvocationHandlerImpl.java | 25 +- .../server/protocol/AMQPFastProtocolHandler.java | 28 +- .../org/apache/qpid/server/queue/AMQMessage.java | 16 +- .../org/apache/qpid/server/queue/AMQQueue.java | 250 +++++- .../apache/qpid/server/queue/AMQQueueMBean.java | 66 +- .../queue/ConcurrentSelectorDeliveryManager.java | 109 +-- .../qpid/server/queue/DefaultQueueRegistry.java | 17 +- .../apache/qpid/server/queue/ExchangeBindings.java | 13 +- .../apache/qpid/server/queue/MessageMetaData.java | 24 +- .../qpid/server/queue/NotificationCheck.java | 25 +- .../server/queue/QueueNotificationListener.java | 26 +- .../apache/qpid/server/queue/QueueRegistry.java | 6 + .../qpid/server/queue/TransientMessageData.java | 25 +- .../org/apache/qpid/server/security/Passwd.java | 81 -- .../qpid/server/txn/NonTransactionalContext.java | 25 +- .../qpid/server/txn/TransactionalContext.java | 124 ++- .../qpid/server/virtualhost/VirtualHost.java | 262 ++++++ .../qpid/tools/messagestore/MessageStoreTool.java | 648 +++++++++++++++ .../messagestore/commands/AbstractCommand.java | 66 ++ .../qpid/tools/messagestore/commands/Clear.java | 85 ++ .../qpid/tools/messagestore/commands/Command.java | 36 + .../qpid/tools/messagestore/commands/Copy.java | 56 ++ .../qpid/tools/messagestore/commands/Dump.java | 299 +++++++ .../qpid/tools/messagestore/commands/Help.java | 98 +++ .../qpid/tools/messagestore/commands/List.java | 314 +++++++ .../qpid/tools/messagestore/commands/Load.java | 94 +++ .../qpid/tools/messagestore/commands/Move.java | 166 ++++ .../qpid/tools/messagestore/commands/Purge.java | 68 ++ .../qpid/tools/messagestore/commands/Quit.java | 54 ++ .../qpid/tools/messagestore/commands/Select.java | 233 ++++++ .../qpid/tools/messagestore/commands/Show.java | 513 ++++++++++++ .../org/apache/qpid/tools/security/Passwd.java | 81 ++ .../org/apache/qpid/tools/utils/CommandParser.java | 51 ++ .../java/org/apache/qpid/tools/utils/Console.java | 90 ++ .../qpid/tools/utils/SimpleCommandParser.java | 121 +++ .../org/apache/qpid/tools/utils/SimpleConsole.java | 363 +++++++++ .../qpid/tools/utils/utils/CommandParser.java | 51 ++ .../org/apache/qpid/tools/utils/utils/Console.java | 75 ++ .../qpid/tools/utils/utils/RSHCommandParser.java | 352 ++++++++ .../tools/utils/utils/SimpleCommandParser.java | 116 +++ .../qpid/server/exchange/ExchangeMBeanTest.java | 25 +- .../server/protocol/TestMinaProtocolSession.java | 25 +- .../qpid/server/queue/AMQQueueAlertTest.java | 25 +- .../qpid/server/queue/AMQQueueMBeanTest.java | 25 +- .../publisher/MonitorMessageDispatcher.java | 59 +- .../qpid/example/publisher/MonitorPublisher.java | 53 +- .../org/apache/qpid/example/pubsub/Client.java | 72 ++ .../qpid/example/pubsub/ConnectionSetup.java | 123 +++ .../org/apache/qpid/example/pubsub/Publisher.java | 81 ++ .../org/apache/qpid/example/pubsub/Subscriber.java | 98 +++ java/client/pom.xml | 44 + .../java/org/apache/qpid/client/AMQConnection.java | 4 +- .../org/apache/qpid/client/AMQConnectionURL.java | 31 +- .../java/org/apache/qpid/client/AMQSession.java | 10 + .../handler/ExchangeBoundOkMethodHandler.java | 25 +- .../client/handler/QueueDeleteOkMethodHandler.java | 25 +- .../channelclose/CloseWithBlockingReceiveTest.java | 25 +- .../test/unit/client/forwardall/CombinedTest.java | 17 +- .../test/unit/transacted/CommitRollbackTest.java | 118 ++- .../qpid/server/cluster/SimpleBodySendable.java | 25 +- java/common/pom.xml | 26 +- .../org/apache/qpid/framing/AMQShortString.java | 56 ++ .../abstraction/MessagePublishInfoConverter.java | 25 +- .../ProtocolVersionMethodConverter.java | 25 +- .../org/apache/qpid/util/CommandLineParser.java | 14 +- java/distribution/pom.xml | 7 +- java/distribution/src/main/assembly/bin-test.xml | 151 +--- java/distribution/src/main/assembly/bin.xml | 178 +--- .../assembly/management-eclipse-plugin-unix.xml | 39 +- .../main/assembly/management-eclipse-plugin.xml | 68 +- java/distribution/src/main/assembly/src.xml | 42 +- java/distribution/src/main/release/DISCLAIMER | 5 - java/distribution/src/main/release/LICENSE.txt | 203 ----- java/distribution/src/main/release/NOTICE.txt | 36 - java/distribution/src/main/release/README.txt | 104 --- java/etc/coding_standards.xml | 3 +- .../docs/RunningSustainedTests.txt | 14 +- java/integrationtests/pom.xml | 6 +- .../interop/clienttestcases/TestCase1DummyRun.java | 133 +++ .../interop/clienttestcases/TestCase2BasicP2P.java | 207 +++++ .../clienttestcases/TestCase3BasicPubSub.java | 237 ++++++ .../interop/coordinator/CoordinatingTestCase.java | 263 ------ .../qpid/interop/coordinator/Coordinator.java | 388 --------- .../interop/coordinator/InvitingTestDecorator.java | 220 ----- .../coordinator/ListeningCoordinatorTest.java | 28 - .../coordinator/ListeningTestDecorator.java | 200 ----- .../qpid/interop/coordinator/OptOutTestCase.java | 65 -- .../interop/coordinator/TestClientDetails.java | 87 -- .../qpid/interop/coordinator/XMLTestListener.java | 402 --------- .../testcases/CoordinatingTestCase1DummyRun.java | 85 -- .../testcases/CoordinatingTestCase2BasicP2P.java | 90 -- .../CoordinatingTestCase3BasicPubSub.java | 92 --- .../java/org/apache/qpid/interop/old/Listener.java | 291 ------- .../org/apache/qpid/interop/old/Publisher.java | 244 ------ .../qpid/interop/testcases/CircuitTestCase.java | 101 +++ .../testcases/InteropTestCase1DummyRun.java | 84 ++ .../testcases/InteropTestCase2BasicP2P.java | 90 ++ .../testcases/InteropTestCase3BasicPubSub.java | 88 ++ .../interop/testclient/InteropClientTestCase.java | 104 --- .../apache/qpid/interop/testclient/TestClient.java | 422 ---------- .../testclient/testcases/TestCase1DummyRun.java | 96 --- .../testclient/testcases/TestCase2BasicP2P.java | 214 ----- .../testclient/testcases/TestCase3BasicPubSub.java | 249 ------ .../qpid/sustained/SustainedClientTestCase.java | 905 +++++++++++++++++++++ .../apache/qpid/sustained/SustainedTestCase.java | 126 +++ .../apache/qpid/sustained/SustainedTestClient.java | 8 +- .../qpid/sustained/SustainedTestCoordinator.java | 222 ----- .../java/org/apache/qpid/sustained/TestClient.java | 157 ---- .../org/apache/qpid/sustained/TestCoordinator.java | 117 --- .../distributedtesting/InteropClientTestCase.java | 101 +++ .../framework/distributedtesting/TestClient.java | 377 +++++++++ .../org/apache/qpid/util/ClasspathScanner.java | 234 ------ .../org/apache/qpid/util/ConversationFactory.java | 479 ----------- .../org/apache/qpid/interop/connection.properties | 20 - java/management/eclipse-plugin/pom.xml | 41 +- .../qpid/management/ui/ManagementConsoleTest.java | 24 +- java/perftests/pom.xml | 230 +++--- .../qpid/client/message/TestMessageFactory.java | 25 +- .../org/apache/qpid/ping/PingDurableClient.java | 27 +- .../org/apache/qpid/ping/PingSendOnlyClient.java | 2 +- .../apache/qpid/requestreply/PingPongProducer.java | 35 +- java/pom.xml | 62 +- java/release-docs/RELEASE_NOTES.txt | 127 +-- java/resources/LICENSE | 203 +++++ java/resources/LICENSE.txt | 203 ----- java/resources/META-INF/DISCLAIMER | 10 + java/resources/META-INF/DISCLAIMER.txt | 7 - java/resources/META-INF/LICENSE | 203 +++++ java/resources/META-INF/NOTICE | 105 +++ java/resources/NOTICE | 105 +++ java/resources/NOTICE.txt | 36 - java/resources/README | 40 + java/resources/README.txt | 40 - java/systests/pom.xml | 3 + .../qpid/server/AMQBrokerManagerMBeanTest.java | 48 +- .../qpid/server/exchange/ImmediateMessageTest.java | 827 +++---------------- .../qpid/server/exchange/MandatoryMessageTest.java | 210 +++-- .../exchange/MessagingTestConfigProperties.java | 309 ------- .../ReturnUnroutableMandatoryMessageTest.java | 12 +- .../protocol/AMQProtocolSessionMBeanTest.java | 25 +- .../qpid/server/protocol/MaxChannelsTest.java | 25 +- .../qpid/server/queue/PersistentTestManual.java | 69 +- .../main/java/org/apache/qpid/test/VMTestCase.java | 28 +- .../org/apache/qpid/test/framework/Assertion.java | 39 + .../apache/qpid/test/framework/AssertionBase.java | 66 ++ .../org/apache/qpid/test/framework/Circuit.java | 109 +++ .../org/apache/qpid/test/framework/CircuitEnd.java | 77 ++ .../apache/qpid/test/framework/CircuitEndBase.java | 119 +++ .../org/apache/qpid/test/framework/DropInTest.java | 51 ++ .../qpid/test/framework/ExceptionMonitor.java | 151 ++++ .../qpid/test/framework/FrameworkBaseCase.java | 207 +++++ .../apache/qpid/test/framework/MessageMonitor.java | 46 ++ .../framework/MessagingTestConfigProperties.java | 303 +++++++ .../org/apache/qpid/test/framework/Publisher.java | 56 ++ .../org/apache/qpid/test/framework/Receiver.java | 48 ++ .../qpid/test/framework/TestClientDetails.java | 86 ++ .../org/apache/qpid/test/framework/TestUtils.java | 156 ++++ .../distributedcircuit/DistributedCircuitImpl.java | 116 +++ .../framework/distributedtesting/Coordinator.java | 498 ++++++++++++ .../distributedtesting/DistributedTestCase.java | 81 ++ .../DistributedTestDecorator.java | 166 ++++ .../distributedtesting/FanOutTestDecorator.java | 201 +++++ .../distributedtesting/InteropTestDecorator.java | 207 +++++ .../distributedtesting/OptOutTestCase.java | 68 ++ .../test/framework/listeners/XMLTestListener.java | 382 +++++++++ .../test/framework/localcircuit/CircuitImpl.java | 394 +++++++++ .../test/framework/localcircuit/PublisherImpl.java | 162 ++++ .../test/framework/localcircuit/ReceiverImpl.java | 90 ++ .../org/apache/qpid/test/framework/package.html | 22 + .../sequencers/BaseDistributedTestSequencer.java | 129 +++ .../sequencers/DistributedTestSequencer.java | 75 ++ .../framework/sequencers/FanOutTestSequencer.java | 171 ++++ .../framework/sequencers/InteropTestSequencer.java | 137 ++++ .../framework/sequencers/TestCaseSequencer.java | 66 ++ .../org/apache/qpid/util/ClasspathScanner.java | 234 ++++++ .../org/apache/qpid/util/ConversationFactory.java | 479 +++++++++++ java/tasks/src/org/apache/qpid/tasks/BaseTask.java | 74 -- java/tasks/src/org/apache/qpid/tasks/Foreach.java | 84 -- java/tasks/src/org/apache/qpid/tasks/Map.java | 94 --- java/tasks/src/org/apache/qpid/tasks/Require.java | 80 -- 209 files changed, 15599 insertions(+), 8204 deletions(-) create mode 100755 java/broker/bin/msTool.sh create mode 100644 java/broker/etc/debug.log4j.xml create mode 100644 java/broker/etc/messagestoretool-log4j.xml create mode 100644 java/broker/etc/mstool-log4j.xml create mode 100644 java/broker/src/main/java/org/apache/qpid/configuration/Configuration.java delete mode 100644 java/broker/src/main/java/org/apache/qpid/server/security/Passwd.java create mode 100644 java/broker/src/main/java/org/apache/qpid/tools/messagestore/MessageStoreTool.java create mode 100644 java/broker/src/main/java/org/apache/qpid/tools/messagestore/commands/AbstractCommand.java create mode 100644 java/broker/src/main/java/org/apache/qpid/tools/messagestore/commands/Clear.java create mode 100644 java/broker/src/main/java/org/apache/qpid/tools/messagestore/commands/Command.java create mode 100644 java/broker/src/main/java/org/apache/qpid/tools/messagestore/commands/Copy.java create mode 100644 java/broker/src/main/java/org/apache/qpid/tools/messagestore/commands/Dump.java create mode 100644 java/broker/src/main/java/org/apache/qpid/tools/messagestore/commands/Help.java create mode 100644 java/broker/src/main/java/org/apache/qpid/tools/messagestore/commands/List.java create mode 100644 java/broker/src/main/java/org/apache/qpid/tools/messagestore/commands/Load.java create mode 100644 java/broker/src/main/java/org/apache/qpid/tools/messagestore/commands/Move.java create mode 100644 java/broker/src/main/java/org/apache/qpid/tools/messagestore/commands/Purge.java create mode 100644 java/broker/src/main/java/org/apache/qpid/tools/messagestore/commands/Quit.java create mode 100644 java/broker/src/main/java/org/apache/qpid/tools/messagestore/commands/Select.java create mode 100644 java/broker/src/main/java/org/apache/qpid/tools/messagestore/commands/Show.java create mode 100644 java/broker/src/main/java/org/apache/qpid/tools/security/Passwd.java create mode 100644 java/broker/src/main/java/org/apache/qpid/tools/utils/CommandParser.java create mode 100644 java/broker/src/main/java/org/apache/qpid/tools/utils/Console.java create mode 100644 java/broker/src/main/java/org/apache/qpid/tools/utils/SimpleCommandParser.java create mode 100644 java/broker/src/main/java/org/apache/qpid/tools/utils/SimpleConsole.java create mode 100644 java/broker/src/main/java/org/apache/qpid/tools/utils/utils/CommandParser.java create mode 100644 java/broker/src/main/java/org/apache/qpid/tools/utils/utils/Console.java create mode 100644 java/broker/src/main/java/org/apache/qpid/tools/utils/utils/RSHCommandParser.java create mode 100644 java/broker/src/main/java/org/apache/qpid/tools/utils/utils/SimpleCommandParser.java create mode 100644 java/client/example/src/main/java/org/apache/qpid/example/pubsub/Client.java create mode 100644 java/client/example/src/main/java/org/apache/qpid/example/pubsub/ConnectionSetup.java create mode 100644 java/client/example/src/main/java/org/apache/qpid/example/pubsub/Publisher.java create mode 100644 java/client/example/src/main/java/org/apache/qpid/example/pubsub/Subscriber.java delete mode 100644 java/distribution/src/main/release/DISCLAIMER delete mode 100755 java/distribution/src/main/release/LICENSE.txt delete mode 100644 java/distribution/src/main/release/NOTICE.txt delete mode 100644 java/distribution/src/main/release/README.txt create mode 100644 java/integrationtests/src/main/java/org/apache/qpid/interop/clienttestcases/TestCase1DummyRun.java create mode 100644 java/integrationtests/src/main/java/org/apache/qpid/interop/clienttestcases/TestCase2BasicP2P.java create mode 100644 java/integrationtests/src/main/java/org/apache/qpid/interop/clienttestcases/TestCase3BasicPubSub.java delete mode 100644 java/integrationtests/src/main/java/org/apache/qpid/interop/coordinator/CoordinatingTestCase.java delete mode 100644 java/integrationtests/src/main/java/org/apache/qpid/interop/coordinator/Coordinator.java delete mode 100644 java/integrationtests/src/main/java/org/apache/qpid/interop/coordinator/InvitingTestDecorator.java delete mode 100644 java/integrationtests/src/main/java/org/apache/qpid/interop/coordinator/ListeningCoordinatorTest.java delete mode 100644 java/integrationtests/src/main/java/org/apache/qpid/interop/coordinator/ListeningTestDecorator.java delete mode 100644 java/integrationtests/src/main/java/org/apache/qpid/interop/coordinator/OptOutTestCase.java delete mode 100644 java/integrationtests/src/main/java/org/apache/qpid/interop/coordinator/TestClientDetails.java delete mode 100644 java/integrationtests/src/main/java/org/apache/qpid/interop/coordinator/XMLTestListener.java delete mode 100644 java/integrationtests/src/main/java/org/apache/qpid/interop/coordinator/testcases/CoordinatingTestCase1DummyRun.java delete mode 100644 java/integrationtests/src/main/java/org/apache/qpid/interop/coordinator/testcases/CoordinatingTestCase2BasicP2P.java delete mode 100644 java/integrationtests/src/main/java/org/apache/qpid/interop/coordinator/testcases/CoordinatingTestCase3BasicPubSub.java delete mode 100644 java/integrationtests/src/main/java/org/apache/qpid/interop/old/Listener.java delete mode 100644 java/integrationtests/src/main/java/org/apache/qpid/interop/old/Publisher.java create mode 100644 java/integrationtests/src/main/java/org/apache/qpid/interop/testcases/CircuitTestCase.java create mode 100644 java/integrationtests/src/main/java/org/apache/qpid/interop/testcases/InteropTestCase1DummyRun.java create mode 100644 java/integrationtests/src/main/java/org/apache/qpid/interop/testcases/InteropTestCase2BasicP2P.java create mode 100644 java/integrationtests/src/main/java/org/apache/qpid/interop/testcases/InteropTestCase3BasicPubSub.java delete mode 100644 java/integrationtests/src/main/java/org/apache/qpid/interop/testclient/InteropClientTestCase.java delete mode 100644 java/integrationtests/src/main/java/org/apache/qpid/interop/testclient/TestClient.java delete mode 100644 java/integrationtests/src/main/java/org/apache/qpid/interop/testclient/testcases/TestCase1DummyRun.java delete mode 100644 java/integrationtests/src/main/java/org/apache/qpid/interop/testclient/testcases/TestCase2BasicP2P.java delete mode 100644 java/integrationtests/src/main/java/org/apache/qpid/interop/testclient/testcases/TestCase3BasicPubSub.java create mode 100644 java/integrationtests/src/main/java/org/apache/qpid/sustained/SustainedClientTestCase.java create mode 100644 java/integrationtests/src/main/java/org/apache/qpid/sustained/SustainedTestCase.java delete mode 100644 java/integrationtests/src/main/java/org/apache/qpid/sustained/SustainedTestCoordinator.java delete mode 100644 java/integrationtests/src/main/java/org/apache/qpid/sustained/TestClient.java delete mode 100644 java/integrationtests/src/main/java/org/apache/qpid/sustained/TestCoordinator.java create mode 100644 java/integrationtests/src/main/java/org/apache/qpid/test/framework/distributedtesting/InteropClientTestCase.java create mode 100644 java/integrationtests/src/main/java/org/apache/qpid/test/framework/distributedtesting/TestClient.java delete mode 100644 java/integrationtests/src/main/java/org/apache/qpid/util/ClasspathScanner.java delete mode 100644 java/integrationtests/src/main/java/org/apache/qpid/util/ConversationFactory.java delete mode 100644 java/integrationtests/src/resources/org/apache/qpid/interop/connection.properties create mode 100644 java/resources/LICENSE delete mode 100755 java/resources/LICENSE.txt create mode 100644 java/resources/META-INF/DISCLAIMER delete mode 100644 java/resources/META-INF/DISCLAIMER.txt create mode 100644 java/resources/META-INF/LICENSE create mode 100644 java/resources/META-INF/NOTICE create mode 100644 java/resources/NOTICE delete mode 100644 java/resources/NOTICE.txt create mode 100644 java/resources/README delete mode 100644 java/resources/README.txt delete mode 100644 java/systests/src/main/java/org/apache/qpid/server/exchange/MessagingTestConfigProperties.java create mode 100644 java/systests/src/main/java/org/apache/qpid/test/framework/Assertion.java create mode 100644 java/systests/src/main/java/org/apache/qpid/test/framework/AssertionBase.java create mode 100644 java/systests/src/main/java/org/apache/qpid/test/framework/Circuit.java create mode 100644 java/systests/src/main/java/org/apache/qpid/test/framework/CircuitEnd.java create mode 100644 java/systests/src/main/java/org/apache/qpid/test/framework/CircuitEndBase.java create mode 100644 java/systests/src/main/java/org/apache/qpid/test/framework/DropInTest.java create mode 100644 java/systests/src/main/java/org/apache/qpid/test/framework/ExceptionMonitor.java create mode 100644 java/systests/src/main/java/org/apache/qpid/test/framework/FrameworkBaseCase.java create mode 100644 java/systests/src/main/java/org/apache/qpid/test/framework/MessageMonitor.java create mode 100644 java/systests/src/main/java/org/apache/qpid/test/framework/MessagingTestConfigProperties.java create mode 100644 java/systests/src/main/java/org/apache/qpid/test/framework/Publisher.java create mode 100644 java/systests/src/main/java/org/apache/qpid/test/framework/Receiver.java create mode 100644 java/systests/src/main/java/org/apache/qpid/test/framework/TestClientDetails.java create mode 100644 java/systests/src/main/java/org/apache/qpid/test/framework/TestUtils.java create mode 100644 java/systests/src/main/java/org/apache/qpid/test/framework/distributedcircuit/DistributedCircuitImpl.java create mode 100644 java/systests/src/main/java/org/apache/qpid/test/framework/distributedtesting/Coordinator.java create mode 100644 java/systests/src/main/java/org/apache/qpid/test/framework/distributedtesting/DistributedTestCase.java create mode 100644 java/systests/src/main/java/org/apache/qpid/test/framework/distributedtesting/DistributedTestDecorator.java create mode 100644 java/systests/src/main/java/org/apache/qpid/test/framework/distributedtesting/FanOutTestDecorator.java create mode 100644 java/systests/src/main/java/org/apache/qpid/test/framework/distributedtesting/InteropTestDecorator.java create mode 100644 java/systests/src/main/java/org/apache/qpid/test/framework/distributedtesting/OptOutTestCase.java create mode 100644 java/systests/src/main/java/org/apache/qpid/test/framework/listeners/XMLTestListener.java create mode 100644 java/systests/src/main/java/org/apache/qpid/test/framework/localcircuit/CircuitImpl.java create mode 100644 java/systests/src/main/java/org/apache/qpid/test/framework/localcircuit/PublisherImpl.java create mode 100644 java/systests/src/main/java/org/apache/qpid/test/framework/localcircuit/ReceiverImpl.java create mode 100644 java/systests/src/main/java/org/apache/qpid/test/framework/package.html create mode 100644 java/systests/src/main/java/org/apache/qpid/test/framework/sequencers/BaseDistributedTestSequencer.java create mode 100644 java/systests/src/main/java/org/apache/qpid/test/framework/sequencers/DistributedTestSequencer.java create mode 100644 java/systests/src/main/java/org/apache/qpid/test/framework/sequencers/FanOutTestSequencer.java create mode 100644 java/systests/src/main/java/org/apache/qpid/test/framework/sequencers/InteropTestSequencer.java create mode 100644 java/systests/src/main/java/org/apache/qpid/test/framework/sequencers/TestCaseSequencer.java create mode 100644 java/systests/src/main/java/org/apache/qpid/util/ClasspathScanner.java create mode 100644 java/systests/src/main/java/org/apache/qpid/util/ConversationFactory.java delete mode 100644 java/tasks/src/org/apache/qpid/tasks/BaseTask.java delete mode 100644 java/tasks/src/org/apache/qpid/tasks/Foreach.java delete mode 100644 java/tasks/src/org/apache/qpid/tasks/Map.java delete mode 100644 java/tasks/src/org/apache/qpid/tasks/Require.java (limited to 'java') diff --git a/java/broker/bin/msTool.sh b/java/broker/bin/msTool.sh new file mode 100755 index 0000000000..4d55ee7811 --- /dev/null +++ b/java/broker/bin/msTool.sh @@ -0,0 +1,56 @@ +#!/bin/bash +# +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# + +# Set classpath to include Qpid jar with all required jars in manifest +QPID_LIBS=$QPID_TOOLS/lib/qpid-incubating.jar + +die() { + if [[ $1 = -usage ]]; then + shift + usage=true + else + usage=false + fi + echo "$@" + $usage && echo + $usage && usage + exit 1 +} + +cygwin=false +if [[ "$(uname -a | fgrep Cygwin)" != "" ]]; then + cygwin=true +fi + +if $cygwin; then + QPID_TOOLS=$(cygpath -w $QPID_TOOLS) +fi + +# Set other variables used by the qpid-run script before calling +export JAVA=java \ + JAVA_VM=-server \ + JAVA_OPTS=-Dlog4j.configuration=file:$QPID_TOOLS/etc/mstool-log4j.xml \ + QPID_CLASSPATH=$QPID_LIBS + +if [ -z "$QPID_TOOLS" ]; then + die "QPID_TOOLS be set" +fi + +. qpid-run org.apache.qpid.tools.messagestore.MessageStoreTool "$@" diff --git a/java/broker/bin/qpid-passwd b/java/broker/bin/qpid-passwd index 6e64af6e70..f046252522 100644 --- a/java/broker/bin/qpid-passwd +++ b/java/broker/bin/qpid-passwd @@ -27,4 +27,4 @@ export JAVA=java \ JAVA_MEM=-Xmx1024m \ QPID_CLASSPATH=$QPID_LIBS -. qpid-run org.apache.qpid.server.security.Passwd "$@" +. qpid-run org.apache.qpid.tools.security.Passwd "$@" diff --git a/java/broker/bin/qpid-server b/java/broker/bin/qpid-server index 76d0ad786d..fabf7e941c 100644 --- a/java/broker/bin/qpid-server +++ b/java/broker/bin/qpid-server @@ -7,9 +7,9 @@ # to you under the Apache License, Version 2.0 (the # "License"); you may not use this file except in compliance # with the License. You may obtain a copy of the License at -# +# # http://www.apache.org/licenses/LICENSE-2.0 -# +# # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY @@ -25,7 +25,7 @@ QPID_LIBS=$QPID_HOME/lib/qpid-incubating.jar:$QPID_HOME/lib/bdbstore-launch.jar export JAVA=java \ JAVA_VM=-server \ JAVA_MEM=-Xmx1024m \ - JAVA_GC=-XX:-UseConcMarkSweepGC + JAVA_GC=-XX:-UseConcMarkSweepGC \ QPID_CLASSPATH=$QPID_LIBS . qpid-run org.apache.qpid.server.Main "$@" diff --git a/java/broker/distribution/src/main/assembly/broker-bin.xml b/java/broker/distribution/src/main/assembly/broker-bin.xml index 4b32630771..e66190a3f4 100644 --- a/java/broker/distribution/src/main/assembly/broker-bin.xml +++ b/java/broker/distribution/src/main/assembly/broker-bin.xml @@ -114,9 +114,9 @@ 473 - ../bin/passwd + ../bin/qpid-passwd qpid-${qpid.version}/bin - passwd + qpid-passwd 473 diff --git a/java/broker/etc/debug.log4j.xml b/java/broker/etc/debug.log4j.xml new file mode 100644 index 0000000000..e8fd7e119d --- /dev/null +++ b/java/broker/etc/debug.log4j.xml @@ -0,0 +1,114 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/java/broker/etc/log4j.xml b/java/broker/etc/log4j.xml index 2fb7b80c96..2060246b7f 100644 --- a/java/broker/etc/log4j.xml +++ b/java/broker/etc/log4j.xml @@ -44,7 +44,7 @@ - + @@ -57,6 +57,15 @@ + + + + + + + + + @@ -64,15 +73,27 @@ - + + + + + + + + + + + + + - - + + + @@ -80,10 +101,11 @@ --> + - + diff --git a/java/broker/etc/messagestoretool-log4j.xml b/java/broker/etc/messagestoretool-log4j.xml new file mode 100644 index 0000000000..0313de4f95 --- /dev/null +++ b/java/broker/etc/messagestoretool-log4j.xml @@ -0,0 +1,53 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/java/broker/etc/mstool-log4j.xml b/java/broker/etc/mstool-log4j.xml new file mode 100644 index 0000000000..8c46010e2d --- /dev/null +++ b/java/broker/etc/mstool-log4j.xml @@ -0,0 +1,54 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/java/broker/pom.xml b/java/broker/pom.xml index 81c5d22b22..35c29d504f 100644 --- a/java/broker/pom.xml +++ b/java/broker/pom.xml @@ -101,6 +101,25 @@ + + + + + org.apache.maven.plugins maven-antrun-plugin diff --git a/java/broker/src/main/java/org/apache/log4j/QpidCompositeRollingAppender.java b/java/broker/src/main/java/org/apache/log4j/QpidCompositeRollingAppender.java index 931c15a664..7e0c4defe1 100644 --- a/java/broker/src/main/java/org/apache/log4j/QpidCompositeRollingAppender.java +++ b/java/broker/src/main/java/org/apache/log4j/QpidCompositeRollingAppender.java @@ -31,7 +31,6 @@ import java.util.concurrent.ConcurrentLinkedQueue; import java.util.concurrent.Executor; import java.util.concurrent.Executors; import java.util.concurrent.atomic.AtomicBoolean; -import java.util.concurrent.atomic.AtomicInteger; import java.util.zip.GZIPOutputStream; import org.apache.log4j.helpers.CountingQuietWriter; @@ -39,8 +38,6 @@ import org.apache.log4j.helpers.LogLog; import org.apache.log4j.helpers.OptionConverter; import org.apache.log4j.spi.LoggingEvent; -import org.apache.qpid.framing.FieldTable; - /** *

CompositeRollingAppender combines RollingFileAppender and DailyRollingFileAppender
It can function as either * or do both at the same time (making size based rolling files like RollingFileAppender until a data/time boundary is diff --git a/java/broker/src/main/java/org/apache/qpid/configuration/Configuration.java b/java/broker/src/main/java/org/apache/qpid/configuration/Configuration.java new file mode 100644 index 0000000000..40ff590a0a --- /dev/null +++ b/java/broker/src/main/java/org/apache/qpid/configuration/Configuration.java @@ -0,0 +1,188 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +package org.apache.qpid.configuration; + +import org.apache.commons.cli.CommandLine; +import org.apache.commons.cli.Option; +import org.apache.commons.cli.Options; +import org.apache.commons.cli.ParseException; +import org.apache.commons.cli.PosixParser; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.File; + +public class Configuration +{ + public static final String QPID_HOME = "QPID_HOME"; + + final String QPIDHOME = System.getProperty(QPID_HOME); + + private static Logger _devlog = LoggerFactory.getLogger(Configuration.class); + + public static final String DEFAULT_LOG_CONFIG_FILENAME = "log4j.xml"; + public static final String DEFAULT_CONFIG_FILE = "etc/config.xml"; + + protected final Options _options = new Options(); + protected CommandLine _commandLine; + protected File _configFile; + + + public Configuration() + { + + } + + public void processCommandline(String[] args) throws InitException + { + try + { + _commandLine = new PosixParser().parse(_options, args); + } + catch (ParseException e) + { + throw new InitException("Unable to parse commmandline", e); + } + + final File defaultConfigFile = new File(QPIDHOME, DEFAULT_CONFIG_FILE); + setConfig(new File(_commandLine.getOptionValue("c", defaultConfigFile.getPath()))); + } + + public void setConfig(File file) + { + _configFile = file; + } + + /** + * @param option The option to set. + */ + public void setOption(Option option) + { + _options.addOption(option); + } + + /** + * getOptionValue from the configuration + * @param option variable argument, first string is option to get, second if present is the default value. + * @return the String for the given option or null if not present (if default value not specified) + */ + public String getOptionValue(String... option) + { + if (option.length == 1) + { + return _commandLine.getOptionValue(option[0]); + } + else if (option.length == 2) + { + return _commandLine.getOptionValue(option[0], option[1]); + } + return null; + } + + public void loadConfig(File file) throws InitException + { + setConfig(file); + loadConfig(); + } + + private void loadConfig() throws InitException + { + if (!_configFile.exists()) + { + String error = "File " + _configFile + " could not be found. Check the file exists and is readable."; + + if (QPIDHOME == null) + { + error = error + "\nNote: " + QPID_HOME + " is not set."; + } + + throw new InitException(error, null); + } + else + { + _devlog.debug("Using configuration file " + _configFile.getAbsolutePath()); + } + +// String logConfig = _commandLine.getOptionValue("l"); +// String logWatchConfig = _commandLine.getOptionValue("w", "0"); +// if (logConfig != null) +// { +// File logConfigFile = new File(logConfig); +// configureLogging(logConfigFile, logWatchConfig); +// } +// else +// { +// File configFileDirectory = _configFile.getParentFile(); +// File logConfigFile = new File(configFileDirectory, DEFAULT_LOG_CONFIG_FILENAME); +// configureLogging(logConfigFile, logWatchConfig); +// } + } + + +// private void configureLogging(File logConfigFile, String logWatchConfig) +// { +// int logWatchTime = 0; +// try +// { +// logWatchTime = Integer.parseInt(logWatchConfig); +// } +// catch (NumberFormatException e) +// { +// _devlog.error("Log watch configuration value of " + logWatchConfig + " is invalid. Must be " +// + "a non-negative integer. Using default of zero (no watching configured"); +// } +// +// if (logConfigFile.exists() && logConfigFile.canRead()) +// { +// _devlog.info("Configuring logger using configuration file " + logConfigFile.getAbsolutePath()); +// if (logWatchTime > 0) +// { +// _devlog.info("log file " + logConfigFile.getAbsolutePath() + " will be checked for changes every " +// + logWatchTime + " seconds"); +// // log4j expects the watch interval in milliseconds +// DOMConfigurator.configureAndWatch(logConfigFile.getAbsolutePath(), logWatchTime * 1000); +// } +// else +// { +// DOMConfigurator.configure(logConfigFile.getAbsolutePath()); +// } +// } +// else +// { +// System.err.println("Logging configuration error: unable to read file " + logConfigFile.getAbsolutePath()); +// System.err.println("Using basic log4j configuration"); +// BasicConfigurator.configure(); +// } +// } + + public File getConfigFile() + { + return _configFile; + } + + + public class InitException extends Exception + { + InitException(String msg, Throwable cause) + { + super(msg, cause); + } + } +} \ No newline at end of file diff --git a/java/broker/src/main/java/org/apache/qpid/server/AMQChannel.java b/java/broker/src/main/java/org/apache/qpid/server/AMQChannel.java index 28a9e85489..7f14946834 100644 --- a/java/broker/src/main/java/org/apache/qpid/server/AMQChannel.java +++ b/java/broker/src/main/java/org/apache/qpid/server/AMQChannel.java @@ -582,9 +582,9 @@ public class AMQChannel final List msgToRequeue = new LinkedList(); final List msgToResend = new LinkedList(); - if (_log.isInfoEnabled()) + if (_log.isDebugEnabled()) { - _log.info("unacked map Size:" + _unacknowledgedMessageMap.size()); + _log.debug("unacked map Size:" + _unacknowledgedMessageMap.size()); } // Process the Unacked-Map. @@ -640,15 +640,15 @@ public class AMQChannel }); // Process Messages to Resend - if (_log.isInfoEnabled()) + if (_log.isDebugEnabled()) { if (!msgToResend.isEmpty()) { - _log.info("Preparing (" + msgToResend.size() + ") message to resend."); + _log.debug("Preparing (" + msgToResend.size() + ") message to resend."); } else { - _log.info("No message to resend."); + _log.debug("No message to resend."); } } diff --git a/java/broker/src/main/java/org/apache/qpid/server/Main.java b/java/broker/src/main/java/org/apache/qpid/server/Main.java index 29ea69caf7..dd6546585f 100644 --- a/java/broker/src/main/java/org/apache/qpid/server/Main.java +++ b/java/broker/src/main/java/org/apache/qpid/server/Main.java @@ -34,6 +34,7 @@ import org.apache.commons.cli.OptionBuilder; import org.apache.commons.cli.Options; import org.apache.commons.cli.ParseException; import org.apache.commons.cli.PosixParser; +import org.apache.commons.configuration.Configuration; import org.apache.commons.configuration.ConfigurationException; import org.apache.log4j.BasicConfigurator; import org.apache.log4j.Logger; @@ -48,6 +49,7 @@ import org.apache.qpid.common.QpidProperties; import org.apache.qpid.framing.ProtocolVersion; import org.apache.qpid.pool.ReadWriteThreadModel; import org.apache.qpid.server.configuration.VirtualHostConfiguration; +import org.apache.qpid.server.management.JMXManagedObjectRegistry; import org.apache.qpid.server.protocol.AMQPFastProtocolHandler; import org.apache.qpid.server.protocol.AMQPProtocolProvider; import org.apache.qpid.server.registry.ApplicationRegistry; @@ -55,11 +57,19 @@ import org.apache.qpid.server.registry.ConfigurationFileApplicationRegistry; import org.apache.qpid.server.transport.ConnectorConfiguration; import org.apache.qpid.url.URLSyntaxException; +import java.io.File; +import java.io.IOException; +import java.net.BindException; +import java.net.InetAddress; +import java.net.InetSocketAddress; +import java.util.Collection; +import java.util.List; + /** * Main entry point for AMQPD. * */ -@SuppressWarnings({ "AccessStaticViaInstance" }) +@SuppressWarnings({"AccessStaticViaInstance"}) public class Main { /** Used for debugging. */ @@ -133,6 +143,12 @@ public class Main OptionBuilder.withArgName("port").hasArg() .withDescription("listen on the specified port. Overrides any value in the config file") .withLongOpt("port").create("p"); + Option mport = + OptionBuilder.withArgName("mport").hasArg() + .withDescription("listen on the specified management port. Overrides any value in the config file") + .withLongOpt("mport").create("m"); + + Option bind = OptionBuilder.withArgName("bind").hasArg() .withDescription("bind to the specified address. Overrides any value in the config file") @@ -153,6 +169,7 @@ public class Main options.addOption(logconfig); options.addOption(logwatchconfig); options.addOption(port); + options.addOption(mport); options.addOption(bind); } @@ -203,15 +220,19 @@ public class Main catch (InitException e) { System.out.println(e.getMessage()); + _brokerLogger.error("Initialisation Error : " + e.getMessage()); + } catch (ConfigurationException e) { System.out.println("Error configuring message broker: " + e); + _brokerLogger.error("Error configuring message broker: " + e); e.printStackTrace(); } catch (Exception e) { System.out.println("Error intialising message broker: " + e); + _brokerLogger.error("Error intialising message broker: " + e); e.printStackTrace(); } } @@ -260,7 +281,15 @@ public class Main configureLogging(logConfigFile, logWatchConfig); } - ApplicationRegistry.initialise(new ConfigurationFileApplicationRegistry(configFile)); + ConfigurationFileApplicationRegistry config = new ConfigurationFileApplicationRegistry(configFile); + + + updateManagementPort(config.getConfiguration(), commandLine.getOptionValue("m")); + + + + ApplicationRegistry.initialise(config); + // fixme .. use QpidProperties.getVersionString when we have fixed the classpath issues // that are causing the broker build to pick up the wrong properties file and hence say @@ -318,6 +347,29 @@ public class Main bind(port, connectorConfig); } + /** + * Update the configuration data with the management port. + * @param configuration + * @param managementPort The string from the command line + */ + private void updateManagementPort(Configuration configuration, String managementPort) + { + if (managementPort != null) + { + int mport; + int defaultMPort = configuration.getInt(JMXManagedObjectRegistry.MANAGEMENT_PORT_CONFIG_PATH); + try + { + mport = Integer.parseInt(managementPort); + configuration.setProperty(JMXManagedObjectRegistry.MANAGEMENT_PORT_CONFIG_PATH, mport); + } + catch (NumberFormatException e) + { + _logger.warn("Invalid management port: " + managementPort + " will use default:" + defaultMPort, e); + } + } + } + protected void setupVirtualHosts(String configFileParent, String configFilePath) throws ConfigurationException, AMQException, URLSyntaxException { diff --git a/java/broker/src/main/java/org/apache/qpid/server/exchange/AbstractExchange.java b/java/broker/src/main/java/org/apache/qpid/server/exchange/AbstractExchange.java index 868ac31a54..9ebb893362 100644 --- a/java/broker/src/main/java/org/apache/qpid/server/exchange/AbstractExchange.java +++ b/java/broker/src/main/java/org/apache/qpid/server/exchange/AbstractExchange.java @@ -38,9 +38,13 @@ import org.apache.qpid.server.management.Managable; import org.apache.qpid.server.management.ManagedObject; import org.apache.qpid.server.management.ManagedObjectRegistry; import org.apache.qpid.server.queue.QueueRegistry; +import org.apache.qpid.server.queue.AMQQueue; import org.apache.qpid.server.registry.ApplicationRegistry; import org.apache.qpid.server.virtualhost.VirtualHost; +import java.util.List; +import java.util.Map; + public abstract class AbstractExchange implements Exchange, Managable { private AMQShortString _name; @@ -189,6 +193,8 @@ public abstract class AbstractExchange implements Exchange, Managable } } + abstract public Map> getBindings(); + public String toString() { return getClass().getName() + "[" + getName() +"]"; diff --git a/java/broker/src/main/java/org/apache/qpid/server/exchange/DefaultExchangeRegistry.java b/java/broker/src/main/java/org/apache/qpid/server/exchange/DefaultExchangeRegistry.java index f3bdecc32e..377a73dd31 100644 --- a/java/broker/src/main/java/org/apache/qpid/server/exchange/DefaultExchangeRegistry.java +++ b/java/broker/src/main/java/org/apache/qpid/server/exchange/DefaultExchangeRegistry.java @@ -20,18 +20,20 @@ */ package org.apache.qpid.server.exchange; -import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.ConcurrentMap; - import org.apache.log4j.Logger; import org.apache.qpid.AMQException; import org.apache.qpid.framing.AMQShortString; import org.apache.qpid.server.protocol.ExchangeInitialiser; import org.apache.qpid.server.queue.AMQMessage; +import org.apache.qpid.server.store.MessageStore; import org.apache.qpid.server.virtualhost.VirtualHost; import org.apache.qpid.server.messageStore.MessageStore; import org.apache.qpid.server.exception.InternalErrorException; +import java.util.Collection; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ConcurrentMap; + public class DefaultExchangeRegistry implements ExchangeRegistry { private static final Logger _log = Logger.getLogger(DefaultExchangeRegistry.class); @@ -64,7 +66,7 @@ public class DefaultExchangeRegistry implements ExchangeRegistry public void registerExchange(Exchange exchange) throws AMQException { _exchangeMap.put(exchange.getName(), exchange); - if(exchange.isDurable()) + if (exchange.isDurable()) { try { @@ -86,13 +88,18 @@ public class DefaultExchangeRegistry implements ExchangeRegistry return _defaultExchange; } + public Collection getExchangeNames() + { + return _exchangeMap.keySet(); + } + public void unregisterExchange(AMQShortString name, boolean inUse) throws AMQException { // TODO: check inUse argument Exchange e = _exchangeMap.remove(name); if (e != null) { - if(e.isDurable()) + if (e.isDurable()) { try { @@ -112,7 +119,7 @@ public class DefaultExchangeRegistry implements ExchangeRegistry public Exchange getExchange(AMQShortString name) { - if((name == null) || name.length() == 0) + if ((name == null) || name.length() == 0) { return getDefaultExchange(); } diff --git a/java/broker/src/main/java/org/apache/qpid/server/exchange/DestNameExchange.java b/java/broker/src/main/java/org/apache/qpid/server/exchange/DestNameExchange.java index 0dcceaddbb..c24f9a37e1 100644 --- a/java/broker/src/main/java/org/apache/qpid/server/exchange/DestNameExchange.java +++ b/java/broker/src/main/java/org/apache/qpid/server/exchange/DestNameExchange.java @@ -26,22 +26,16 @@ import java.util.Map; import javax.management.JMException; import javax.management.MBeanException; -import javax.management.openmbean.ArrayType; import javax.management.openmbean.CompositeData; import javax.management.openmbean.CompositeDataSupport; -import javax.management.openmbean.CompositeType; import javax.management.openmbean.OpenDataException; -import javax.management.openmbean.OpenType; -import javax.management.openmbean.SimpleType; import javax.management.openmbean.TabularData; import javax.management.openmbean.TabularDataSupport; -import javax.management.openmbean.TabularType; import org.apache.log4j.Logger; import org.apache.qpid.AMQException; import org.apache.qpid.exchange.ExchangeDefaults; import org.apache.qpid.framing.AMQShortString; -import org.apache.qpid.framing.BasicPublishBody; import org.apache.qpid.framing.FieldTable; import org.apache.qpid.framing.abstraction.MessagePublishInfo; import org.apache.qpid.server.management.MBeanConstructor; @@ -222,4 +216,9 @@ public class DestNameExchange extends AbstractExchange { return !_index.getBindingsMap().isEmpty(); } + + public Map> getBindings() + { + return _index.getBindingsMap(); + } } diff --git a/java/broker/src/main/java/org/apache/qpid/server/exchange/DestWildExchange.java b/java/broker/src/main/java/org/apache/qpid/server/exchange/DestWildExchange.java index f6a95b5e55..e1a3a24d3e 100644 --- a/java/broker/src/main/java/org/apache/qpid/server/exchange/DestWildExchange.java +++ b/java/broker/src/main/java/org/apache/qpid/server/exchange/DestWildExchange.java @@ -21,11 +21,9 @@ package org.apache.qpid.server.exchange; import org.apache.log4j.Logger; - import org.apache.qpid.AMQException; import org.apache.qpid.exchange.ExchangeDefaults; import org.apache.qpid.framing.AMQShortString; -import org.apache.qpid.framing.BasicPublishBody; import org.apache.qpid.framing.FieldTable; import org.apache.qpid.framing.abstraction.MessagePublishInfo; import org.apache.qpid.server.management.MBeanConstructor; @@ -35,17 +33,11 @@ import org.apache.qpid.server.queue.AMQQueue; import javax.management.JMException; import javax.management.MBeanException; -import javax.management.openmbean.ArrayType; import javax.management.openmbean.CompositeData; import javax.management.openmbean.CompositeDataSupport; -import javax.management.openmbean.CompositeType; import javax.management.openmbean.OpenDataException; -import javax.management.openmbean.OpenType; -import javax.management.openmbean.SimpleType; import javax.management.openmbean.TabularData; import javax.management.openmbean.TabularDataSupport; -import javax.management.openmbean.TabularType; - import java.util.ArrayList; import java.util.LinkedList; import java.util.List; @@ -59,7 +51,7 @@ public class DestWildExchange extends AbstractExchange private static final Logger _logger = Logger.getLogger(DestWildExchange.class); private ConcurrentHashMap> _routingKey2queues = - new ConcurrentHashMap>(); + new ConcurrentHashMap>(); // private ConcurrentHashMap _routingKey2queue = new ConcurrentHashMap(); private static final String TOPIC_SEPARATOR = "."; private static final String AMQP_STAR = "*"; @@ -92,7 +84,7 @@ public class DestWildExchange extends AbstractExchange queueList.add(q.getName().toString()); } - Object[] bindingItemValues = { key.toString(), queueList.toArray(new String[0]) }; + Object[] bindingItemValues = {key.toString(), queueList.toArray(new String[0])}; CompositeData bindingData = new CompositeDataSupport(_bindingDataType, _bindingItemNames, bindingItemValues); _bindingList.put(bindingData); } @@ -311,6 +303,11 @@ public class DestWildExchange extends AbstractExchange } } + public Map> getBindings() + { + return _routingKey2queues; + } + private List getMatchedQueues(AMQShortString routingKey) { List list = new LinkedList(); @@ -358,8 +355,8 @@ public class DestWildExchange extends AbstractExchange if (queueList.size() > (depth + queueskip)) { // a hash and it is the last entry matching = - queueList.get(depth + queueskip).equals(AMQP_HASH) - && (queueList.size() == (depth + queueskip + 1)); + queueList.get(depth + queueskip).equals(AMQP_HASH) + && (queueList.size() == (depth + queueskip + 1)); } } else if (routingkeyList.size() > (depth + routingskip)) diff --git a/java/broker/src/main/java/org/apache/qpid/server/exchange/Exchange.java b/java/broker/src/main/java/org/apache/qpid/server/exchange/Exchange.java index a5f77cc2a4..37cd85a8f8 100644 --- a/java/broker/src/main/java/org/apache/qpid/server/exchange/Exchange.java +++ b/java/broker/src/main/java/org/apache/qpid/server/exchange/Exchange.java @@ -27,9 +27,13 @@ import org.apache.qpid.server.queue.AMQMessage; import org.apache.qpid.server.queue.AMQQueue; import org.apache.qpid.server.virtualhost.VirtualHost; +import java.util.List; +import java.util.Map; + public interface Exchange { AMQShortString getName(); + AMQShortString getType(); void initialise(VirtualHost host, AMQShortString name, boolean durable, int ticket, boolean autoDelete) throws AMQException; @@ -51,6 +55,17 @@ public interface Exchange void route(AMQMessage message) throws AMQException; + + /** + * Determines whether a message would be isBound to a particular queue using a specific routing key and arguments + * @param routingKey + * @param arguments + * @param queue + * @return + * @throws AMQException + */ + boolean isBound(AMQShortString routingKey, FieldTable arguments, AMQQueue queue); + /** * Determines whether a message would be isBound to a particular queue using a specific routing key * @param routingKey @@ -58,22 +73,25 @@ public interface Exchange * @return * @throws AMQException */ - boolean isBound(AMQShortString routingKey, AMQQueue queue) throws AMQException; + boolean isBound(AMQShortString routingKey, AMQQueue queue); /** - * Determines whether a message is routing to any queue using a specific routing key + * Determines whether a message is routing to any queue using a specific _routing key * @param routingKey * @return * @throws AMQException */ - boolean isBound(AMQShortString routingKey) throws AMQException; + boolean isBound(AMQShortString routingKey); - boolean isBound(AMQQueue queue) throws AMQException; + boolean isBound(AMQQueue queue); /** * Returns true if this exchange has at least one binding associated with it. * @return * @throws AMQException */ - boolean hasBindings() throws AMQException; + boolean hasBindings(); + + Map> getBindings(); + } diff --git a/java/broker/src/main/java/org/apache/qpid/server/exchange/ExchangeRegistry.java b/java/broker/src/main/java/org/apache/qpid/server/exchange/ExchangeRegistry.java index d3a466565f..fe3b19e74e 100644 --- a/java/broker/src/main/java/org/apache/qpid/server/exchange/ExchangeRegistry.java +++ b/java/broker/src/main/java/org/apache/qpid/server/exchange/ExchangeRegistry.java @@ -23,6 +23,8 @@ package org.apache.qpid.server.exchange; import org.apache.qpid.AMQException; import org.apache.qpid.framing.AMQShortString; +import java.util.Collection; + public interface ExchangeRegistry extends MessageRouter { @@ -43,5 +45,7 @@ public interface ExchangeRegistry extends MessageRouter Exchange getDefaultExchange(); + Collection getExchangeNames(); + void initialise() throws AMQException; } diff --git a/java/broker/src/main/java/org/apache/qpid/server/exchange/FanoutExchange.java b/java/broker/src/main/java/org/apache/qpid/server/exchange/FanoutExchange.java index bf00eeb9d3..1a705248c1 100644 --- a/java/broker/src/main/java/org/apache/qpid/server/exchange/FanoutExchange.java +++ b/java/broker/src/main/java/org/apache/qpid/server/exchange/FanoutExchange.java @@ -21,7 +21,6 @@ package org.apache.qpid.server.exchange; import org.apache.log4j.Logger; - import org.apache.qpid.AMQException; import org.apache.qpid.exchange.ExchangeDefaults; import org.apache.qpid.framing.AMQShortString; @@ -34,17 +33,13 @@ import org.apache.qpid.server.queue.AMQQueue; import javax.management.JMException; import javax.management.MBeanException; -import javax.management.openmbean.ArrayType; import javax.management.openmbean.CompositeData; import javax.management.openmbean.CompositeDataSupport; -import javax.management.openmbean.CompositeType; import javax.management.openmbean.OpenDataException; -import javax.management.openmbean.OpenType; -import javax.management.openmbean.SimpleType; import javax.management.openmbean.TabularData; import javax.management.openmbean.TabularDataSupport; -import javax.management.openmbean.TabularType; - +import java.util.List; +import java.util.Map; import java.util.concurrent.CopyOnWriteArraySet; public class FanoutExchange extends AbstractExchange @@ -79,7 +74,7 @@ public class FanoutExchange extends AbstractExchange { String queueName = queue.getName().toString(); - Object[] bindingItemValues = { queueName, new String[] { queueName } }; + Object[] bindingItemValues = {queueName, new String[]{queueName}}; CompositeData bindingData = new CompositeDataSupport(_bindingDataType, _bindingItemNames, bindingItemValues); _bindingList.put(bindingData); } @@ -120,6 +115,11 @@ public class FanoutExchange extends AbstractExchange } } + public Map> getBindings() + { + return null; + } + public AMQShortString getType() { return ExchangeDefaults.FANOUT_EXCHANGE_CLASS; @@ -181,24 +181,29 @@ public class FanoutExchange extends AbstractExchange } } - public boolean isBound(AMQShortString routingKey, AMQQueue queue) throws AMQException + public boolean isBound(AMQShortString routingKey, FieldTable arguments, AMQQueue queue) + { + return isBound(routingKey, queue); + } + + public boolean isBound(AMQShortString routingKey, AMQQueue queue) { return _queues.contains(queue); } - public boolean isBound(AMQShortString routingKey) throws AMQException + public boolean isBound(AMQShortString routingKey) { return (_queues != null) && !_queues.isEmpty(); } - public boolean isBound(AMQQueue queue) throws AMQException + public boolean isBound(AMQQueue queue) { return _queues.contains(queue); } - public boolean hasBindings() throws AMQException + public boolean hasBindings() { return !_queues.isEmpty(); } diff --git a/java/broker/src/main/java/org/apache/qpid/server/exchange/HeadersExchange.java b/java/broker/src/main/java/org/apache/qpid/server/exchange/HeadersExchange.java index e86094e26f..9bb1ee6a62 100644 --- a/java/broker/src/main/java/org/apache/qpid/server/exchange/HeadersExchange.java +++ b/java/broker/src/main/java/org/apache/qpid/server/exchange/HeadersExchange.java @@ -20,23 +20,6 @@ */ package org.apache.qpid.server.exchange; -import java.util.ArrayList; -import java.util.Iterator; -import java.util.List; -import java.util.concurrent.CopyOnWriteArrayList; - -import javax.management.JMException; -import javax.management.openmbean.ArrayType; -import javax.management.openmbean.CompositeData; -import javax.management.openmbean.CompositeDataSupport; -import javax.management.openmbean.CompositeType; -import javax.management.openmbean.OpenDataException; -import javax.management.openmbean.OpenType; -import javax.management.openmbean.SimpleType; -import javax.management.openmbean.TabularData; -import javax.management.openmbean.TabularDataSupport; -import javax.management.openmbean.TabularType; - import org.apache.log4j.Logger; import org.apache.qpid.AMQException; import org.apache.qpid.exchange.ExchangeDefaults; @@ -50,6 +33,23 @@ import org.apache.qpid.server.management.MBeanDescription; import org.apache.qpid.server.queue.AMQMessage; import org.apache.qpid.server.queue.AMQQueue; +import javax.management.JMException; +import javax.management.openmbean.ArrayType; +import javax.management.openmbean.CompositeData; +import javax.management.openmbean.CompositeDataSupport; +import javax.management.openmbean.CompositeType; +import javax.management.openmbean.OpenDataException; +import javax.management.openmbean.OpenType; +import javax.management.openmbean.SimpleType; +import javax.management.openmbean.TabularData; +import javax.management.openmbean.TabularDataSupport; +import javax.management.openmbean.TabularType; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.concurrent.CopyOnWriteArrayList; + /** * An exchange that binds queues based on a set of required headers and header values * and routes messages to these queues by matching the headers of the message against @@ -91,13 +91,13 @@ public class HeadersExchange extends AbstractExchange private final class HeadersExchangeMBean extends ExchangeMBean { @MBeanConstructor("Creates an MBean for AMQ Headers exchange") - public HeadersExchangeMBean() throws JMException + public HeadersExchangeMBean() throws JMException { super(); _exchangeType = "headers"; init(); } - + /** * initialises the OpenType objects. */ @@ -113,7 +113,7 @@ public class HeadersExchange extends AbstractExchange _bindingDataType = new CompositeType("Exchange Binding", "Queue name and header bindings", _bindingItemNames, _bindingItemNames, _bindingItemTypes); _bindinglistDataType = new TabularType("Exchange Bindings", "List of exchange bindings for " + getName(), - _bindingDataType, _bindingItemIndexNames); + _bindingDataType, _bindingItemIndexNames); } public TabularData bindings() throws OpenDataException @@ -169,7 +169,7 @@ public class HeadersExchange extends AbstractExchange throw new JMException("Queue \"" + queueName + "\" is not registered with the exchange."); } - String[] bindings = binding.split(","); + String[] bindings = binding.split(","); FieldTable bindingMap = new FieldTable(); for (int i = 0; i < bindings.length; i++) { @@ -241,17 +241,23 @@ public class HeadersExchange extends AbstractExchange } } - public boolean isBound(AMQShortString routingKey, AMQQueue queue) throws AMQException + public boolean isBound(AMQShortString routingKey, FieldTable arguments, AMQQueue queue) + { + //fixme isBound here should take the arguements in to consideration. + return isBound(routingKey, queue); + } + + public boolean isBound(AMQShortString routingKey, AMQQueue queue) { return isBound(queue); } - public boolean isBound(AMQShortString routingKey) throws AMQException + public boolean isBound(AMQShortString routingKey) { return hasBindings(); } - public boolean isBound(AMQQueue queue) throws AMQException + public boolean isBound(AMQQueue queue) { for (Registration r : _bindings) { @@ -263,7 +269,7 @@ public class HeadersExchange extends AbstractExchange return false; } - public boolean hasBindings() throws AMQException + public boolean hasBindings() { return !_bindings.isEmpty(); } @@ -288,6 +294,11 @@ public class HeadersExchange extends AbstractExchange } } + public Map> getBindings() + { + return null; + } + private static class Registration { private final HeadersBinding binding; diff --git a/java/broker/src/main/java/org/apache/qpid/server/handler/BasicConsumeMethodHandler.java b/java/broker/src/main/java/org/apache/qpid/server/handler/BasicConsumeMethodHandler.java index 9346eecbb2..ab4f2c4e64 100644 --- a/java/broker/src/main/java/org/apache/qpid/server/handler/BasicConsumeMethodHandler.java +++ b/java/broker/src/main/java/org/apache/qpid/server/handler/BasicConsumeMethodHandler.java @@ -100,6 +100,12 @@ public class BasicConsumeMethodHandler implements StateAwareMethodListener { @@ -77,7 +77,7 @@ public class QueueBindHandler implements StateAwareMethodListener { throw body.getChannelException(AMQConstant.NOT_FOUND, "No default queue defined on channel and queue was null"); } - + if (body.routingKey == null) { body.routingKey = queue.getName(); @@ -97,9 +97,18 @@ public class QueueBindHandler implements StateAwareMethodListener { throw body.getChannelException(AMQConstant.NOT_FOUND, "Exchange " + body.exchange + " does not exist."); } + + if (body.routingKey != null) + { + body.routingKey = body.routingKey.intern(); + } + try - { - queue.bind(body.routingKey, body.arguments, exch); + { + if (!exch.isBound(body.routingKey, body.arguments, queue)) + { + queue.bind(body.routingKey, body.arguments, exch); + } } catch (AMQInvalidRoutingKeyException rke) { diff --git a/java/broker/src/main/java/org/apache/qpid/server/handler/QueueDeclareHandler.java b/java/broker/src/main/java/org/apache/qpid/server/handler/QueueDeclareHandler.java index f9e94af697..28967841a2 100644 --- a/java/broker/src/main/java/org/apache/qpid/server/handler/QueueDeclareHandler.java +++ b/java/broker/src/main/java/org/apache/qpid/server/handler/QueueDeclareHandler.java @@ -93,8 +93,15 @@ public class QueueDeclareHandler implements StateAwareMethodListener foundMessagesList = getMessagesOnTheQueue(fromMessageId, toMessageId); - // move messages to another queue - anotherQueue.startMovingMessages(); - anotherQueue.enqueueMovedMessages(storeContext, foundMessagesList); + try + { + fromStore.beginTran(storeContext); + + // Move the messages in on the message store. + for (AMQMessage message : foundMessagesList) + { + fromStore.dequeueMessage(storeContext, _name, message.getMessageId()); + toStore.enqueueMessage(storeContext, toQueue._name, message.getMessageId()); + } + + // Commit and flush the move transcations. + try + { + fromStore.commitTran(storeContext); + } + catch (AMQException e) + { + throw new RuntimeException("Failed to commit transaction whilst moving messages on message store.", e); + } + + // Move the messages on the in-memory queues. + toQueue.enqueueMovedMessages(storeContext, foundMessagesList); + _deliveryMgr.removeMovedMessages(foundMessagesList); + } + // Abort the move transactions on move failures. + catch (AMQException e) + { + try + { + fromStore.abortTran(storeContext); + } + catch (AMQException ae) + { + throw new RuntimeException("Failed to abort transaction whilst moving messages on message store.", ae); + } + } + } + // Release locks to allow activity on the queues being moved between to continue. + finally + { + toQueue.stopMovingMessages(); + stopMovingMessages(); + } + } + + /** + * Copies messages on this queue to another queue, and also commits the move on the message store. Delivery activity + * on the queues being moved between is suspended during the move. + * + * @param fromMessageId The first message id to move. + * @param toMessageId The last message id to move. + * @param queueName The queue to move the messages to. + * @param storeContext The context of the message store under which to perform the move. This is associated with + * the stores transactional context. + */ + public synchronized void copyMessagesToAnotherQueue(long fromMessageId, long toMessageId, String queueName, + StoreContext storeContext) + { + AMQQueue toQueue = getVirtualHost().getQueueRegistry().getQueue(new AMQShortString(queueName)); + + MessageStore fromStore = getVirtualHost().getMessageStore(); + MessageStore toStore = toQueue.getVirtualHost().getMessageStore(); - // moving is successful, now remove from original queue - _deliveryMgr.removeMovedMessages(foundMessagesList); + if (toStore != fromStore) + { + throw new RuntimeException("Can only move messages between queues on the same message store."); } + + try + { + // Obtain locks to prevent activity on the queues being moved between. + startMovingMessages(); + toQueue.startMovingMessages(); + + // Get the list of messages to move. + List foundMessagesList = getMessagesOnTheQueue(fromMessageId, toMessageId); + + try + { + fromStore.beginTran(storeContext); + + // Move the messages in on the message store. + for (AMQMessage message : foundMessagesList) + { + toStore.enqueueMessage(storeContext, toQueue._name, message.getMessageId()); + message.takeReference(); + } + + // Commit and flush the move transcations. + try + { + fromStore.commitTran(storeContext); + } + catch (AMQException e) + { + throw new RuntimeException("Failed to commit transaction whilst moving messages on message store.", e); + } + + // Move the messages on the in-memory queues. + toQueue.enqueueMovedMessages(storeContext, foundMessagesList); + } + // Abort the move transactions on move failures. + catch (AMQException e) + { + try + { + fromStore.abortTran(storeContext); + } + catch (AMQException ae) + { + throw new RuntimeException("Failed to abort transaction whilst moving messages on message store.", ae); + } + } + } + // Release locks to allow activity on the queues being moved between to continue. + finally + { + toQueue.stopMovingMessages(); + stopMovingMessages(); + } + } + + /** + * Removes messages from this queue, and also commits the remove on the message store. Delivery activity + * on the queues being moved between is suspended during the remove. + * + * @param fromMessageId The first message id to move. + * @param toMessageId The last message id to move. + * @param storeContext The context of the message store under which to perform the move. This is associated with + * the stores transactional context. + */ + public synchronized void removeMessagesFromQueue(long fromMessageId, long toMessageId, StoreContext storeContext) + { + MessageStore fromStore = getVirtualHost().getMessageStore(); + + try + { + // Obtain locks to prevent activity on the queues being moved between. + startMovingMessages(); + + // Get the list of messages to move. + List foundMessagesList = getMessagesOnTheQueue(fromMessageId, toMessageId); + + try + { + fromStore.beginTran(storeContext); + + // remove the messages in on the message store. + for (AMQMessage message : foundMessagesList) + { + fromStore.dequeueMessage(storeContext, _name, message.getMessageId()); + } + + // Commit and flush the move transcations. + try + { + fromStore.commitTran(storeContext); + } + catch (AMQException e) + { + throw new RuntimeException("Failed to commit transaction whilst moving messages on message store.", e); + } + + // remove the messages on the in-memory queues. + _deliveryMgr.removeMovedMessages(foundMessagesList); + } + // Abort the move transactions on move failures. + catch (AMQException e) + { + try + { + fromStore.abortTran(storeContext); + } + catch (AMQException ae) + { + throw new RuntimeException("Failed to abort transaction whilst moving messages on message store.", ae); + } + } + } + // Release locks to allow activity on the queues being moved between to continue. finally { - // remove the lock and start the async delivery - anotherQueue.stopMovingMessages(); stopMovingMessages(); } } @@ -458,7 +639,7 @@ public class AMQQueue implements Managable, Comparable, StorableQueue } public void registerProtocolSession(AMQProtocolSession ps, int channel, AMQShortString consumerTag, boolean acks, - FieldTable filters, boolean noLocal, boolean exclusive) throws AMQException + FieldTable filters, boolean noLocal, boolean exclusive) throws AMQException { if (incrementSubscriberCount() > 1) { @@ -481,13 +662,12 @@ public class AMQQueue implements Managable, Comparable, StorableQueue if (_logger.isDebugEnabled()) { - _logger.debug(MessageFormat.format( - "Registering protocol session {0} with channel {1} and " + "consumer tag {2} with {3}", ps, channel, - consumerTag, this)); + _logger.debug(MessageFormat.format("Registering protocol session {0} with channel {1} and " + + "consumer tag {2} with {3}", ps, channel, consumerTag, this)); } Subscription subscription = - _subscriptionFactory.createSubscription(channel, ps, consumerTag, acks, filters, noLocal, this); + _subscriptionFactory.createSubscription(channel, ps, consumerTag, acks, filters, noLocal, this); if (subscription.filtersMessages()) { @@ -525,8 +705,8 @@ public class AMQQueue implements Managable, Comparable, StorableQueue if (_logger.isDebugEnabled()) { _logger.debug(MessageFormat.format( - "Unregistering protocol session {0} with channel {1} and consumer tag {2} from {3}", ps, channel, - consumerTag, this)); + "Unregistering protocol session {0} with channel {1} and consumer tag {2} from {3}", + ps, channel, consumerTag, this)); } Subscription removedSubscription; diff --git a/java/broker/src/main/java/org/apache/qpid/server/queue/AMQQueueMBean.java b/java/broker/src/main/java/org/apache/qpid/server/queue/AMQQueueMBean.java index bbaa7379f6..07872d7644 100644 --- a/java/broker/src/main/java/org/apache/qpid/server/queue/AMQQueueMBean.java +++ b/java/broker/src/main/java/org/apache/qpid/server/queue/AMQQueueMBean.java @@ -18,30 +18,23 @@ * under the License. * */ -/* - * - * Copyright (c) 2006 The Apache Software Foundation - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ package org.apache.qpid.server.queue; -import java.text.SimpleDateFormat; -import java.util.ArrayList; -import java.util.Date; -import java.util.Iterator; -import java.util.List; +import org.apache.log4j.Logger; + +import org.apache.mina.common.ByteBuffer; + +import org.apache.qpid.AMQException; +import org.apache.qpid.framing.AMQShortString; +import org.apache.qpid.framing.BasicContentHeaderProperties; +import org.apache.qpid.framing.CommonContentHeaderProperties; +import org.apache.qpid.framing.ContentHeaderBody; +import org.apache.qpid.framing.abstraction.ContentChunk; +import org.apache.qpid.server.management.AMQManagedObject; +import org.apache.qpid.server.management.MBeanConstructor; +import org.apache.qpid.server.management.MBeanDescription; +import org.apache.qpid.server.management.ManagedObject; +import org.apache.qpid.server.store.StoreContext; import javax.management.JMException; import javax.management.MBeanException; @@ -60,30 +53,25 @@ import javax.management.openmbean.TabularData; import javax.management.openmbean.TabularDataSupport; import javax.management.openmbean.TabularType; -import org.apache.log4j.Logger; - -import org.apache.mina.common.ByteBuffer; - -import org.apache.qpid.AMQException; -import org.apache.qpid.framing.AMQShortString; -import org.apache.qpid.framing.BasicContentHeaderProperties; -import org.apache.qpid.framing.CommonContentHeaderProperties; -import org.apache.qpid.framing.ContentHeaderBody; -import org.apache.qpid.framing.abstraction.ContentChunk; -import org.apache.qpid.server.management.AMQManagedObject; -import org.apache.qpid.server.management.MBeanConstructor; -import org.apache.qpid.server.management.MBeanDescription; -import org.apache.qpid.server.management.ManagedObject; -import org.apache.qpid.server.store.StoreContext; +import java.text.SimpleDateFormat; +import java.util.ArrayList; +import java.util.Date; +import java.util.Iterator; +import java.util.List; /** - * MBean class for AMQQueue. It implements all the management features exposed - * for an AMQQueue. + * AMQQueueMBean is the management bean for an {@link AMQQueue}. + * + *

CRC Caption + * Responsibilities Collaborations + * */ @MBeanDescription("Management Interface for AMQQueue") public class AMQQueueMBean extends AMQManagedObject implements ManagedQueue, QueueNotificationListener { + /** Used for debugging purposes. */ private static final Logger _logger = Logger.getLogger(AMQQueueMBean.class); + private static final SimpleDateFormat _dateFormat = new SimpleDateFormat("MM-dd-yy HH:mm:ss.SSS z"); /** diff --git a/java/broker/src/main/java/org/apache/qpid/server/queue/ConcurrentSelectorDeliveryManager.java b/java/broker/src/main/java/org/apache/qpid/server/queue/ConcurrentSelectorDeliveryManager.java index 2aa759b35d..907d68b733 100644 --- a/java/broker/src/main/java/org/apache/qpid/server/queue/ConcurrentSelectorDeliveryManager.java +++ b/java/broker/src/main/java/org/apache/qpid/server/queue/ConcurrentSelectorDeliveryManager.java @@ -20,19 +20,6 @@ */ package org.apache.qpid.server.queue; -import java.util.ArrayList; -import java.util.Iterator; -import java.util.List; -import java.util.Queue; -import java.util.Set; -import java.util.Collections; -import java.util.HashSet; -import java.util.concurrent.Executor; -import java.util.concurrent.atomic.AtomicBoolean; -import java.util.concurrent.atomic.AtomicLong; -import java.util.concurrent.atomic.AtomicInteger; -import java.util.concurrent.locks.ReentrantLock; - import org.apache.log4j.Logger; import org.apache.qpid.AMQException; import org.apache.qpid.configuration.Configured; @@ -42,8 +29,21 @@ import org.apache.qpid.server.AMQChannel; import org.apache.qpid.server.configuration.Configurator; import org.apache.qpid.server.protocol.AMQProtocolSession; import org.apache.qpid.server.store.StoreContext; -import org.apache.qpid.util.MessageQueue; import org.apache.qpid.util.ConcurrentLinkedMessageQueueAtomicSize; +import org.apache.qpid.util.MessageQueue; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashSet; +import java.util.Iterator; +import java.util.List; +import java.util.Queue; +import java.util.Set; +import java.util.concurrent.Executor; +import java.util.concurrent.atomic.AtomicBoolean; +import java.util.concurrent.atomic.AtomicInteger; +import java.util.concurrent.atomic.AtomicLong; +import java.util.concurrent.locks.ReentrantLock; /** Manages delivery of messages on behalf of a queue */ @@ -87,6 +87,10 @@ public class ConcurrentSelectorDeliveryManager implements DeliveryManager private final Object _queueHeadLock = new Object(); private String _processingThreadName = ""; + + /** Used by any reaping thread to purge messages */ + private StoreContext _reapingStoreContext = new StoreContext(); + ConcurrentSelectorDeliveryManager(SubscriptionManager subscriptions, AMQQueue queue) { @@ -453,12 +457,31 @@ public class ConcurrentSelectorDeliveryManager implements DeliveryManager //while (we have a message) && ((The subscriber is not a browser or message is taken ) or we are clearing) && (Check message is taken.) while (purgeMessage(message, sub)) { + // if we are purging then ensure we mark this message taken for the current subscriber + // the current subscriber may be null in the case of a get or a purge but this is ok. +// boolean alreadyTaken = message.taken(_queue, sub); + //remove the already taken message or expired AMQMessage removed = messages.poll(); assert removed == message; - _totalMessageSize.addAndGet(-message.getSize()); + // if the message expired then the _totalMessageSize needs adjusting + if (message.expired(_queue)) + { + _totalMessageSize.addAndGet(-message.getSize()); + + // Use the reapingStoreContext as any sub(if we have one) may be in a tx. + message.dequeue(_reapingStoreContext, _queue); + + if (_log.isInfoEnabled()) + { + _log.info(debugIdentity() + " Doing clean up of the main _message queue."); + } + } + + //else the clean up is not required as the message has already been taken for this queue therefore + // it was the responsibility of the code that took the message to ensure the _totalMessageSize was updated. if (_log.isTraceEnabled()) { @@ -473,7 +496,10 @@ public class ConcurrentSelectorDeliveryManager implements DeliveryManager } /** - * + * This method will return true if the message is to be purged from the queue. + * + * + * SIDE-EFFECT: The message will be taken by the Subscription(sub) for the current Queue(_queue) * @param message * @param sub * @return @@ -493,15 +519,15 @@ public class ConcurrentSelectorDeliveryManager implements DeliveryManager // if the message is null then don't purge as we have no messagse. if (message != null) { + // Check that the message hasn't expired. + if (message.expired(_queue)) + { + return true; + } + // if we have a subscriber perform message checks if (sub != null) { - // Check that the message hasn't expired. - if (message.expired(sub.getChannel().getStoreContext(), _queue)) - { - return true; - } - // if we have a queue browser(we don't purge) so check mark the message as taken purge = ((!sub.isBrowser() || message.isTaken(_queue))); } @@ -606,7 +632,10 @@ public class ConcurrentSelectorDeliveryManager implements DeliveryManager { if (_log.isInfoEnabled()) { - _log.info(debugIdentity() + "We could do clean up of the main _message queue here"); + //fixme - we should do the clean up as the message remains on the _message queue + // this is resulting in the next consumer receiving the message and then attempting to purge it + // + _log.info(debugIdentity() + "We should do clean up of the main _message queue here"); } } @@ -617,7 +646,14 @@ public class ConcurrentSelectorDeliveryManager implements DeliveryManager } catch (AMQException e) { - message.release(_queue); + if (message != null) + { + message.release(_queue); + } + else + { + _log.error(debugIdentity() + "Unable to release message as it is null. " + e, e); + } _log.error(debugIdentity() + "Unable to deliver message as dequeue failed: " + e, e); } } @@ -696,25 +732,6 @@ public class ConcurrentSelectorDeliveryManager implements DeliveryManager } -// private void sendNextMessage(Subscription sub) -// { -// if (sub.filtersMessages()) -// { -// sendNextMessage(sub, sub.getPreDeliveryQueue()); -// if (sub.isAutoClose()) -// { -// if (sub.getPreDeliveryQueue().isEmpty()) -// { -// sub.close(); -// } -// } -// } -// else -// { -// sendNextMessage(sub, _messages); -// } -// } - public void deliver(StoreContext context, AMQShortString name, AMQMessage msg, boolean deliverFirst) throws AMQException { @@ -723,8 +740,6 @@ public class ConcurrentSelectorDeliveryManager implements DeliveryManager { _log.debug(debugIdentity() + "deliver :first(" + deliverFirst + ") :" + msg); } - // This shouldn't be done here. -// msg.release(); //Check if we have someone to deliver the message to. _lock.lock(); @@ -800,7 +815,7 @@ public class ConcurrentSelectorDeliveryManager implements DeliveryManager if (debugEnabled) { _log.debug(debugIdentity() + " Subscription(" + System.identityHashCode(s) + ") became " + - "suspended between nextSubscriber and send for message:" + msg.debugIdentity()); + "suspended between nextSubscriber and send for message:" + msg.debugIdentity()); } } } @@ -810,7 +825,7 @@ public class ConcurrentSelectorDeliveryManager implements DeliveryManager if (debugEnabled) { _log.debug(debugIdentity() + " Message(" + msg.debugIdentity() + ") has not been taken so recursing!:" + - " Subscriber:" + System.identityHashCode(s)); + " Subscriber:" + System.identityHashCode(s)); } deliver(context, name, msg, deliverFirst); diff --git a/java/broker/src/main/java/org/apache/qpid/server/queue/DefaultQueueRegistry.java b/java/broker/src/main/java/org/apache/qpid/server/queue/DefaultQueueRegistry.java index c0f1e7f40c..cbe9246f09 100644 --- a/java/broker/src/main/java/org/apache/qpid/server/queue/DefaultQueueRegistry.java +++ b/java/broker/src/main/java/org/apache/qpid/server/queue/DefaultQueueRegistry.java @@ -20,13 +20,14 @@ */ package org.apache.qpid.server.queue; -import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.ConcurrentMap; - import org.apache.qpid.AMQException; import org.apache.qpid.framing.AMQShortString; import org.apache.qpid.server.virtualhost.VirtualHost; +import java.util.Collection; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ConcurrentMap; + public class DefaultQueueRegistry implements QueueRegistry { private ConcurrentMap _queueMap = new ConcurrentHashMap(); @@ -57,4 +58,14 @@ public class DefaultQueueRegistry implements QueueRegistry { return _queueMap.get(name); } + + public Collection getQueueNames() + { + return _queueMap.keySet(); + } + + public Collection getQueues() + { + return _queueMap.values(); + } } diff --git a/java/broker/src/main/java/org/apache/qpid/server/queue/ExchangeBindings.java b/java/broker/src/main/java/org/apache/qpid/server/queue/ExchangeBindings.java index a8247aa2db..60c1a8f574 100644 --- a/java/broker/src/main/java/org/apache/qpid/server/queue/ExchangeBindings.java +++ b/java/broker/src/main/java/org/apache/qpid/server/queue/ExchangeBindings.java @@ -46,7 +46,7 @@ class ExchangeBindings ExchangeBinding(AMQShortString routingKey, Exchange exchange) { - this(routingKey, exchange,EMPTY_ARGUMENTS); + this(routingKey, exchange, EMPTY_ARGUMENTS); } ExchangeBinding(AMQShortString routingKey, Exchange exchange, FieldTable arguments) @@ -80,7 +80,10 @@ class ExchangeBindings public boolean equals(Object o) { - if (!(o instanceof ExchangeBinding)) return false; + if (!(o instanceof ExchangeBinding)) + { + return false; + } ExchangeBinding eb = (ExchangeBinding) o; return _exchange.equals(eb._exchange) && _routingKey.equals(eb._routingKey) @@ -104,16 +107,16 @@ class ExchangeBindings */ void addBinding(AMQShortString routingKey, FieldTable arguments, Exchange exchange) { - _bindings.add(new ExchangeBinding(routingKey, exchange, arguments )); + _bindings.add(new ExchangeBinding(routingKey, exchange, arguments)); } public void remove(AMQShortString routingKey, FieldTable arguments, Exchange exchange) { - _bindings.remove(new ExchangeBinding(routingKey, exchange, arguments )); + _bindings.remove(new ExchangeBinding(routingKey, exchange, arguments)); } - + /** * Deregisters this queue from any exchange it has been bound to */ diff --git a/java/broker/src/main/java/org/apache/qpid/server/queue/MessageMetaData.java b/java/broker/src/main/java/org/apache/qpid/server/queue/MessageMetaData.java index 285f05fb20..6118a4c11f 100644 --- a/java/broker/src/main/java/org/apache/qpid/server/queue/MessageMetaData.java +++ b/java/broker/src/main/java/org/apache/qpid/server/queue/MessageMetaData.java @@ -1,18 +1,22 @@ /* * - * Copyright (c) 2006 The Apache Software Foundation + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * http://www.apache.org/licenses/LICENSE-2.0 * - * http://www.apache.org/licenses/LICENSE-2.0 + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. */ package org.apache.qpid.server.queue; diff --git a/java/broker/src/main/java/org/apache/qpid/server/queue/NotificationCheck.java b/java/broker/src/main/java/org/apache/qpid/server/queue/NotificationCheck.java index 00ccffdea1..6b3d65661f 100644 --- a/java/broker/src/main/java/org/apache/qpid/server/queue/NotificationCheck.java +++ b/java/broker/src/main/java/org/apache/qpid/server/queue/NotificationCheck.java @@ -1,18 +1,21 @@ /* * - * Copyright (c) 2006 The Apache Software Foundation + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * http://www.apache.org/licenses/LICENSE-2.0 * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. * */ package org.apache.qpid.server.queue; diff --git a/java/broker/src/main/java/org/apache/qpid/server/queue/QueueNotificationListener.java b/java/broker/src/main/java/org/apache/qpid/server/queue/QueueNotificationListener.java index 9554d34f00..959ca03c80 100644 --- a/java/broker/src/main/java/org/apache/qpid/server/queue/QueueNotificationListener.java +++ b/java/broker/src/main/java/org/apache/qpid/server/queue/QueueNotificationListener.java @@ -1,22 +1,26 @@ /* * - * Copyright (c) 2006 The Apache Software Foundation + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * http://www.apache.org/licenses/LICENSE-2.0 * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. * */ package org.apache.qpid.server.queue; + public interface QueueNotificationListener { void notifyClients(NotificationCheck notification, AMQQueue queue, String notificationMsg); diff --git a/java/broker/src/main/java/org/apache/qpid/server/queue/QueueRegistry.java b/java/broker/src/main/java/org/apache/qpid/server/queue/QueueRegistry.java index ed2101fd75..13c150f82b 100644 --- a/java/broker/src/main/java/org/apache/qpid/server/queue/QueueRegistry.java +++ b/java/broker/src/main/java/org/apache/qpid/server/queue/QueueRegistry.java @@ -25,6 +25,7 @@ import org.apache.qpid.framing.AMQShortString; import org.apache.qpid.server.virtualhost.VirtualHost; import org.apache.qpid.server.messageStore.StorableQueue; +import java.util.Collection; public interface QueueRegistry { @@ -35,4 +36,9 @@ public interface QueueRegistry void unregisterQueue(AMQShortString name) throws AMQException; AMQQueue getQueue(AMQShortString name); + + Collection getQueueNames(); + + Collection getQueues(); + } diff --git a/java/broker/src/main/java/org/apache/qpid/server/queue/TransientMessageData.java b/java/broker/src/main/java/org/apache/qpid/server/queue/TransientMessageData.java index 7c8064789e..79ee6b93a3 100644 --- a/java/broker/src/main/java/org/apache/qpid/server/queue/TransientMessageData.java +++ b/java/broker/src/main/java/org/apache/qpid/server/queue/TransientMessageData.java @@ -1,18 +1,21 @@ /* * - * Copyright (c) 2006 The Apache Software Foundation + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * http://www.apache.org/licenses/LICENSE-2.0 * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. * */ package org.apache.qpid.server.queue; diff --git a/java/broker/src/main/java/org/apache/qpid/server/security/Passwd.java b/java/broker/src/main/java/org/apache/qpid/server/security/Passwd.java deleted file mode 100644 index f9e093dba7..0000000000 --- a/java/broker/src/main/java/org/apache/qpid/server/security/Passwd.java +++ /dev/null @@ -1,81 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - * - * - */ -package org.apache.qpid.server.security; - -import org.apache.commons.codec.binary.Base64; - -import java.security.MessageDigest; -import java.security.NoSuchAlgorithmException; -import java.security.DigestException; -import java.io.File; -import java.io.FileWriter; -import java.io.IOException; -import java.io.PrintStream; - -public class Passwd -{ - public static void main(String args[]) throws NoSuchAlgorithmException, DigestException, IOException - { - if (args.length != 2) - { - System.out.println("Passwd "); - System.exit(0); - } - - byte[] data = args[1].getBytes("utf-8"); - - MessageDigest md = MessageDigest.getInstance("MD5"); - - for (byte b : data) - { - md.update(b); - } - - byte[] digest = md.digest(); - - Base64 b64 = new Base64(); - - byte[] encoded = b64.encode(digest); - - output(args[0], encoded); - } - - private static void output(String user, byte[] encoded) throws IOException - { - -// File passwdFile = new File("qpid.passwd"); - - PrintStream ps = new PrintStream(System.out); - - user += ":"; - ps.write(user.getBytes("utf-8")); - - for (byte b : encoded) - { - ps.write(b); - } - - ps.println(); - - ps.flush(); - ps.close(); - } -} diff --git a/java/broker/src/main/java/org/apache/qpid/server/txn/NonTransactionalContext.java b/java/broker/src/main/java/org/apache/qpid/server/txn/NonTransactionalContext.java index 8becaf52b9..d9500429af 100644 --- a/java/broker/src/main/java/org/apache/qpid/server/txn/NonTransactionalContext.java +++ b/java/broker/src/main/java/org/apache/qpid/server/txn/NonTransactionalContext.java @@ -1,18 +1,21 @@ /* * - * Copyright (c) 2006 The Apache Software Foundation + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * http://www.apache.org/licenses/LICENSE-2.0 * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. * */ package org.apache.qpid.server.txn; diff --git a/java/broker/src/main/java/org/apache/qpid/server/txn/TransactionalContext.java b/java/broker/src/main/java/org/apache/qpid/server/txn/TransactionalContext.java index 88451e2fca..fee25c07df 100644 --- a/java/broker/src/main/java/org/apache/qpid/server/txn/TransactionalContext.java +++ b/java/broker/src/main/java/org/apache/qpid/server/txn/TransactionalContext.java @@ -28,24 +28,144 @@ import org.apache.qpid.server.queue.AMQQueue; import org.apache.qpid.server.store.StoreContext; /** - * @author Robert Greig (robert.j.greig@jpmorgan.com) + * TransactionalContext provides a context in which transactional operations on {@link AMQMessage}s are performed. + * Different levels of transactional support for the delivery of messages may be provided by different implementations + * of this interface. + * + *

The fundamental transactional operations that can be performed on a message queue are 'enqueue' and 'dequeue'. + * In this interface, these have been recast as the {@link #messageFullyReceived} and {@link #acknowledgeMessage} + * operations. This interface essentially provides a way to make enqueueing and dequeuing transactional. + * + *

+ *
CRC Card
Responsibilities + *
Explicitly accept a transaction start notification. + *
Commit all pending operations in a transaction. + *
Rollback all pending operations in a transaction. + *
Deliver a message to a queue as part of a transaction. + *
Redeliver a message to a queue as part of a transaction. + *
Mark a message as acknowledged as part of a transaction. + *
Accept notification that a message has been completely received as part of a transaction. + *
Accept notification that a message has been fully processed as part of a transaction. + *
Associate a message store context with this transaction context. + *
+ * + * @todo The 'fullyReceived' and 'messageProcessed' events sit uncomfortably in the responsibilities of a transactional + * context. They are non-transactional operations, used to trigger other side-effects. Consider moving them + * somewhere else, a seperate interface for example. + * + * @todo This transactional context could be written as a wrapper extension to a Queue implementation, that provides + * transactional management of the enqueue and dequeue operations, with added commit/rollback methods. Any + * queue implementation could be made transactional by wrapping it as a transactional queue. This would mean + * that the enqueue/dequeue operations do not need to be recast as deliver/acknowledge operations, which may be + * conceptually neater. + * + * For example: + *

+ * public interface Transactional
+ * {
+ *    public void commit();
+ *    public void rollback();
+ * }
+ *
+ * public interface TransactionalQueue extends Transactional, SizeableQueue
+ * {}
+ *
+ * public class Queues
+ * {
+ *    ...
+ *    // For transactional messaging, take a transactional view onto the queue.
+ *    public static  TransactionalQueue getTransactionalQueue(SizeableQueue queue) { ... }
+ *
+ *    // For non-transactional messaging, take a non-transactional view onto the queue.
+ *    public static  TransactionalQueue getNonTransactionalQueue(SizeableQueue queue) { ... }
+ * }
+ * 
*/ public interface TransactionalContext { + /** + * Explicitly begins the transaction, if it has not already been started. {@link #commit} or {@link #rollback} + * should automatically begin the next transaction in the chain. + * + * @throws AMQException If the transaction cannot be started for any reason. + */ void beginTranIfNecessary() throws AMQException; + /** + * Makes all pending operations on the transaction permanent and visible. + * + * @throws AMQException If the transaction cannot be committed for any reason. + */ void commit() throws AMQException; + /** + * Erases all pending operations on the transaction. + * + * @throws AMQException If the transaction cannot be committed for any reason. + */ void rollback() throws AMQException; + /** + * Delivers the specified message to the specified queue. A 'deliverFirst' flag may be set if the message is a + * redelivery, and should be placed on the front of the queue. + * + *

This is an 'enqueue' operation. + * + * @param message The message to deliver. + * @param queue The queue to deliver the message to. + * @param deliverFirst true to place the message on the front of the queue for redelivery, false + * for normal FIFO message ordering. + * + * @throws AMQException If the message cannot be delivered for any reason. + */ void deliver(AMQMessage message, AMQQueue queue, boolean deliverFirst) throws AMQException; + /** + * Acknowledges a message or many messages as delivered. All messages up to a specified one, may be acknowledged by + * setting the 'multiple' flag. It is also possible for the acknowledged message id to be zero, when the 'multiple' + * flag is set, in which case an acknowledgement up to the latest delivered message should be done. + * + *

This is a 'dequeue' operation. + * + * @param deliveryTag The id of the message to acknowledge, or zero, if using multiple acknowledgement + * up to the latest message. + * @param lastDeliveryTag The latest message delivered. + * @param multiple true if all message ids up the acknowledged one or latest delivered, are + * to be acknowledged, false otherwise. + * @param unacknowledgedMessageMap The unacknowledged messages in the transaction, to remove the acknowledged message + * from. + * + * @throws AMQException If the message cannot be acknowledged for any reason. + */ void acknowledgeMessage(long deliveryTag, long lastDeliveryTag, boolean multiple, - UnacknowledgedMessageMap unacknowledgedMessageMap) throws AMQException; + UnacknowledgedMessageMap unacknowledgedMessageMap) throws AMQException; + /** + * Notifies the transactional context that a message has been fully received. The actual message that was received + * is not specified. This event may be used to trigger a process related to the receipt of the message, for example, + * flushing its data to disk. + * + * @param persistent true if the received message is persistent, false otherwise. + * + * @throws AMQException If the fully received event cannot be processed for any reason. + */ void messageFullyReceived(boolean persistent) throws AMQException; + /** + * Notifies the transactional context that a message has been delivered, succesfully or otherwise. The actual + * message that was delivered is not specified. This event may be used to trigger a process related to the + * outcome of the delivery of the message, for example, cleaning up failed deliveries. + * + * @param protocolSession The protocol session of the deliverable message. + * + * @throws AMQException If the message processed event cannot be handled for any reason. + */ void messageProcessed(AMQProtocolSession protocolSession) throws AMQException; + /** + * Gets the message store context associated with this transactional context. + * + * @return The message store context associated with this transactional context. + */ StoreContext getStoreContext(); } diff --git a/java/broker/src/main/java/org/apache/qpid/server/virtualhost/VirtualHost.java b/java/broker/src/main/java/org/apache/qpid/server/virtualhost/VirtualHost.java index 6638689299..235555c58b 100644 --- a/java/broker/src/main/java/org/apache/qpid/server/virtualhost/VirtualHost.java +++ b/java/broker/src/main/java/org/apache/qpid/server/virtualhost/VirtualHost.java @@ -1,3 +1,4 @@ +<<<<<<< .working /* * * Licensed to the Apache Software Foundation (ASF) under one @@ -286,3 +287,264 @@ public class VirtualHost implements Accessable } } +======= +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +package org.apache.qpid.server.virtualhost; + +import javax.management.NotCompliantMBeanException; + +import org.apache.commons.configuration.Configuration; +import org.apache.log4j.Logger; +import org.apache.qpid.server.AMQBrokerManagerMBean; +import org.apache.qpid.server.security.access.AccessManager; +import org.apache.qpid.server.security.access.AccessManagerImpl; +import org.apache.qpid.server.security.access.Accessable; +import org.apache.qpid.server.security.auth.manager.PrincipalDatabaseAuthenticationManager; +import org.apache.qpid.server.security.auth.manager.AuthenticationManager; +import org.apache.qpid.server.configuration.Configurator; +import org.apache.qpid.server.exchange.DefaultExchangeFactory; +import org.apache.qpid.server.exchange.DefaultExchangeRegistry; +import org.apache.qpid.server.exchange.ExchangeFactory; +import org.apache.qpid.server.exchange.ExchangeRegistry; +import org.apache.qpid.server.management.AMQManagedObject; +import org.apache.qpid.server.management.ManagedObject; +import org.apache.qpid.server.queue.DefaultQueueRegistry; +import org.apache.qpid.server.queue.QueueRegistry; +import org.apache.qpid.server.registry.ApplicationRegistry; +import org.apache.qpid.server.store.MessageStore; + +public class VirtualHost implements Accessable +{ + private static final Logger _logger = Logger.getLogger(VirtualHost.class); + + + private final String _name; + + private QueueRegistry _queueRegistry; + + private ExchangeRegistry _exchangeRegistry; + + private ExchangeFactory _exchangeFactory; + + private MessageStore _messageStore; + + protected VirtualHostMBean _virtualHostMBean; + + private AMQBrokerManagerMBean _brokerMBean; + + private AuthenticationManager _authenticationManager; + + private AccessManager _accessManager; + + + public void setAccessableName(String name) + { + _logger.warn("Setting Accessable Name for VirualHost is not allowed. (" + + name + ") ignored remains :" + getAccessableName()); + } + + public String getAccessableName() + { + return _name; + } + + + /** + * Abstract MBean class. This has some of the methods implemented from management intrerface for exchanges. Any + * implementaion of an Exchange MBean should extend this class. + */ + public class VirtualHostMBean extends AMQManagedObject implements ManagedVirtualHost + { + public VirtualHostMBean() throws NotCompliantMBeanException + { + super(ManagedVirtualHost.class, "VirtualHost"); + } + + public String getObjectInstanceName() + { + return _name.toString(); + } + + public String getName() + { + return _name.toString(); + } + + public VirtualHost getVirtualHost() + { + return VirtualHost.this; + } + + + } // End of MBean class + + /** + * Used for testing only + * @param name + * @param store + * @throws Exception + */ + public VirtualHost(String name, MessageStore store) throws Exception + { + this(name, null, store); + } + + /** + * Normal Constructor + * @param name + * @param hostConfig + * @throws Exception + */ + public VirtualHost(String name, Configuration hostConfig) throws Exception + { + this(name, hostConfig, null); + } + + private VirtualHost(String name, Configuration hostConfig, MessageStore store) throws Exception + { + _name = name; + + _virtualHostMBean = new VirtualHostMBean(); + // This isn't needed to be registered + //_virtualHostMBean.register(); + + _queueRegistry = new DefaultQueueRegistry(this); + _exchangeFactory = new DefaultExchangeFactory(this); + _exchangeRegistry = new DefaultExchangeRegistry(this); + + if (store != null) + { + _messageStore = store; + } + else + { + if (hostConfig == null) + { + throw new IllegalAccessException("HostConfig and MessageStore cannot be null"); + } + initialiseMessageStore(hostConfig); + } + + _exchangeRegistry.initialise(); + + _authenticationManager = new PrincipalDatabaseAuthenticationManager(name, hostConfig); + + _accessManager = new AccessManagerImpl(name, hostConfig); + + _brokerMBean = new AMQBrokerManagerMBean(_virtualHostMBean); + _brokerMBean.register(); + } + + private void initialiseMessageStore(Configuration config) throws Exception + { + String messageStoreClass = config.getString("store.class"); + + Class clazz = Class.forName(messageStoreClass); + Object o = clazz.newInstance(); + + if (!(o instanceof MessageStore)) + { + throw new ClassCastException("Message store class must implement " + MessageStore.class + ". Class " + clazz + + " does not."); + } + _messageStore = (MessageStore) o; + _messageStore.configure(this, "store", config); + } + + + public T getConfiguredObject(Class instanceType, Configuration config) + { + T instance; + try + { + instance = instanceType.newInstance(); + } + catch (Exception e) + { + _logger.error("Unable to instantiate configuration class " + instanceType + " - ensure it has a public default constructor"); + throw new IllegalArgumentException("Unable to instantiate configuration class " + instanceType + " - ensure it has a public default constructor", e); + } + Configurator.configure(instance); + + return instance; + } + + + public String getName() + { + return _name; + } + + public QueueRegistry getQueueRegistry() + { + return _queueRegistry; + } + + public ExchangeRegistry getExchangeRegistry() + { + return _exchangeRegistry; + } + + public ExchangeFactory getExchangeFactory() + { + return _exchangeFactory; + } + + public ApplicationRegistry getApplicationRegistry() + { + throw new UnsupportedOperationException(); + } + + public MessageStore getMessageStore() + { + return _messageStore; + } + + public AuthenticationManager getAuthenticationManager() + { + return _authenticationManager; + } + + public AccessManager getAccessManager() + { + return _accessManager; + } + + public void close() throws Exception + { + if (_messageStore != null) + { + _messageStore.close(); + } + } + + public ManagedObject getBrokerMBean() + { + return _brokerMBean; + } + + public ManagedObject getManagedObject() + { + return _virtualHostMBean; + } +} +>>>>>>> .merge-right.r553432 diff --git a/java/broker/src/main/java/org/apache/qpid/tools/messagestore/MessageStoreTool.java b/java/broker/src/main/java/org/apache/qpid/tools/messagestore/MessageStoreTool.java new file mode 100644 index 0000000000..afa7916074 --- /dev/null +++ b/java/broker/src/main/java/org/apache/qpid/tools/messagestore/MessageStoreTool.java @@ -0,0 +1,648 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + * + */ +package org.apache.qpid.tools.messagestore; + +import org.apache.commons.cli.Option; +import org.apache.commons.cli.OptionBuilder; +import org.apache.commons.configuration.ConfigurationException; +import org.apache.qpid.configuration.Configuration; +import org.apache.qpid.server.exchange.Exchange; +import org.apache.qpid.server.queue.AMQQueue; +import org.apache.qpid.server.registry.ApplicationRegistry; +import org.apache.qpid.server.registry.ConfigurationFileApplicationRegistry; +import org.apache.qpid.server.store.MemoryMessageStore; +import org.apache.qpid.server.virtualhost.VirtualHost; +import org.apache.qpid.tools.messagestore.commands.Clear; +import org.apache.qpid.tools.messagestore.commands.Command; +import org.apache.qpid.tools.messagestore.commands.Copy; +import org.apache.qpid.tools.messagestore.commands.Dump; +import org.apache.qpid.tools.messagestore.commands.Help; +import org.apache.qpid.tools.messagestore.commands.List; +import org.apache.qpid.tools.messagestore.commands.Load; +import org.apache.qpid.tools.messagestore.commands.Quit; +import org.apache.qpid.tools.messagestore.commands.Select; +import org.apache.qpid.tools.messagestore.commands.Show; +import org.apache.qpid.tools.utils.CommandParser; +import org.apache.qpid.tools.utils.Console; +import org.apache.qpid.tools.utils.SimpleCommandParser; +import org.apache.qpid.tools.utils.SimpleConsole; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.BufferedReader; +import java.io.BufferedWriter; +import java.io.File; +import java.io.FileReader; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.io.OutputStream; +import java.io.OutputStreamWriter; +import java.util.Collection; +import java.util.HashMap; +import java.util.LinkedList; +import java.util.Map; +import java.util.StringTokenizer; + +/** + * MessageStoreTool. + */ +public class MessageStoreTool +{ + /** Text outputted at the start of each console.*/ + private static final String BOILER_PLATE = "MessageStoreTool - for examining Persistent Qpid Broker MessageStore instances"; + + /** I/O Wrapper. */ + protected Console _console; + + /** Batch mode flag. */ + protected boolean _batchMode; + + /** Internal State object. */ + private State _state = new State(); + + private HashMap _commands = new HashMap(); + + /** SLF4J Logger. */ + private static Logger _devlog = LoggerFactory.getLogger(MessageStoreTool.class); + + /** Loaded configuration file. */ + private Configuration _config; + + /** Control used for main run loop. */ + private boolean _running = true; + private boolean _initialised = false; + + //---------------------------------------------------------------------------------------------------/ + + public static void main(String[] args) throws Configuration.InitException + { + + MessageStoreTool tool = new MessageStoreTool(args); + + tool.start(); + } + + + public MessageStoreTool(String[] args) throws Configuration.InitException + { + this(args, System.in, System.out); + } + + public MessageStoreTool(String[] args, InputStream in, OutputStream out) throws Configuration.InitException + { + BufferedReader consoleReader = new BufferedReader(new InputStreamReader(in)); + BufferedWriter consoleWriter = new BufferedWriter(new OutputStreamWriter(out)); + + Runtime.getRuntime().addShutdownHook(new Thread(new ShutdownHook(this))); + _batchMode = false; + + _console = new SimpleConsole(consoleWriter, consoleReader); + + _config = new Configuration(); + + setOptions(); + _config.processCommandline(args); + } + + + private void setOptions() + { + Option help = new Option("h", "help", false, "print this message"); + Option version = new Option("v", "version", false, "print the version information and exit"); + Option configFile = + OptionBuilder.withArgName("file").hasArg() + .withDescription("use given configuration file By " + + "default looks for a file named " + + Configuration.DEFAULT_CONFIG_FILE + " in " + Configuration.QPID_HOME) + .withLongOpt("config") + .create("c"); + + _config.setOption(help); + _config.setOption(version); + _config.setOption(configFile); + } + + public State getState() + { + return _state; + } + + public Map getCommands() + { + return _commands; + } + + public void setConfigurationFile(String configfile) throws Configuration.InitException + { + _config.loadConfig(new File(configfile)); + setup(); + } + + public Console getConsole() + { + return _console; + } + + public void setConsole(Console console) + { + _console = console; + } + + /** + * Simple ShutdownHook to cleanly shutdown the databases + */ + class ShutdownHook implements Runnable + { + MessageStoreTool _tool; + + ShutdownHook(MessageStoreTool messageStoreTool) + { + _tool = messageStoreTool; + } + + public void run() + { + _tool.quit(); + } + } + + public void quit() + { + _running = false; + + if (_initialised) + { + ApplicationRegistry.remove(1); + } + + _console.println("...exiting"); + + _console.close(); + } + + public void setBatchMode(boolean batchmode) + { + _batchMode = batchmode; + } + + /** + * Main loop + */ + protected void start() + { + setup(); + + if (!_initialised) + { + System.exit(1); + } + + _console.println(""); + + _console.println(BOILER_PLATE); + + runCLI(); + } + + private void setup() + { + loadDefaultVirtualHosts(); + + loadCommands(); + + _state.clearAll(); + } + + private void loadCommands() + { + _commands.clear(); + //todo Dynamically load the classes that exis in com.redhat.etp.qpid.commands + _commands.put("close", new Clear(this)); + _commands.put("copy", new Copy(this)); + _commands.put("dump", new Dump(this)); + _commands.put("help", new Help(this)); + _commands.put("list", new List(this)); + _commands.put("load", new Load(this)); + _commands.put("quit", new Quit(this)); + _commands.put("select", new Select(this)); + _commands.put("show", new Show(this)); + } + + private void loadDefaultVirtualHosts() + { + final File configFile = _config.getConfigFile(); + + loadVirtualHosts(configFile); + } + + private void loadVirtualHosts(File configFile) + { + + if (!configFile.exists()) + { + _devlog.error("Config file not found:" + configFile.getAbsolutePath()); + return; + } + else + { + _devlog.debug("using config file :" + configFile.getAbsolutePath()); + } + + try + { + ConfigurationFileApplicationRegistry registry = new ConfigurationFileApplicationRegistry(configFile); + + ApplicationRegistry.remove(1); + + ApplicationRegistry.initialise(registry); + + checkMessageStores(); + _initialised = true; + } + catch (ConfigurationException e) + { + _console.println("Unable to load configuration due to configuration error: " + e.getMessage()); + e.printStackTrace(); + } + catch (Exception e) + { + _console.println("Unable to load configuration due to: " + e.getMessage()); + e.printStackTrace(); + } + + + } + + private void checkMessageStores() + { + Collection vhosts = ApplicationRegistry.getInstance().getVirtualHostRegistry().getVirtualHosts(); + + boolean warning = false; + for (VirtualHost vhost : vhosts) + { + if (vhost.getMessageStore() instanceof MemoryMessageStore) + { + _console.println("WARNING: Virtualhost '" + vhost.getName() + "' is using a MemoryMessageStore. " + + "Changes will not persist."); + warning = true; + } + } + + if (warning) + { + _console.println(""); + _console.println("Please ensure you are using the correct config file currently using '" + + _config.getConfigFile().getAbsolutePath() + "'"); + _console.println("New config file can be specifed by 'load ' or -c on the commandline."); + _console.println(""); + } + } + + private void runCLI() + { + while (_running) + { + if (!_batchMode) + { + printPrompt(); + } + + String[] args = _console.readCommand(); + + while (args != null) + { + exec(args); + + if (_running) + { + if (!_batchMode) + { + printPrompt(); + } + + args = _console.readCommand(); + } + } + } + } + + private void printPrompt() + { + _console.print(prompt()); + } + + + /** + * Execute a script (batch mode). + * + * @param script The file script + */ + protected void runScripts(String script) + { + //Store Current State + boolean oldBatch = _batchMode; + CommandParser oldParser = _console.getCommandParser(); + setBatchMode(true); + + try + { + _devlog.debug("Running script '" + script + "'"); + + _console.setCommandParser(new SimpleCommandParser(new BufferedReader(new FileReader(script)))); + + start(); + } + catch (java.io.FileNotFoundException e) + { + _devlog.error("Script not found: '" + script + "' due to:" + e.getMessage()); + } + + //Restore previous state + _console.setCommandParser(oldParser); + setBatchMode(oldBatch); + } + + public String prompt() + { + String state = _state.toString(); + if (state != null && state.length() != 0) + { + return state + ":bdb$ "; + } + else + { + return "bdb$ "; + } + } + + /** + * Execute the command. + * + * @param args [command, arg0, arg1...]. + */ + protected void exec(String[] args) + { + // Comment lines start with a # + if (args.length == 0 || args[0].startsWith("#")) + { + return; + } + + final String command = args[0]; + + Command cmd = _commands.get(command); + + if (cmd == null) + { + _console.println("Command not understood: " + command); + } + else + { + cmd.execute(args); + } + } + + + /** + * Displays usage info. + */ + protected static void help() + { + System.out.println(BOILER_PLATE); + System.out.println("Usage: java " + MessageStoreTool.class + " [Options]"); + System.out.println(" [-c ] : Defaults to \"$QPID_HOME/etc/config.xml\""); + } + + + /** + * This class is used to store the current state of the tool. + * + * This is then interrogated by the various commands to augment their behaviour. + * + * + */ + public class State + { + private VirtualHost _vhost = null; + private AMQQueue _queue = null; + private Exchange _exchange = null; + private java.util.List _msgids = null; + + public State() + { + } + + public void setQueue(AMQQueue queue) + { + _queue = queue; + } + + public AMQQueue getQueue() + { + return _queue; + } + + public void setVhost(VirtualHost vhost) + { + _vhost = vhost; + } + + public VirtualHost getVhost() + { + return _vhost; + } + + public Exchange getExchange() + { + return _exchange; + } + + public void setExchange(Exchange exchange) + { + _exchange = exchange; + } + + public String toString() + { + StringBuilder status = new StringBuilder(); + + if (_vhost != null) + { + status.append(_vhost.getName()); + + if (_exchange != null) + { + status.append("["); + status.append(_exchange.getName()); + status.append("]"); + + if (_queue != null) + { + status.append("->'"); + status.append(_queue.getName()); + status.append("'"); + + if (_msgids != null) + { + status.append(printMessages()); + } + } + } + } + + return status.toString(); + } + + + public String printMessages() + { + StringBuilder sb = new StringBuilder(); + + Long previous = null; + + Long start = null; + for (Long id : _msgids) + { + if (previous != null) + { + if (id == previous + 1) + { + if (start == null) + { + start = previous; + } + } + else + { + if (start != null) + { + sb.append(","); + sb.append(start); + sb.append("-"); + sb.append(id); + start = null; + } + else + { + sb.append(","); + sb.append(previous); + } + } + } + + previous = id; + } + + if (start != null) + { + sb.append(","); + sb.append(start); + sb.append("-"); + sb.append(_msgids.get(_msgids.size() - 1)); + } + else + { + sb.append(","); + sb.append(previous); + } + + // surround list in () + sb.replace(0, 1, "("); + sb.append(")"); + return sb.toString(); + } + + public void clearAll() + { + _vhost = null; + clearExchange(); + } + + public void clearExchange() + { + _exchange = null; + clearQueue(); + } + + public void clearQueue() + { + _queue = null; + clearMessages(); + } + + public void clearMessages() + { + _msgids = null; + } + + /** + * A common location to provide parsing of the message id string + * utilised by a number of the commands. + * The String is comma separated list of ids that can be individual ids + * or a range (4-10) + * + * @param msgString string of msg ids to parse 1,2,4-10 + */ + public void setMessages(String msgString) + { + StringTokenizer tok = new StringTokenizer(msgString, ","); + + if (tok.hasMoreTokens()) + { + _msgids = new LinkedList(); + } + + while (tok.hasMoreTokens()) + { + String next = tok.nextToken(); + if (next.contains("-")) + { + Long start = Long.parseLong(next.substring(0, next.indexOf("-"))); + Long end = Long.parseLong(next.substring(next.indexOf("-") + 1)); + + if (end >= start) + { + for (long l = start; l <= end; l++) + { + _msgids.add(l); + } + } + } + else + { + _msgids.add(Long.parseLong(next)); + } + } + + } + + public void setMessages(java.util.List msgids) + { + _msgids = msgids; + } + + public java.util.List getMessages() + { + return _msgids; + } + }//Class State + +}//Class MessageStoreTool diff --git a/java/broker/src/main/java/org/apache/qpid/tools/messagestore/commands/AbstractCommand.java b/java/broker/src/main/java/org/apache/qpid/tools/messagestore/commands/AbstractCommand.java new file mode 100644 index 0000000000..5444197cb4 --- /dev/null +++ b/java/broker/src/main/java/org/apache/qpid/tools/messagestore/commands/AbstractCommand.java @@ -0,0 +1,66 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + * + */ +package org.apache.qpid.tools.messagestore.commands; + +import org.apache.qpid.tools.messagestore.MessageStoreTool; +import org.apache.qpid.tools.utils.Console; + +public abstract class AbstractCommand implements Command +{ + protected Console _console; + protected MessageStoreTool _tool; + + public AbstractCommand(MessageStoreTool tool) + { + _console = tool.getConsole(); + _tool = tool; + } + + public void setOutput(Console out) + { + _console = out; + } + + protected void commandError(String message, String[] args) + { + _console.print(getCommand() + " : " + message); + + if (args != null) + { + for (int i = 1; i < args.length; i++) + { + _console.print(args[i]); + } + } + _console.println(""); + _console.println(help()); + } + + + public abstract String help(); + + public abstract String usage(); + + public abstract String getCommand(); + + + public abstract void execute(String... args); +} diff --git a/java/broker/src/main/java/org/apache/qpid/tools/messagestore/commands/Clear.java b/java/broker/src/main/java/org/apache/qpid/tools/messagestore/commands/Clear.java new file mode 100644 index 0000000000..b0006b3fe6 --- /dev/null +++ b/java/broker/src/main/java/org/apache/qpid/tools/messagestore/commands/Clear.java @@ -0,0 +1,85 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + * + */ +package org.apache.qpid.tools.messagestore.commands; + +import org.apache.qpid.tools.messagestore.MessageStoreTool; + +public class Clear extends AbstractCommand +{ + public Clear(MessageStoreTool tool) + { + super(tool); + } + + public String help() + { + return "Clears any selection."; + } + + public String usage() + { + return "clear [ all | virtualhost | exchange | queue | msgs ]"; + } + + public String getCommand() + { + return "clear"; + } + + public void execute(String... args) + { + assert args.length > 0; + assert args[0].equals(getCommand()); + + if (args.length < 1) + { + doClose("all"); + } + else + { + doClose(args[1]); + } + } + + private void doClose(String type) + { + if (type.equals("virtualhost") + || type.equals("all")) + { + _tool.getState().clearAll(); + } + + if (type.equals("exchange")) + { + _tool.getState().clearExchange(); + } + + if (type.equals("queue")) + { + _tool.getState().clearQueue(); + } + + if (type.equals("msgs")) + { + _tool.getState().clearMessages(); + } + } +} diff --git a/java/broker/src/main/java/org/apache/qpid/tools/messagestore/commands/Command.java b/java/broker/src/main/java/org/apache/qpid/tools/messagestore/commands/Command.java new file mode 100644 index 0000000000..bfa775a34a --- /dev/null +++ b/java/broker/src/main/java/org/apache/qpid/tools/messagestore/commands/Command.java @@ -0,0 +1,36 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + * + */ +package org.apache.qpid.tools.messagestore.commands; + +import org.apache.qpid.tools.utils.Console; + +public interface Command +{ + public void setOutput(Console out); + + public String help(); + + public abstract String usage(); + + String getCommand(); + + public void execute(String... args); +} diff --git a/java/broker/src/main/java/org/apache/qpid/tools/messagestore/commands/Copy.java b/java/broker/src/main/java/org/apache/qpid/tools/messagestore/commands/Copy.java new file mode 100644 index 0000000000..96ecb36952 --- /dev/null +++ b/java/broker/src/main/java/org/apache/qpid/tools/messagestore/commands/Copy.java @@ -0,0 +1,56 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + * + */ +package org.apache.qpid.tools.messagestore.commands; + +import org.apache.qpid.server.queue.AMQQueue; +import org.apache.qpid.server.store.StoreContext; +import org.apache.qpid.tools.messagestore.MessageStoreTool; + +public class Copy extends Move +{ + public Copy(MessageStoreTool tool) + { + super(tool); + } + + public String help() + { + return "Copy messages between queues.\n" + + "The currently selected message set will be copied to the specifed queue.\n" + + "Alternatively the values can be provided on the command line."; + } + + public String usage() + { + return "copy to= [from=] [msgids=]"; + } + + public String getCommand() + { + return "copy"; + } + + protected void doCommand(AMQQueue fromQueue, long start, long end, AMQQueue toQueue, StoreContext storeContext) + { + fromQueue.copyMessagesToAnotherQueue(start, end, toQueue.getName().toString(), storeContext); + } + +} diff --git a/java/broker/src/main/java/org/apache/qpid/tools/messagestore/commands/Dump.java b/java/broker/src/main/java/org/apache/qpid/tools/messagestore/commands/Dump.java new file mode 100644 index 0000000000..eea53252c6 --- /dev/null +++ b/java/broker/src/main/java/org/apache/qpid/tools/messagestore/commands/Dump.java @@ -0,0 +1,299 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + * + */ +package org.apache.qpid.tools.messagestore.commands; + +import org.apache.commons.codec.binary.Hex; +import org.apache.mina.common.ByteBuffer; +import org.apache.qpid.framing.abstraction.ContentChunk; +import org.apache.qpid.server.queue.AMQMessage; +import org.apache.qpid.tools.messagestore.MessageStoreTool; +import org.apache.qpid.tools.utils.Console; + +import java.io.UnsupportedEncodingException; +import java.util.Iterator; +import java.util.LinkedList; +import java.util.List; + +public class Dump extends Show +{ + private static final int LINE_SIZE = 8; + private static final String DEFAULT_ENCODING = "utf-8"; + private static final boolean SPACE_BYTES = true; + private static final String BYTE_SPACER = " "; + private static final String NON_PRINTING_ASCII_CHAR = "?"; + + protected boolean _content = true; + + public Dump(MessageStoreTool tool) + { + super(tool); + } + + public String help() + { + return "Dump selected message content. Default: show=content"; + } + + public String usage() + { + return getCommand() + " [show=[all],[msgheaders],[_amqHeaders],[routing],[content]] [id=]"; + } + + public String getCommand() + { + return "dump"; + } + + public void execute(String... args) + { + assert args.length > 0; + assert args[0].equals(getCommand()); + + + if (args.length >= 2) + { + for (String arg : args) + { + if (arg.startsWith("show=")) + { + _content = arg.contains("content") || arg.contains("all"); + } + } + + parseArgs(args); + } + + performShow(); + } + + + protected List createMessageData(java.util.List msgids, List messages, boolean showHeaders, boolean showRouting, + boolean showMessageHeaders) + { + + List display = new LinkedList(); + + List hex = new LinkedList(); + List ascii = new LinkedList(); + display.add(hex); + display.add(ascii); + + for (AMQMessage msg : messages) + { + if (!includeMsg(msg, msgids)) + { + continue; + } + + //Add divider between messages + hex.add(Console.ROW_DIVIDER); + ascii.add(Console.ROW_DIVIDER); + + // Show general message information + hex.add(Show.Columns.ID.name()); + ascii.add(msg.getMessageId().toString()); + + hex.add(Console.ROW_DIVIDER); + ascii.add(Console.ROW_DIVIDER); + + if (showRouting) + { + addShowInformation(hex, ascii, msg, "Routing Details", true, false, false); + } + if (showHeaders) + { + addShowInformation(hex, ascii, msg, "Headers", false, true, false); + } + if (showMessageHeaders) + { + addShowInformation(hex, ascii, msg, null, false, false, true); + } + + // Add Content Body seciont + hex.add("Content Body"); + ascii.add(""); + hex.add(Console.ROW_DIVIDER); + ascii.add(Console.ROW_DIVIDER); + + Iterator bodies = msg.getContentBodyIterator(); + if (bodies.hasNext()) + { + + hex.add("Hex"); + hex.add(Console.ROW_DIVIDER); + + + ascii.add("ASCII"); + ascii.add(Console.ROW_DIVIDER); + + while (bodies.hasNext()) + { + ContentChunk chunk = (ContentChunk) bodies.next(); + + //Duplicate so we don't destroy original data :) + ByteBuffer hexBuffer = chunk.getData().duplicate(); + + ByteBuffer charBuffer = hexBuffer.duplicate(); + + Hex hexencoder = new Hex(); + + while (hexBuffer.hasRemaining()) + { + byte[] line = new byte[LINE_SIZE]; + + int bufsize = hexBuffer.remaining(); + if (bufsize < LINE_SIZE) + { + hexBuffer.get(line, 0, bufsize); + } + else + { + bufsize = line.length; + hexBuffer.get(line); + } + + byte[] encoded = hexencoder.encode(line); + + try + { + String encStr = new String(encoded, 0, bufsize * 2, DEFAULT_ENCODING); + String hexLine = ""; + + int strKength = encStr.length(); + for (int c = 0; c < strKength; c++) + { + hexLine += encStr.charAt(c); + + if (c % 2 == 1 && SPACE_BYTES) + { + hexLine += BYTE_SPACER; + } + } + + hex.add(hexLine); + } + catch (UnsupportedEncodingException e) + { + _console.println(e.getMessage()); + return null; + } + } + + while (charBuffer.hasRemaining()) + { + String asciiLine = ""; + + for (int pos = 0; pos < LINE_SIZE; pos++) + { + if (charBuffer.hasRemaining()) + { + byte ch = charBuffer.get(); + + if (isPrintable(ch)) + { + asciiLine += (char) ch; + } + else + { + asciiLine += NON_PRINTING_ASCII_CHAR; + } + + if (SPACE_BYTES) + { + asciiLine += BYTE_SPACER; + } + } + else + { + break; + } + } + + ascii.add(asciiLine); + } + } + } + else + { + List result = new LinkedList(); + + display.add(result); + result.add("No ContentBodies"); + } + } + + // if hex is empty then we have no data to display + if (hex.size() == 0) + { + return null; + } + + return display; + } + + private void addShowInformation(List column1, List column2, AMQMessage msg, + String title, boolean routing, boolean headers, boolean messageHeaders) + { + List single = new LinkedList(); + single.add(msg); + + List routingData = super.createMessageData(null, single, headers, routing, messageHeaders); + + //Reformat data + if (title != null) + { + column1.add(title); + column2.add(""); + column1.add(Console.ROW_DIVIDER); + column2.add(Console.ROW_DIVIDER); + } + + // look at all columns in the routing Data + for (List item : routingData) + { + // the item should be: + // Title + // *divider + // value + // otherwise we can't reason about the correct value + if (item.size() == 3) + { + //Filter out the columns we are not interested in. + + String columnName = item.get(0).toString(); + + if (!(columnName.equals(Show.Columns.ID.name()) + || columnName.equals(Show.Columns.Size.name()))) + { + column1.add(columnName); + column2.add(item.get(2).toString()); + } + } + } + column1.add(Console.ROW_DIVIDER); + column2.add(Console.ROW_DIVIDER); + } + + private boolean isPrintable(byte c) + { + return c > 31 && c < 127; + } +} diff --git a/java/broker/src/main/java/org/apache/qpid/tools/messagestore/commands/Help.java b/java/broker/src/main/java/org/apache/qpid/tools/messagestore/commands/Help.java new file mode 100644 index 0000000000..0f9546541b --- /dev/null +++ b/java/broker/src/main/java/org/apache/qpid/tools/messagestore/commands/Help.java @@ -0,0 +1,98 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + * + */ +package org.apache.qpid.tools.messagestore.commands; + +import org.apache.qpid.tools.messagestore.MessageStoreTool; +import org.apache.qpid.tools.utils.Console; + +import java.util.LinkedList; +import java.util.Map; + +public class Help extends AbstractCommand +{ + public Help(MessageStoreTool tool) + { + super(tool); + } + + public String help() + { + return "Provides detailed help on commands."; + } + + public String getCommand() + { + return "help"; + } + + public String usage() + { + return "help []"; + } + + public void execute(String... args) + { + assert args.length > 0; + assert args[0].equals(getCommand()); + + if (args.length > 1) + { + Command command = _tool.getCommands().get(args[1]); + if (command != null) + { + _console.println(command.help()); + _console.println("Usage:" + command.usage()); + } + else + { + commandError("Command not found: ", args); + } + } + else + { + java.util.List data = new LinkedList(); + + java.util.List commandName = new LinkedList(); + java.util.List commandDescription = new LinkedList(); + + data.add(commandName); + data.add(commandDescription); + + //Set up Headers + commandName.add("Command"); + commandDescription.add("Description"); + + commandName.add(Console.ROW_DIVIDER); + commandDescription.add(Console.ROW_DIVIDER); + + //Add current Commands with descriptions + Map commands = _tool.getCommands(); + + for (Command command : commands.values()) + { + commandName.add(command.getCommand()); + commandDescription.add(command.help()); + } + + _console.printMap("Available Commands", data); + } + } +} diff --git a/java/broker/src/main/java/org/apache/qpid/tools/messagestore/commands/List.java b/java/broker/src/main/java/org/apache/qpid/tools/messagestore/commands/List.java new file mode 100644 index 0000000000..df8b59ec19 --- /dev/null +++ b/java/broker/src/main/java/org/apache/qpid/tools/messagestore/commands/List.java @@ -0,0 +1,314 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + * + */ +package org.apache.qpid.tools.messagestore.commands; + +import org.apache.qpid.framing.AMQShortString; +import org.apache.qpid.server.exchange.Exchange; +import org.apache.qpid.server.queue.AMQQueue; +import org.apache.qpid.server.registry.ApplicationRegistry; +import org.apache.qpid.server.virtualhost.VirtualHost; +import org.apache.qpid.tools.messagestore.MessageStoreTool; +import org.apache.qpid.tools.utils.Console; + +import java.util.Collection; +import java.util.LinkedList; + +public class List extends AbstractCommand +{ + + public List(MessageStoreTool tool) + { + super(tool); + } + + public void setOutput(Console out) + { + _console = out; + } + + public String help() + { + return "list available items."; + } + + public String usage() + { + return "list queues [] | exchanges | bindings [] | all"; + } + + public String getCommand() + { + return "list"; + } + + public void execute(String... args) + { + assert args.length > 0; + assert args[0].equals(getCommand()); + + if (args.length > 1) + { + if ((args[1].equals("exchanges")) + || (args[1].equals("queues")) + || (args[1].equals("bindings")) + || (args[1].equals("all"))) + { + if (args.length == 2) + { + doList(args[1]); + } + else if (args.length == 3) + { + doList(args[1], args[2]); + } + } + else + { + commandError("Unknown options. ", args); + } + } + else if (args.length < 2) + { + doList("all"); + } + else + { + doList(args[1]); + } + } + + private void doList(String... listItem) + { + if (_tool.getState().getVhost() == null) + { + _console.println("No Virtualhost open. Open a Virtualhost first."); + listVirtualHosts(); + return; + } + + VirtualHost vhost = _tool.getState().getVhost(); + + java.util.List data = null; + + if (listItem[0].equals("queues")) + { + if (listItem.length > 1) + { + data = listQueues(vhost, new AMQShortString(listItem[1])); + } + else + { + Exchange exchange = _tool.getState().getExchange(); + data = listQueues(vhost, exchange); + } + } + + if (listItem[0].equals("exchanges")) + { + data = listExchanges(vhost); + } + + if (listItem[0].equals("bindings")) + { + + if (listItem.length > 1) + { + data = listBindings(vhost, new AMQShortString(listItem[1])); + } + else + { + Exchange exchange = _tool.getState().getExchange(); + + data = listBindings(vhost, exchange); + } + } + + if (data != null) + { + if (data.size() == 1) + { + _console.println("No '" + listItem[0] + "' to display,"); + } + else + { + _console.displayList(true, data.toArray(new String[0])); + } + } + + + if (listItem[0].equals("all")) + { + + boolean displayed = false; + Exchange exchange = _tool.getState().getExchange(); + + //Do the display here for each one so that they are pretty printed + data = listQueues(vhost, exchange); + if (data != null) + { + displayed = true; + _console.displayList(true, data.toArray(new String[0])); + } + + if (exchange == null) + { + data = listExchanges(vhost); + if (data != null) + { + displayed = true; + _console.displayList(true, data.toArray(new String[0])); + } + } + + data = listBindings(vhost, exchange); + if (data != null) + { + displayed = true; + _console.displayList(true, data.toArray(new String[0])); + } + + if (!displayed) + { + _console.println("Nothing to list"); + } + } + } + + private void listVirtualHosts() + { + Collection vhosts = ApplicationRegistry.getInstance() + .getVirtualHostRegistry().getVirtualHosts(); + + String[] data = new String[vhosts.size() + 1]; + + data[0] = "Available VirtualHosts"; + + int index = 1; + for (VirtualHost vhost : vhosts) + { + data[index] = vhost.getName(); + index++; + } + + _console.displayList(true, data); + } + + private java.util.List listBindings(VirtualHost vhost, AMQShortString exchangeName) + { + return listBindings(vhost, vhost.getExchangeRegistry().getExchange(exchangeName)); + } + + private java.util.List listBindings(VirtualHost vhost, Exchange exchange) + { + Collection queues = vhost.getQueueRegistry().getQueueNames(); + + if (queues == null || queues.size() == 0) + { + return null; + } + + java.util.List data = new LinkedList(); + + data.add("Current Bindings"); + + for (AMQShortString queue : queues) + { + if (exchange != null) + { + if (exchange.isBound(queue)) + { + data.add(queue.toString()); + } + } + else + { + data.add(queue.toString()); + } + } + + return data; + } + + private java.util.List listExchanges(VirtualHost vhost) + { + Collection queues = vhost.getExchangeRegistry().getExchangeNames(); + + if (queues == null || queues.size() == 0) + { + return null; + } + + java.util.List data = new LinkedList(); + + data.add("Available Exchanges"); + + for (AMQShortString queue : queues) + { + data.add(queue.toString()); + } + + return data; + } + + private java.util.List listQueues(VirtualHost vhost, AMQShortString exchangeName) + { + return listQueues(vhost, vhost.getExchangeRegistry().getExchange(exchangeName)); + } + + private java.util.List listQueues(VirtualHost vhost, Exchange exchange) + { + Collection queues = vhost.getQueueRegistry().getQueues(); + + if (queues == null || queues.size() == 0) + { + return null; + } + + java.util.List data = new LinkedList(); + + data.add("Available Queues"); + + for (AMQQueue queue : queues) + { + if (exchange != null) + { + if (exchange.isBound(queue)) + { + data.add(queue.getName().toString()); + } + } + else + { + data.add(queue.getName().toString()); + } + } + + if (exchange != null) + { + if (queues.size() == 1) + { + return null; + } + } + + return data; + } +} diff --git a/java/broker/src/main/java/org/apache/qpid/tools/messagestore/commands/Load.java b/java/broker/src/main/java/org/apache/qpid/tools/messagestore/commands/Load.java new file mode 100644 index 0000000000..244a311c30 --- /dev/null +++ b/java/broker/src/main/java/org/apache/qpid/tools/messagestore/commands/Load.java @@ -0,0 +1,94 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + * + */ +package org.apache.qpid.tools.messagestore.commands; + +import org.apache.qpid.configuration.Configuration; +import org.apache.qpid.tools.messagestore.MessageStoreTool; + +public class Load extends AbstractCommand +{ + public Load(MessageStoreTool tool) + { + super(tool); + } + + public String help() + { + return "Loads specified broker configuration file."; + } + + public String usage() + { + return "load "; + } + + public String getCommand() + { + return "load"; + } + + public void execute(String... args) + { + assert args.length > 0; + assert args[0].equals(getCommand()); + + if (args.length > 2) + { + _console.print("load " + args[1] + ": additional options not understood:"); + for (int i = 2; i < args.length; i++) + { + _console.print(args[i] + " "); + } + _console.println(""); + } + else if (args.length < 2) + { + _console.println("Enter Configuration file."); + String input = _console.readln(); + if (input != null) + { + doLoad(input); + } + else + { + _console.println("Did not recognise config file."); + } + } + else + { + doLoad(args[1]); + } + } + + private void doLoad(String configfile) + { + _console.println("Loading Configuration:" + configfile); + + try + { + _tool.setConfigurationFile(configfile); + } + catch (Configuration.InitException e) + { + _console.println("Unable to open config file due to: '" + e.getMessage() + "'"); + } + } +} diff --git a/java/broker/src/main/java/org/apache/qpid/tools/messagestore/commands/Move.java b/java/broker/src/main/java/org/apache/qpid/tools/messagestore/commands/Move.java new file mode 100644 index 0000000000..a9497fd23e --- /dev/null +++ b/java/broker/src/main/java/org/apache/qpid/tools/messagestore/commands/Move.java @@ -0,0 +1,166 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + * + */ +package org.apache.qpid.tools.messagestore.commands; + +import org.apache.qpid.framing.AMQShortString; +import org.apache.qpid.server.queue.AMQQueue; +import org.apache.qpid.server.store.StoreContext; +import org.apache.qpid.tools.messagestore.MessageStoreTool; + +import java.util.List; + +public class Move extends AbstractCommand +{ + + /** + * Since the Coopy command is not associated with a real channel we can safely create our own store context + * for use in the few methods that require one. + */ + private StoreContext _storeContext = new StoreContext(); + + public Move(MessageStoreTool tool) + { + super(tool); + } + + public String help() + { + return "Move messages between queues.\n" + + "The currently selected message set will be moved to the specifed queue.\n" + + "Alternatively the values can be provided on the command line."; + } + + public String usage() + { + return "move to= [from=] [msgids=]"; + } + + public String getCommand() + { + return "move"; + } + + public void execute(String... args) + { + AMQQueue toQueue = null; + AMQQueue fromQueue = _tool.getState().getQueue(); + java.util.List msgids = _tool.getState().getMessages(); + + if (args.length >= 2) + { + for (String arg : args) + { + if (arg.startsWith("to=")) + { + String queueName = arg.substring(arg.indexOf("=") + 1); + toQueue = _tool.getState().getVhost().getQueueRegistry().getQueue(new AMQShortString(queueName)); + } + + if (arg.startsWith("from=")) + { + String queueName = arg.substring(arg.indexOf("=") + 1); + fromQueue = _tool.getState().getVhost().getQueueRegistry().getQueue(new AMQShortString(queueName)); + } + + if (arg.startsWith("msgids=")) + { + String msgidStr = arg.substring(arg.indexOf("=") + 1); + + // Record the current message selection + java.util.List currentIDs = _tool.getState().getMessages(); + + // Use the ToolState class to perform the messasge parsing + _tool.getState().setMessages(msgidStr); + msgids = _tool.getState().getMessages(); + + // Reset the original selection of messages + _tool.getState().setMessages(currentIDs); + } + } + } + + if (!checkRequirements(fromQueue, toQueue, msgids)) + { + return; + } + + processIDs(fromQueue, toQueue, msgids); + } + + private void processIDs(AMQQueue fromQueue, AMQQueue toQueue, java.util.List msgids) + { + Long previous = null; + Long start = null; + + for (long id : msgids) + { + if (previous != null) + { + if (id == previous + 1) + { + if (start == null) + { + start = previous; + } + } + else + { + if (start != null) + { + //move a range of ids + doCommand(fromQueue, start, id, toQueue, _storeContext); + } + else + { + //move a single id + doCommand(fromQueue, id, id, toQueue, _storeContext); + } + } + } + + previous = id; + } + } + + protected boolean checkRequirements(AMQQueue fromQueue, AMQQueue toQueue, List msgids) + { + if (toQueue == null) + { + _console.println("Destination queue not specifed."); + _console.println(usage()); + return false; + } + + if (fromQueue == null) + { + _console.println("Source queue not specifed."); + _console.println(usage()); + return false; + } + + return true; + } + + protected void doCommand(AMQQueue fromQueue, long start, long id, AMQQueue toQueue, StoreContext storeContext) + { + fromQueue.moveMessagesToAnotherQueue(start, id, toQueue.getName().toString(), _storeContext); + } +} diff --git a/java/broker/src/main/java/org/apache/qpid/tools/messagestore/commands/Purge.java b/java/broker/src/main/java/org/apache/qpid/tools/messagestore/commands/Purge.java new file mode 100644 index 0000000000..7154159b40 --- /dev/null +++ b/java/broker/src/main/java/org/apache/qpid/tools/messagestore/commands/Purge.java @@ -0,0 +1,68 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + * + */ +package org.apache.qpid.tools.messagestore.commands; + +import org.apache.qpid.server.queue.AMQQueue; +import org.apache.qpid.server.store.StoreContext; +import org.apache.qpid.tools.messagestore.MessageStoreTool; + +public class Purge extends Move +{ + public Purge(MessageStoreTool tool) + { + super(tool); + } + + public String help() + { + return "Purge messages from a queue.\n" + + "The currently selected message set will be purged from the specifed queue.\n" + + "Alternatively the values can be provided on the command line."; + } + + public String usage() + { + return "purge from= [msgids=]"; + } + + public String getCommand() + { + return "purge"; + } + + + protected boolean checkRequirements(AMQQueue fromQueue, AMQQueue toQueue, java.util.List msgids) + { + if (fromQueue == null) + { + _console.println("Source queue not specifed."); + _console.println(usage()); + return false; + } + + return true; + } + + protected void doCommand(AMQQueue fromQueue, long start, long end, AMQQueue toQueue, StoreContext storeContext) + { + fromQueue.removeMessagesFromQueue(start, end, storeContext); + } +} diff --git a/java/broker/src/main/java/org/apache/qpid/tools/messagestore/commands/Quit.java b/java/broker/src/main/java/org/apache/qpid/tools/messagestore/commands/Quit.java new file mode 100644 index 0000000000..a81bc07c38 --- /dev/null +++ b/java/broker/src/main/java/org/apache/qpid/tools/messagestore/commands/Quit.java @@ -0,0 +1,54 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + * + */ +package org.apache.qpid.tools.messagestore.commands; + +import org.apache.qpid.tools.messagestore.MessageStoreTool; + +public class Quit extends AbstractCommand +{ + public Quit(MessageStoreTool tool) + { + super(tool); + } + + public String help() + { + return "Quit the tool."; + } + + public String usage() + { + return "quit"; + } + + public String getCommand() + { + return "quit"; + } + + public void execute(String... args) + { + assert args.length > 0; + assert args[0].equals("quit"); + + _tool.quit(); + } +} diff --git a/java/broker/src/main/java/org/apache/qpid/tools/messagestore/commands/Select.java b/java/broker/src/main/java/org/apache/qpid/tools/messagestore/commands/Select.java new file mode 100644 index 0000000000..5e9b7028e9 --- /dev/null +++ b/java/broker/src/main/java/org/apache/qpid/tools/messagestore/commands/Select.java @@ -0,0 +1,233 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + * + */ +package org.apache.qpid.tools.messagestore.commands; + +import org.apache.qpid.framing.AMQShortString; +import org.apache.qpid.server.exchange.Exchange; +import org.apache.qpid.server.queue.AMQQueue; +import org.apache.qpid.server.registry.ApplicationRegistry; +import org.apache.qpid.server.virtualhost.VirtualHost; +import org.apache.qpid.tools.messagestore.MessageStoreTool; + +import java.util.LinkedList; +import java.util.StringTokenizer; + +public class Select extends AbstractCommand +{ + + public Select(MessageStoreTool tool) + { + super(tool); + } + + public String help() + { + return "Perform a selection."; + } + + public String usage() + { + return "select virtualhost |exchange |queue | msgs id="; + } + + public String getCommand() + { + return "select"; + } + + public void execute(String... args) + { + assert args.length > 2; + assert args[0].equals("select"); + + if (args.length < 3) + { + if (args[1].equals("show")) + { + doSelect(args[1], null); + } + else + { + _console.print("select : unknown command:"); + _console.println(help()); + } + } + else + { + if (args[1].equals("virtualhost") + || args[1].equals("vhost") + || args[1].equals("exchange") + || args[1].equals("queue") + || args[1].equals("msg") + ) + { + doSelect(args[1], args[2]); + } + else + { + _console.println(help()); + } + } + } + + private void doSelect(String type, String item) + { + if (type.equals("virtualhost")) + { + + VirtualHost vhost = ApplicationRegistry.getInstance() + .getVirtualHostRegistry().getVirtualHost(item); + + if (vhost == null) + { + _console.println("Virtualhost '" + item + "' not found."); + } + else + { + _tool.getState().setVhost(vhost); + } + } + + if (type.equals("exchange")) + { + + VirtualHost vhost = _tool.getState().getVhost(); + + if (vhost == null) + { + _console.println("No Virtualhost open. Open a Virtualhost first."); + return; + } + + + Exchange exchange = vhost.getExchangeRegistry().getExchange(new AMQShortString(item)); + + if (exchange == null) + { + _console.println("Exchange '" + item + "' not found."); + } + else + { + _tool.getState().setExchange(exchange); + } + + if (_tool.getState().getQueue() != null) + { + if (!exchange.isBound(_tool.getState().getQueue())) + { + _tool.getState().setQueue(null); + } + } + } + + if (type.equals("queue")) + { + VirtualHost vhost = _tool.getState().getVhost(); + + if (vhost == null) + { + _console.println("No Virtualhost open. Open a Virtualhost first."); + return; + } + + AMQQueue queue = vhost.getQueueRegistry().getQueue(new AMQShortString(item)); + + if (queue == null) + { + _console.println("Queue '" + item + "' not found."); + } + else + { + _tool.getState().setQueue(queue); + + if (_tool.getState().getExchange() == null) + { + for (AMQShortString exchangeName : vhost.getExchangeRegistry().getExchangeNames()) + { + Exchange exchange = vhost.getExchangeRegistry().getExchange(exchangeName); + if (exchange.isBound(queue)) + { + _tool.getState().setExchange(exchange); + break; + } + } + } + + //remove the message selection + _tool.getState().setMessages((java.util.List) null); + } + } + + if (type.equals("msg")) + { + if (item.startsWith("id=")) + { + StringTokenizer tok = new StringTokenizer(item.substring(item.indexOf("=") + 1), ","); + + java.util.List msgids = null; + + if (tok.hasMoreTokens()) + { + msgids = new LinkedList(); + } + + while (tok.hasMoreTokens()) + { + String next = tok.nextToken(); + if (next.contains("-")) + { + Long start = Long.parseLong(next.substring(0, next.indexOf("-"))); + Long end = Long.parseLong(next.substring(next.indexOf("-") + 1)); + + if (end >= start) + { + for (long l = start; l <= end; l++) + { + msgids.add(l); + } + } + } + else + { + msgids.add(Long.parseLong(next)); + } + } + + _tool.getState().setMessages(msgids); + } + + } + + if (type.equals("show")) + { + _console.println(_tool.getState().toString()); + if (_tool.getState().getMessages() != null) + { + _console.print("Msgs:"); + for (Long l : _tool.getState().getMessages()) + { + _console.print(" " + l); + } + _console.println(""); + } + } + } +} diff --git a/java/broker/src/main/java/org/apache/qpid/tools/messagestore/commands/Show.java b/java/broker/src/main/java/org/apache/qpid/tools/messagestore/commands/Show.java new file mode 100644 index 0000000000..5988cdabfc --- /dev/null +++ b/java/broker/src/main/java/org/apache/qpid/tools/messagestore/commands/Show.java @@ -0,0 +1,513 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + * + */ +package org.apache.qpid.tools.messagestore.commands; + +import org.apache.qpid.AMQException; +import org.apache.qpid.framing.AMQShortString; +import org.apache.qpid.framing.BasicContentHeaderProperties; +import org.apache.qpid.framing.FieldTable; +import org.apache.qpid.framing.abstraction.MessagePublishInfo; +import org.apache.qpid.server.queue.AMQMessage; +import org.apache.qpid.server.queue.AMQQueue; +import org.apache.qpid.tools.messagestore.MessageStoreTool; +import org.apache.qpid.tools.utils.Console; + +import java.util.LinkedList; +import java.util.List; +import java.util.StringTokenizer; + +public class Show extends AbstractCommand +{ + protected boolean _amqHeaders = false; + protected boolean _routing = false; + protected boolean _msgHeaders = false; + + public Show(MessageStoreTool tool) + { + super(tool); + } + + public String help() + { + return "Shows the messages headers."; + } + + public String usage() + { + return getCommand() + " [show=[all],[msgheaders],[amqheaders],[routing]] [id=]"; + } + + public String getCommand() + { + return "show"; + } + + public void execute(String... args) + { + assert args.length > 0; + assert args[0].equals(getCommand()); + + if (args.length < 2) + { + parseArgs("all"); + } + else + { + parseArgs(args); + } + + performShow(); + } + + protected void parseArgs(String... args) + { + List msgids = null; + + if (args.length >= 2) + { + for (String arg : args) + { + if (arg.startsWith("show=")) + { + _msgHeaders = arg.contains("msgheaders") || arg.contains("all"); + _amqHeaders = arg.contains("amqheaders") || arg.contains("all"); + _routing = arg.contains("routing") || arg.contains("all"); + } + + if (arg.startsWith("id=")) + { + _tool.getState().setMessages(msgids); + } + }//for args + }// if args > 2 + } + + protected void performShow() + { + if (_tool.getState().getVhost() == null) + { + _console.println("No Virtualhost selected. 'DuSelect' a Virtualhost first."); + return; + } + + AMQQueue _queue = _tool.getState().getQueue(); + + List msgids = _tool.getState().getMessages(); + + if (_queue != null) + { + List messages = _queue.getMessagesOnTheQueue(); + if (messages == null || messages.size() == 0) + { + _console.println("No messages on queue"); + return; + } + + List data = createMessageData(msgids, messages, _amqHeaders, _routing, _msgHeaders); + if (data != null) + { + _console.printMap(null, data); + } + else + { + String message = "No data to display."; + if (msgids != null) + { + message += " Is message selection correct? " + _tool.getState().printMessages(); + } + _console.println(message); + } + + } + else + { + _console.println("No Queue specified to show."); + } + } + + /** + * Create the list data for display from the messages. + * + * @param msgids The list of message ids to display + * @param messages A list of messages to format and display. + * @param showHeaders should the header info be shown + * @param showRouting show the routing info be shown + * @param showMessageHeaders show the msg headers be shown + * @return the formated data lists for printing + */ + protected List createMessageData(List msgids, List messages, boolean showHeaders, boolean showRouting, + boolean showMessageHeaders) + { + + // Currenly exposed message properties +// //Printing the content Body +// msg.getContentBodyIterator(); +// //Print the Headers +// ((BasicContentHeaderProperties)msg.getContentHeaderBody().properties).getAppId(); +// ((BasicContentHeaderProperties)msg.getContentHeaderBody().properties).getAppIdAsString(); +// ((BasicContentHeaderProperties)msg.getContentHeaderBody().properties).getClusterId(); +// ((BasicContentHeaderProperties)msg.getContentHeaderBody().properties).getContentType(); +// ((BasicContentHeaderProperties)msg.getContentHeaderBody().properties).getCorrelationId(); +// ((BasicContentHeaderProperties)msg.getContentHeaderBody().properties).getDeliveryMode(); +// ((BasicContentHeaderProperties)msg.getContentHeaderBody().properties).getEncoding(); +// ((BasicContentHeaderProperties)msg.getContentHeaderBody().properties).getExpiration(); +// ((BasicContentHeaderProperties)msg.getContentHeaderBody().properties).getHeaders(); +// ((BasicContentHeaderProperties)msg.getContentHeaderBody().properties).getMessageId(); +// ((BasicContentHeaderProperties)msg.getContentHeaderBody().properties).getPriority(); +// ((BasicContentHeaderProperties)msg.getContentHeaderBody().properties).getPropertyFlags(); +// ((BasicContentHeaderProperties)msg.getContentHeaderBody().properties).getReplyTo(); +// ((BasicContentHeaderProperties)msg.getContentHeaderBody().properties).getTimestamp(); +// ((BasicContentHeaderProperties)msg.getContentHeaderBody().properties).getType(); +// ((BasicContentHeaderProperties)msg.getContentHeaderBody().properties).getUserId(); +// +// //Print out all the property names +// ((BasicContentHeaderProperties)msg.getContentHeaderBody().properties).getHeaders().getPropertyNames(); +// +// msg.getMessageId(); +// msg.getSize(); +// msg.getArrivalTime(); + +// msg.getDeliveredSubscription(); +// msg.getDeliveredToConsumer(); +// msg.getMessageHandle(); +// msg.getMessageId(); +// msg.getMessagePublishInfo(); +// msg.getPublisher(); + +// msg.getStoreContext(); +// msg.isAllContentReceived(); +// msg.isPersistent(); +// msg.isRedelivered(); +// msg.isRejectedBy(); +// msg.isTaken(); + + //Header setup + + List data = new LinkedList(); + + List id = new LinkedList(); + data.add(id); + id.add(Columns.ID.name()); + id.add(Console.ROW_DIVIDER); + + List exchange = new LinkedList(); + List routingkey = new LinkedList(); + List immediate = new LinkedList(); + List mandatory = new LinkedList(); + if (showRouting) + { + data.add(exchange); + exchange.add(Columns.Exchange.name()); + exchange.add(Console.ROW_DIVIDER); + + data.add(routingkey); + routingkey.add(Columns.RoutingKey.name()); + routingkey.add(Console.ROW_DIVIDER); + + data.add(immediate); + immediate.add(Columns.isImmediate.name()); + immediate.add(Console.ROW_DIVIDER); + + data.add(mandatory); + mandatory.add(Columns.isMandatory.name()); + mandatory.add(Console.ROW_DIVIDER); + } + + List size = new LinkedList(); + List appid = new LinkedList(); + List clusterid = new LinkedList(); + List contenttype = new LinkedList(); + List correlationid = new LinkedList(); + List deliverymode = new LinkedList(); + List encoding = new LinkedList(); + List arrival = new LinkedList(); + List expiration = new LinkedList(); + List priority = new LinkedList(); + List propertyflag = new LinkedList(); + List replyto = new LinkedList(); + List timestamp = new LinkedList(); + List type = new LinkedList(); + List userid = new LinkedList(); + List ispersitent = new LinkedList(); + List isredelivered = new LinkedList(); + List isdelivered = new LinkedList(); + + data.add(size); + size.add(Columns.Size.name()); + size.add(Console.ROW_DIVIDER); + + if (showHeaders) + { + data.add(ispersitent); + ispersitent.add(Columns.isPersistent.name()); + ispersitent.add(Console.ROW_DIVIDER); + + data.add(isredelivered); + isredelivered.add(Columns.isRedelivered.name()); + isredelivered.add(Console.ROW_DIVIDER); + + data.add(isdelivered); + isdelivered.add(Columns.isDelivered.name()); + isdelivered.add(Console.ROW_DIVIDER); + + data.add(appid); + appid.add(Columns.App_ID.name()); + appid.add(Console.ROW_DIVIDER); + + data.add(clusterid); + clusterid.add(Columns.Cluster_ID.name()); + clusterid.add(Console.ROW_DIVIDER); + + data.add(contenttype); + contenttype.add(Columns.Content_Type.name()); + contenttype.add(Console.ROW_DIVIDER); + + data.add(correlationid); + correlationid.add(Columns.Correlation_ID.name()); + correlationid.add(Console.ROW_DIVIDER); + + data.add(deliverymode); + deliverymode.add(Columns.Delivery_Mode.name()); + deliverymode.add(Console.ROW_DIVIDER); + + data.add(encoding); + encoding.add(Columns.Encoding.name()); + encoding.add(Console.ROW_DIVIDER); + + data.add(arrival); + expiration.add(Columns.Arrival.name()); + expiration.add(Console.ROW_DIVIDER); + + data.add(expiration); + expiration.add(Columns.Expiration.name()); + expiration.add(Console.ROW_DIVIDER); + + data.add(priority); + priority.add(Columns.Priority.name()); + priority.add(Console.ROW_DIVIDER); + + data.add(propertyflag); + propertyflag.add(Columns.Property_Flag.name()); + propertyflag.add(Console.ROW_DIVIDER); + + data.add(replyto); + replyto.add(Columns.ReplyTo.name()); + replyto.add(Console.ROW_DIVIDER); + + data.add(timestamp); + timestamp.add(Columns.Timestamp.name()); + timestamp.add(Console.ROW_DIVIDER); + + data.add(type); + type.add(Columns.Type.name()); + type.add(Console.ROW_DIVIDER); + + data.add(userid); + userid.add(Columns.UserID.name()); + userid.add(Console.ROW_DIVIDER); + } + + List msgHeaders = new LinkedList(); + if (showMessageHeaders) + { + data.add(msgHeaders); + msgHeaders.add(Columns.MsgHeaders.name()); + msgHeaders.add(Console.ROW_DIVIDER); + } + + //Add create the table of data + for (AMQMessage msg : messages) + { + if (!includeMsg(msg, msgids)) + { + continue; + } + + id.add(msg.getMessageId().toString()); + + size.add("" + msg.getSize()); + + arrival.add("" + msg.getArrivalTime()); + + try + { + ispersitent.add(msg.isPersistent() ? "true" : "false"); + } + catch (AMQException e) + { + ispersitent.add("n/a"); + } + + isredelivered.add(msg.isRedelivered() ? "true" : "false"); + + isdelivered.add(msg.getDeliveredToConsumer() ? "true" : "false"); + +// msg.getMessageHandle(); + + BasicContentHeaderProperties headers = null; + + try + { + headers = ((BasicContentHeaderProperties) msg.getContentHeaderBody().properties); + } + catch (AMQException e) + { + //ignore +// commandError("Unable to read properties for message: " + e.getMessage(), null); + } + + if (headers != null) + { + String appidS = headers.getAppIdAsString(); + appid.add(appidS == null ? "null" : appidS); + + String clusterS = headers.getClusterIdAsString(); + clusterid.add(clusterS == null ? "null" : clusterS); + + String contentS = headers.getContentTypeAsString(); + contenttype.add(contentS == null ? "null" : contentS); + + String correlationS = headers.getCorrelationIdAsString(); + correlationid.add(correlationS == null ? "null" : correlationS); + + deliverymode.add("" + headers.getDeliveryMode()); + + AMQShortString encodeSS = headers.getEncoding(); + encoding.add(encodeSS == null ? "null" : encodeSS.toString()); + + expiration.add("" + headers.getExpiration()); + + FieldTable headerFT = headers.getHeaders(); + msgHeaders.add(headerFT == null ? "none" : "" + headerFT.toString()); + + priority.add("" + headers.getPriority()); + propertyflag.add("" + headers.getPropertyFlags()); + + AMQShortString replytoSS = headers.getReplyTo(); + replyto.add(replytoSS == null ? "null" : replytoSS.toString()); + + timestamp.add("" + headers.getTimestamp()); + + AMQShortString typeSS = headers.getType(); + type.add(typeSS == null ? "null" : typeSS.toString()); + + AMQShortString useridSS = headers.getUserId(); + userid.add(useridSS == null ? "null" : useridSS.toString()); + + MessagePublishInfo info = null; + try + { + info = msg.getMessagePublishInfo(); + } + catch (AMQException e) + { + //ignore + } + + if (info != null) + { + AMQShortString exchangeSS = info.getExchange(); + exchange.add(exchangeSS == null ? "null" : exchangeSS.toString()); + + AMQShortString routingkeySS = info.getRoutingKey(); + routingkey.add(routingkeySS == null ? "null" : routingkeySS.toString()); + + immediate.add(info.isImmediate() ? "true" : "false"); + mandatory.add(info.isMandatory() ? "true" : "false"); + } + +// msg.getPublisher(); -- only used in clustering +// msg.getStoreContext(); +// msg.isAllContentReceived(); + + }// if headers!=null + +// need to access internal map and do lookups. +// msg.isTaken(); +// msg.getDeliveredSubscription(); +// msg.isRejectedBy(); + + } + + // if id only had the header and the divider in it then we have no data to display + if (id.size() == 2) + { + return null; + } + return data; + } + + protected boolean includeMsg(AMQMessage msg, List msgids) + { + if (msgids == null) + { + return true; + } + + Long msgid = msg.getMessageId(); + + boolean found = false; + + if (msgids != null) + { + //check msgid is in msgids + for (Long l : msgids) + { + if (l.equals(msgid)) + { + found = true; + break; + } + } + } + return found; + } + + public enum Columns + { + ID, + Size, + Exchange, + RoutingKey, + isImmediate, + isMandatory, + isPersistent, + isRedelivered, + isDelivered, + App_ID, + Cluster_ID, + Content_Type, + Correlation_ID, + Delivery_Mode, + Encoding, + Arrival, + Expiration, + Priority, + Property_Flag, + ReplyTo, + Timestamp, + Type, + UserID, + MsgHeaders + } +} + + diff --git a/java/broker/src/main/java/org/apache/qpid/tools/security/Passwd.java b/java/broker/src/main/java/org/apache/qpid/tools/security/Passwd.java new file mode 100644 index 0000000000..c27c52eb8e --- /dev/null +++ b/java/broker/src/main/java/org/apache/qpid/tools/security/Passwd.java @@ -0,0 +1,81 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + * + */ +package org.apache.qpid.tools.security; + +import org.apache.commons.codec.binary.Base64; + +import java.security.MessageDigest; +import java.security.NoSuchAlgorithmException; +import java.security.DigestException; +import java.io.File; +import java.io.FileWriter; +import java.io.IOException; +import java.io.PrintStream; + +public class Passwd +{ + public static void main(String args[]) throws NoSuchAlgorithmException, DigestException, IOException + { + if (args.length != 2) + { + System.out.println("Passwd "); + System.exit(0); + } + + byte[] data = args[1].getBytes("utf-8"); + + MessageDigest md = MessageDigest.getInstance("MD5"); + + for (byte b : data) + { + md.update(b); + } + + byte[] digest = md.digest(); + + Base64 b64 = new Base64(); + + byte[] encoded = b64.encode(digest); + + output(args[0], encoded); + } + + private static void output(String user, byte[] encoded) throws IOException + { + +// File passwdFile = new File("qpid.passwd"); + + PrintStream ps = new PrintStream(System.out); + + user += ":"; + ps.write(user.getBytes("utf-8")); + + for (byte b : encoded) + { + ps.write(b); + } + + ps.println(); + + ps.flush(); + ps.close(); + } +} diff --git a/java/broker/src/main/java/org/apache/qpid/tools/utils/CommandParser.java b/java/broker/src/main/java/org/apache/qpid/tools/utils/CommandParser.java new file mode 100644 index 0000000000..986fea32cc --- /dev/null +++ b/java/broker/src/main/java/org/apache/qpid/tools/utils/CommandParser.java @@ -0,0 +1,51 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + * + */ +package org.apache.qpid.tools.utils; + +public interface CommandParser +{ + /** + * If there is more than one command received on the last parse request. + * + * Subsequent calls to parse will utilise this input rather than reading new data from the input source + * @return boolean + */ + boolean more(); + + /** + * True if the currently parsed command has been requested as a background operation + * + * @return boolean + */ + boolean isBackground(); + + /** + * Parses user commands, and groups tokens in the + * String[] format that all Java main's love. + * + * If more than one command is provided in one input line then the more() method will return true. + * A subsequent call to parse() will continue to parse that input line before reading new input. + * + * @return input split in args[] format; null if eof. + * @throws java.io.IOException if there is a problem reading from the input stream + */ + String[] parse() throws java.io.IOException; +} diff --git a/java/broker/src/main/java/org/apache/qpid/tools/utils/Console.java b/java/broker/src/main/java/org/apache/qpid/tools/utils/Console.java new file mode 100644 index 0000000000..cf457d1ea5 --- /dev/null +++ b/java/broker/src/main/java/org/apache/qpid/tools/utils/Console.java @@ -0,0 +1,90 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + * + */ +package org.apache.qpid.tools.utils; + +import java.util.List; + +public interface Console +{ + public enum CellFormat + { + CENTRED, LEFT, RIGHT + } + + public static String ROW_DIVIDER = "*divider"; + + public void print(String... message); + + public void println(String... message); + + public String readln(); + + /** + * Reads and parses the command line. + * + * + * @return The next command or null + */ + public String[] readCommand(); + + public CommandParser getCommandParser(); + + public void setCommandParser(CommandParser parser); + + /** + * + * Prints the list of String nicely. + * + * +-------------+ + * | Heading | + * +-------------+ + * | Item 1 | + * | Item 2 | + * | Item 3 | + * +-------------+ + * + * @param hasTitle should list[0] be used as a heading + * @param list The list of Strings to display + */ + public void displayList(boolean hasTitle, String... list); + + /** + * + * Prints the list of String nicely. + * + * +----------------------------+ + * | Heading | + * +----------------------------+ + * | title | title | .. + * +----------------------------+ + * | Item 2 | value 2 | .. + * +----------------------------+ (*divider) + * | Item 3 | value 2 | .. + * +----------------------------+ + * + * @param title The title to display if any + * @param entries the entries to display in a map. + */ + void printMap(String title, List entries); + + + public void close(); +} diff --git a/java/broker/src/main/java/org/apache/qpid/tools/utils/SimpleCommandParser.java b/java/broker/src/main/java/org/apache/qpid/tools/utils/SimpleCommandParser.java new file mode 100644 index 0000000000..09444ccdd7 --- /dev/null +++ b/java/broker/src/main/java/org/apache/qpid/tools/utils/SimpleCommandParser.java @@ -0,0 +1,121 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + * + */ +package org.apache.qpid.tools.utils; + +import java.io.BufferedReader; +import java.io.IOException; +import java.util.StringTokenizer; + +public class SimpleCommandParser implements CommandParser +{ + private static final String COMMAND_SEPERATOR = ";"; + + /** Input source of commands */ + protected BufferedReader _reader; + + /** The next list of commands from the command line */ + private StringBuilder _nextCommand = null; + + public SimpleCommandParser(BufferedReader reader) + { + _reader = reader; + } + + public boolean more() + { + return _nextCommand != null; + } + + public boolean isBackground() + { + return false; + } + + public String[] parse() throws IOException + { + String[] commands = null; + + String input = null; + + if (_nextCommand == null) + { + input = _reader.readLine(); + } + else + { + input = _nextCommand.toString(); + _nextCommand = null; + } + + if (input == null) + { + return null; + } + + StringTokenizer tok = new StringTokenizer(input, " "); + + int tokenCount = tok.countTokens(); + int index = 0; + + if (tokenCount > 0) + { + commands = new String[tokenCount]; + boolean commandComplete = false; + + while (tok.hasMoreTokens()) + { + String next = tok.nextToken(); + + if (next.equals(COMMAND_SEPERATOR)) + { + commandComplete = true; + _nextCommand = new StringBuilder(); + continue; + } + + if (commandComplete) + { + _nextCommand.append(next); + _nextCommand.append(" "); + } + else + { + commands[index] = next; + index++; + } + } + + } + + //Reduce the String[] if not all the tokens were used in this command. + // i.e. there is more than one command on the line. + if (index != tokenCount) + { + String[] shortCommands = new String[index]; + System.arraycopy(commands, 0, shortCommands, 0, index); + return shortCommands; + } + else + { + return commands; + } + } +} diff --git a/java/broker/src/main/java/org/apache/qpid/tools/utils/SimpleConsole.java b/java/broker/src/main/java/org/apache/qpid/tools/utils/SimpleConsole.java new file mode 100644 index 0000000000..ec080a4611 --- /dev/null +++ b/java/broker/src/main/java/org/apache/qpid/tools/utils/SimpleConsole.java @@ -0,0 +1,363 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + * + */ +package org.apache.qpid.tools.utils; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.BufferedReader; +import java.io.BufferedWriter; +import java.io.IOException; +import java.util.LinkedList; +import java.util.List; + +public class SimpleConsole implements Console +{ + /** SLF4J Logger. */ + private static Logger _devlog = LoggerFactory.getLogger(SimpleConsole.class); + + /** Console Writer. */ + protected static BufferedWriter _consoleWriter; + + /** Console Reader. */ + protected static BufferedReader _consoleReader; + + /** Parser for command-line input. */ + protected CommandParser _parser; + + public SimpleConsole(BufferedWriter writer, BufferedReader reader) + { + _consoleWriter = writer; + _consoleReader = reader; + _parser = new SimpleCommandParser(_consoleReader); + } + + public void print(String... message) + { + try + { + for (String s : message) + { + _consoleWriter.write(s); + } + _consoleWriter.flush(); + } + catch (IOException e) + { + _devlog.error(e.getMessage() + ": Occured whilst trying to write:" + message); + } + + } + + public void println(String... message) + { + print(message); + print(System.getProperty("line.separator")); + } + + + public String readln() + { + try + { + return _consoleReader.readLine(); + } + catch (IOException e) + { + _devlog.debug("Unable to read input due to:" + e.getMessage()); + return null; + } + } + + public String[] readCommand() + { + try + { + return _parser.parse(); + } + catch (IOException e) + { + _devlog.error("Error reading command:" + e.getMessage()); + return new String[0]; + } + } + + public CommandParser getCommandParser() + { + return _parser; + } + + public void setCommandParser(CommandParser parser) + { + _parser = parser; + } + + public void displayList(boolean hasTitle, String... list) + { + java.util.List data = new LinkedList(); + + java.util.List values = new LinkedList(); + + data.add(values); + + for (String value : list) + { + values.add(value); + } + + if (hasTitle) + { + values.add(1, "*divider"); + } + + printMap(null, data); + } + + /** + * + * Prints the list of String nicely. + * + * +----------------------------+ + * | Heading | + * +----------------------------+ + * | title | title | .. + * +----------------------------+ + * | Item 2 | value 2 | .. + * | Item 3 | value 2 | .. + * +----------------------------+ + * + * @param title The title to display if any + * @param entries the entries to display in a map. + */ + public void printMap(String title, java.util.List entries) + { + try + { + int columns = entries.size(); + + int[] columnWidth = new int[columns]; + + // calculate row count + int rowMax = 0; + + //the longest item + int itemMax = 0; + + for (int i = 0; i < columns; i++) + { + int columnIRowMax = entries.get(i).size(); + + if (columnIRowMax > rowMax) + { + rowMax = columnIRowMax; + } + for (Object values : entries.get(i)) + { + if (values.toString().equals(Console.ROW_DIVIDER)) + { + continue; + } + + int itemLength = values.toString().length(); + + //note for single width + if (itemLength > itemMax) + { + itemMax = itemLength; + } + + //note for mulit width + if (itemLength > columnWidth[i]) + { + columnWidth[i] = itemLength; + } + + } + } + + int tableWidth = 0; + + + for (int i = 0; i < columns; i++) + { + // plus 2 for the space padding + columnWidth[i] += 2; + } + for (int size : columnWidth) + { + tableWidth += size; + } + tableWidth += (columns - 1); + + if (title != null) + { + if (title.length() > tableWidth) + { + tableWidth = title.length(); + } + + printCellRow("+", "-", tableWidth); + + printCell(CellFormat.CENTRED, "|", tableWidth, " " + title + " ", 0); + _consoleWriter.newLine(); + + } + + //put top line | or bottom of title + printCellRow("+", "-", tableWidth); + + //print the table data + int row = 0; + + for (; row < rowMax; row++) + { + for (int i = 0; i < columns; i++) + { + java.util.List columnData = entries.get(i); + + String value; + // does this column have a value for this row + if (columnData.size() > row) + { + value = " " + columnData.get(row).toString() + " "; + } + else + { + value = " "; + } + + if (i == 0 && value.equals(" " + Console.ROW_DIVIDER + " ")) + { + printCellRow("+", "-", tableWidth); + //move on to the next row + break; + } + else + { + printCell(CellFormat.LEFT, "|", columnWidth[i], value, i); + } + + // if it is the last row then do a new line. + if (i == columns - 1) + { + _consoleWriter.newLine(); + } + } + } + + printCellRow("+", "-", tableWidth); + + } + catch (IOException e) + { + _devlog.error(e.getMessage() + ": Occured whilst trying to write."); + } + } + + public void close() + { + + try + { + _consoleReader.close(); + } + catch (IOException e) + { + _devlog.error(e.getMessage() + ": Occured whilst trying to close reader."); + } + + try + { + + _consoleWriter.close(); + } + catch (IOException e) + { + _devlog.error(e.getMessage() + ": Occured whilst trying to close writer."); + } + + } + + private void printCell(CellFormat format, String edge, int cellWidth, String cell, int column) throws IOException + { + int pad = cellWidth - cell.length(); + + if (column == 0) + { + _consoleWriter.write(edge); + } + + switch (format) + { + case CENTRED: + printPad(" ", pad / 2); + break; + case RIGHT: + printPad(" ", pad); + break; + } + + _consoleWriter.write(cell); + + + switch (format) + { + case CENTRED: + // if pad isn't even put the extra one on the right + if (pad % 2 == 0) + { + printPad(" ", pad / 2); + } + else + { + printPad(" ", (pad / 2) + 1); + } + break; + case LEFT: + printPad(" ", pad); + break; + } + + + _consoleWriter.write(edge); + + } + + private void printCellRow(String edge, String mid, int cellWidth) throws IOException + { + _consoleWriter.write(edge); + + printPad(mid, cellWidth); + + _consoleWriter.write(edge); + _consoleWriter.newLine(); + } + + private void printPad(String padChar, int count) throws IOException + { + for (int i = 0; i < count; i++) + { + _consoleWriter.write(padChar); + } + } + + +} diff --git a/java/broker/src/main/java/org/apache/qpid/tools/utils/utils/CommandParser.java b/java/broker/src/main/java/org/apache/qpid/tools/utils/utils/CommandParser.java new file mode 100644 index 0000000000..6a95529059 --- /dev/null +++ b/java/broker/src/main/java/org/apache/qpid/tools/utils/utils/CommandParser.java @@ -0,0 +1,51 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + * + */ +package com.redhat.etp.qpid.utils; + +public interface CommandParser +{ + /** + * If there is more than one command received on the last parse request. + * + * Subsequent calls to parse will utilise this input rather than reading new data from the input source + * @return boolean + */ + boolean more(); + + /** + * True if the currently parsed command has been requested as a background operation + * + * @return boolean + */ + boolean isBackground(); + + /** + * Parses user commands, and groups tokens in the + * String[] format that all Java main's love. + * + * If more than one command is provided in one input line then the more() method will return true. + * A subsequent call to parse() will continue to parse that input line before reading new input. + * + * @return input split in args[] format; null if eof. + * @throws java.io.IOException if there is a problem reading from the input stream + */ + String[] parse() throws java.io.IOException; +} diff --git a/java/broker/src/main/java/org/apache/qpid/tools/utils/utils/Console.java b/java/broker/src/main/java/org/apache/qpid/tools/utils/utils/Console.java new file mode 100644 index 0000000000..892a48254c --- /dev/null +++ b/java/broker/src/main/java/org/apache/qpid/tools/utils/utils/Console.java @@ -0,0 +1,75 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + * + */ +package com.redhat.etp.qpid; + +import java.util.List; + +public interface Console +{ + public enum CellFormat + { + CENTRED, LEFT, RIGHT + } + + public static String ROW_DIVIDER = "*divider"; + + public void print(String... message); + + public void println(String... message); + + public String[] readln(); + + /** + * + * Prints the list of String nicely. + * + * +-------------+ + * | Heading | + * +-------------+ + * | Item 1 | + * | Item 2 | + * | Item 3 | + * +-------------+ + * + * @param hasTitle should list[0] be used as a heading + * @param list The list of Strings to display + */ + public void displayList(boolean hasTitle, String... list); + + /** + * + * Prints the list of String nicely. + * + * +----------------------------+ + * | Heading | + * +----------------------------+ + * | title | title | .. + * +----------------------------+ + * | Item 2 | value 2 | .. + * +----------------------------+ (*divider) + * | Item 3 | value 2 | .. + * +----------------------------+ + * + * @param title The title to display if any + * @param entries the entries to display in a map. + */ + void printMap(String title, List entries); +} diff --git a/java/broker/src/main/java/org/apache/qpid/tools/utils/utils/RSHCommandParser.java b/java/broker/src/main/java/org/apache/qpid/tools/utils/utils/RSHCommandParser.java new file mode 100644 index 0000000000..ea4045c917 --- /dev/null +++ b/java/broker/src/main/java/org/apache/qpid/tools/utils/utils/RSHCommandParser.java @@ -0,0 +1,352 @@ +/* + * The Java Shell: jsh core -- RELEASE: alpha3 + * (C)1999 Osvaldo Pinali Doederlein. + * + * LICENSE + * ======= + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * CHANGES + * ======= + * 1.0.2 - Added support for non-quoted '\' escape char (Not interpreted by the shell) + * 1.0.1 - Added support for arguments in aliases + * 1.0.0 - Initial release; split from Shell and enhanced a lot. + * + * LINKS + * ===== + * Contact: mailto@osvaldo.visionnaire.com.br, mailto@g.collin@appliweb.net + * Site #1: http://www.geocities.com/ResearchTriangle/Node/2005/ + * Site #2: http://www.appliweb.net/jsh + */ + +package com.redhat.etp.qpid.utils; + +import java.io.BufferedReader; +import java.util.Vector; + +/** + * The Java Shell. + *

+ * Provides an environment for launching and controlling Java apps. + *

+ * TODO: - Support for applets! + * - Support for variable replacement + * + * @author Osvaldo Pinali Doederlein. + */ +public class RSHCommandParser implements CommandParser +{ + /** Where commands come from. */ + protected BufferedReader reader; + /** Continuation for command line. */ + protected String contLine = null; + /** Run next command in background? */ + protected boolean background; + protected String[] env; // Commands passed in args. + + public RSHCommandParser(BufferedReader reader) + { + this(reader, null); + } + + public RSHCommandParser(BufferedReader reader, String env[]) + { + this.reader = reader; + this.env = env; + if (env == null) + { + this.env = new String[0]; + } + } + + + public boolean more() + { + return contLine != null; + } + + public boolean isBackground() + { + return background; + } + + /** + * Solves and expands aliases in an argument array. + * This expansion affects only the first (if any) argument; the + * typical thing to do, as we don't want to expand parameters. + * We recursively parse the result to be sure we expand everything. + * For example, an alias can be expanded to further aliases, or it can contains args. + * + * @param args Raw arguments. + * @return args resolved and expanded. + */ + public static String[] expand(String[] args) + { + if (args.length > 0) + { + String expanded = args[0];//Alias.resolve(args[0]); + + // Try to expand recursively the command line + if (expanded != args[0]) + { + RSHCommandParser recurse = new RSHCommandParser(new BufferedReader( + new java.io.StringReader(expanded))); + + try + { + String cmdLine[] = recurse.parse(); + cmdLine = recurse.expand(cmdLine); + + // do we need to handle new arguments and insert them in the command array ? + if (cmdLine.length > 1) + { + String[] newArgs = new String[cmdLine.length + args.length - 1]; + System.arraycopy(cmdLine, 0, newArgs, 0, cmdLine.length); + + if (args.length > 1) + { + System.arraycopy(args, 1, newArgs, cmdLine.length, args.length - 1); + } + + args = newArgs; + } + else if (cmdLine.length == 1) + { + args[0] = cmdLine[0]; + } + } + catch (java.io.IOException e) + { + } + } + } + + return args; + } + + public String[] parse() throws java.io.IOException + { + final int READ = 0, QUOTE = 1, SKIP = 2, ESCAPE = 3, NONQUOTEDESCAPE = 4, VARIABLE = 5; + final int EOF = 0xFFFF; + int mode = SKIP; + Vector args = new Vector(); + StringBuffer current = new StringBuffer(); + StringBuffer varName = null; + background = false; + String line; + + if (contLine == null) + { + line = reader.readLine(); + } + else + { + line = contLine; + contLine = null; + } + + if (line == null) + { + reader = null; + return null; + } + + for (int pos = 0; pos < line.length(); ++pos) + { + char c = line.charAt(pos); + + switch (mode) + { + case SKIP: + switch (c) + { + case' ': + case'\t': + break; + case'\"': + mode = QUOTE; + break; + case'&': + background = true; + case';': + contLine = line.substring(pos + 1); + pos = line.length(); + break; + default: + mode = READ; + --pos; + } + break; + + case READ: + switch (c) + { + case'\"': + mode = QUOTE; + break; + case';': + case'&': + --pos; + case' ': + case'\t': + mode = SKIP; + break; + case'\\': + mode = NONQUOTEDESCAPE; + break; + case'$': + mode = VARIABLE; + varName = new StringBuffer(); + break; + default: + current.append(c); + } + if ((mode != READ) && (mode != NONQUOTEDESCAPE)) + { + args.addElement(current.toString()); + current = new StringBuffer(); + } + break; + + case QUOTE: + switch (c) + { + case'\"': + mode = READ; + break; + case'\\': + mode = ESCAPE; + break; + default: + current.append(c); + } + break; + + case ESCAPE: + switch (c) + { + case'n': + c = '\n'; + break; + case'r': + c = '\r'; + break; + case't': + c = '\t'; + break; + case'b': + c = '\b'; + break; + case'f': + c = '\f'; + break; + default: + current.append('\\'); + break; + } + mode = QUOTE; + current.append(c); + break; + case NONQUOTEDESCAPE: + switch (c) + { + case';': + mode = READ; + current.append(c); + break; + default: // This is not a escaped char. + mode = READ; + current.append('\\'); + current.append(c); + break; + } + break; + case VARIABLE: + switch (c) + { + case'$': + { +// String val = Set.get(new String(varName)); +// if (val != null) +// { +// current.append(val); +// } + mode = READ; + break; + } + case'@': + { + StringBuffer val = new StringBuffer(); + int i; + for (i = 0; i < env.length; i++) + { + val.append(env[i]); + val.append(' '); + } + current.append(val); + mode = READ; + break; + } + case'0': + case'1': + case'2': + case'3': + case'4': + case'5': + case'6': + case'7': + case'8': + case'9': + { + if (varName.length() == 0) + { + int value = Integer.parseInt(new String(new char[]{c})); + if (env.length > value) + { + current.append(env[value]); + } + mode = READ; + break; + } + // else fall back + } + default: + varName.append(c); + break; + } + break; + } + } + + if (current.length() > 0) + { + args.addElement(current.toString()); + } + return expand(toArray(args)); + } + + private String[] toArray(Vector strings) + { + String[] arr = new String[strings.size()]; + + for (int i = 0; i < strings.size(); ++i) + { + arr[i] = (String) strings.elementAt(i); + } + + return arr; + } + +} diff --git a/java/broker/src/main/java/org/apache/qpid/tools/utils/utils/SimpleCommandParser.java b/java/broker/src/main/java/org/apache/qpid/tools/utils/utils/SimpleCommandParser.java new file mode 100644 index 0000000000..98e816554e --- /dev/null +++ b/java/broker/src/main/java/org/apache/qpid/tools/utils/utils/SimpleCommandParser.java @@ -0,0 +1,116 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + * + */ +package com.redhat.etp.qpid.utils; + +import java.io.BufferedReader; +import java.io.IOException; +import java.util.StringTokenizer; + +public class SimpleCommandParser implements CommandParser +{ + private static final String COMMAND_SEPERATOR = ";"; + + /** Input source of commands */ + protected BufferedReader _reader; + + /** The next list of commands from the command line */ + private StringBuilder _nextCommand = null; + + public SimpleCommandParser(BufferedReader reader) + { + _reader = reader; + } + + public boolean more() + { + return _nextCommand != null; + } + + public boolean isBackground() + { + return false; + } + + public String[] parse() throws IOException + { + String[] commands = null; + + String input = null; + + if (_nextCommand == null) + { + input = _reader.readLine(); + } + else + { + input = _nextCommand.toString(); + _nextCommand = null; + } + + StringTokenizer tok = new StringTokenizer(input, " "); + + int tokenCount = tok.countTokens(); + int index = 0; + + if (tokenCount > 0) + { + commands = new String[tokenCount]; + boolean commandComplete = false; + + while (tok.hasMoreTokens()) + { + String next = tok.nextToken(); + + if (next.equals(COMMAND_SEPERATOR)) + { + commandComplete = true; + _nextCommand = new StringBuilder(); + continue; + } + + if (commandComplete) + { + _nextCommand.append(next); + _nextCommand.append(" "); + } + else + { + commands[index] = next; + index++; + } + } + + } + + //Reduce the String[] if not all the tokens were used in this command. + // i.e. there is more than one command on the line. + if (index != tokenCount) + { + String[] shortCommands = new String[index]; + System.arraycopy(commands, 0, shortCommands, 0, index); + return shortCommands; + } + else + { + return commands; + } + } +} diff --git a/java/broker/src/test/java/org/apache/qpid/server/exchange/ExchangeMBeanTest.java b/java/broker/src/test/java/org/apache/qpid/server/exchange/ExchangeMBeanTest.java index 9653155a51..3bca0a4545 100644 --- a/java/broker/src/test/java/org/apache/qpid/server/exchange/ExchangeMBeanTest.java +++ b/java/broker/src/test/java/org/apache/qpid/server/exchange/ExchangeMBeanTest.java @@ -1,18 +1,21 @@ /* * - * Copyright (c) 2006 The Apache Software Foundation + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * http://www.apache.org/licenses/LICENSE-2.0 * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. * */ package org.apache.qpid.server.exchange; diff --git a/java/broker/src/test/java/org/apache/qpid/server/protocol/TestMinaProtocolSession.java b/java/broker/src/test/java/org/apache/qpid/server/protocol/TestMinaProtocolSession.java index 89b0e068d9..0c0d8f471e 100644 --- a/java/broker/src/test/java/org/apache/qpid/server/protocol/TestMinaProtocolSession.java +++ b/java/broker/src/test/java/org/apache/qpid/server/protocol/TestMinaProtocolSession.java @@ -1,18 +1,21 @@ /* * - * Copyright (c) 2006 The Apache Software Foundation + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * http://www.apache.org/licenses/LICENSE-2.0 * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. * */ package org.apache.qpid.server.protocol; diff --git a/java/broker/src/test/java/org/apache/qpid/server/queue/AMQQueueAlertTest.java b/java/broker/src/test/java/org/apache/qpid/server/queue/AMQQueueAlertTest.java index a7e5c0d1d0..94d67848c6 100644 --- a/java/broker/src/test/java/org/apache/qpid/server/queue/AMQQueueAlertTest.java +++ b/java/broker/src/test/java/org/apache/qpid/server/queue/AMQQueueAlertTest.java @@ -1,18 +1,21 @@ /* * - * Copyright (c) 2006 The Apache Software Foundation + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * http://www.apache.org/licenses/LICENSE-2.0 * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. * */ package org.apache.qpid.server.queue; diff --git a/java/broker/src/test/java/org/apache/qpid/server/queue/AMQQueueMBeanTest.java b/java/broker/src/test/java/org/apache/qpid/server/queue/AMQQueueMBeanTest.java index acd5e0772f..76b67314e6 100644 --- a/java/broker/src/test/java/org/apache/qpid/server/queue/AMQQueueMBeanTest.java +++ b/java/broker/src/test/java/org/apache/qpid/server/queue/AMQQueueMBeanTest.java @@ -1,18 +1,21 @@ /* * - * Copyright (c) 2006 The Apache Software Foundation + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * http://www.apache.org/licenses/LICENSE-2.0 * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. * */ package org.apache.qpid.server.queue; diff --git a/java/client/example/src/main/java/org/apache/qpid/example/publisher/MonitorMessageDispatcher.java b/java/client/example/src/main/java/org/apache/qpid/example/publisher/MonitorMessageDispatcher.java index 8784d340da..b6544db995 100644 --- a/java/client/example/src/main/java/org/apache/qpid/example/publisher/MonitorMessageDispatcher.java +++ b/java/client/example/src/main/java/org/apache/qpid/example/publisher/MonitorMessageDispatcher.java @@ -18,18 +18,18 @@ */ package org.apache.qpid.example.publisher; -import org.apache.log4j.Logger; import org.apache.log4j.BasicConfigurator; +import org.apache.log4j.Logger; -import javax.jms.*; - -import java.util.Properties; +import javax.jms.DeliveryMode; +import javax.jms.JMSException; /** - * Class that sends heartbeat messages to allow monitoring of message consumption - * Sends regular (currently 20 seconds apart) heartbeat message + * Class that sends heartbeat messages to allow monitoring of message consumption Sends regular (currently 20 seconds + * apart) heartbeat message */ -public class MonitorMessageDispatcher { +public class MonitorMessageDispatcher +{ private static final Logger _logger = Logger.getLogger(MonitorMessageDispatcher.class); @@ -39,17 +39,18 @@ public class MonitorMessageDispatcher { /** * Easy entry point for running a message dispatcher for monitoring consumption + * * @param args */ public static void main(String[] args) { - //Switch on logging appropriately for your app BasicConfigurator.configure(); try { - while(true) + int i =0; + while (i < 1000) { try { @@ -62,9 +63,10 @@ public class MonitorMessageDispatcher { } //sleep for twenty seconds and then publish again - change if appropriate - Thread.sleep(20000); + //Thread.sleep(1000); + i++ ; } - catch(UndeliveredMessageException a) + catch (UndeliveredMessageException a) { //trigger application specific failure handling here _logger.error("Problem delivering monitor message"); @@ -72,7 +74,7 @@ public class MonitorMessageDispatcher { } } } - catch(Exception e) + catch (Exception e) { _logger.error("Error trying to dispatch AMS monitor message: " + e); System.exit(1); @@ -81,7 +83,7 @@ public class MonitorMessageDispatcher { { if (getMonitorPublisher() != null) { - getMonitorPublisher().cleanup(); + getMonitorPublisher().cleanup(); } } @@ -90,19 +92,24 @@ public class MonitorMessageDispatcher { /** * Publish heartbeat message + * * @throws JMSException * @throws UndeliveredMessageException */ public static void publish() throws JMSException, UndeliveredMessageException { //Send the message generated from the payload using the _publisher - getMonitorPublisher().sendImmediateMessage - (FileMessageFactory.createSimpleEventMessage(getMonitorPublisher().getSession(),"monitor:" +System.currentTimeMillis())); +// getMonitorPublisher().sendImmediateMessage +// (FileMessageFactory.createSimpleEventMessage(getMonitorPublisher().getSession(),"monitor:" +System.currentTimeMillis())); + + getMonitorPublisher().sendMessage + (getMonitorPublisher()._session, + FileMessageFactory.createSimpleEventMessage(getMonitorPublisher().getSession(), "monitor:" + System.currentTimeMillis()), + DeliveryMode.PERSISTENT, false, true); + } - /** - * Cleanup publishers - */ + /** Cleanup publishers */ public static void cleanup() { if (getMonitorPublisher() != null) @@ -119,16 +126,16 @@ public class MonitorMessageDispatcher { //Returns a _publisher for the monitor queue private static MonitorPublisher getMonitorPublisher() { - if (_monitorPublisher != null) - { - return _monitorPublisher; - } + if (_monitorPublisher != null) + { + return _monitorPublisher; + } - //Create a _publisher using failover details and constant for monitor queue - _monitorPublisher = new MonitorPublisher(); + //Create a _publisher using failover details and constant for monitor queue + _monitorPublisher = new MonitorPublisher(); - _monitorPublisher.setName(MonitorMessageDispatcher.DEFAULT_MONITOR_PUB_NAME); - return _monitorPublisher; + _monitorPublisher.setName(MonitorMessageDispatcher.DEFAULT_MONITOR_PUB_NAME); + return _monitorPublisher; } } diff --git a/java/client/example/src/main/java/org/apache/qpid/example/publisher/MonitorPublisher.java b/java/client/example/src/main/java/org/apache/qpid/example/publisher/MonitorPublisher.java index 233c3fea0a..a67b602e58 100644 --- a/java/client/example/src/main/java/org/apache/qpid/example/publisher/MonitorPublisher.java +++ b/java/client/example/src/main/java/org/apache/qpid/example/publisher/MonitorPublisher.java @@ -18,15 +18,17 @@ */ package org.apache.qpid.example.publisher; -import javax.jms.Message; +import org.apache.log4j.Logger; +import org.apache.qpid.client.BasicMessageProducer; + import javax.jms.DeliveryMode; import javax.jms.JMSException; -import org.apache.qpid.client.BasicMessageProducer; -import org.apache.log4j.Logger; +import javax.jms.Message; +import javax.jms.Session; /** - * Subclass of Publisher which uses QPID functionality to send a heartbeat message - * Note immediate flag not available via JMS MessageProducer + * Subclass of Publisher which uses QPID functionality to send a heartbeat message Note immediate flag not available via + * JMS MessageProducer */ public class MonitorPublisher extends Publisher { @@ -40,14 +42,45 @@ public class MonitorPublisher extends Publisher super(); } - /* - * Publishes a non-persistent message using transacted session - */ + /* + * Publishes a message using given details + */ + public boolean sendMessage(Session session, Message message, int deliveryMode, + boolean immediate, boolean commit) throws UndeliveredMessageException + { + try + { + _producer = (BasicMessageProducer) session.createProducer(_destination); + + _producer.send(message, deliveryMode, immediate); + + if (commit) + { + //commit the message send and close the transaction + _session.commit(); + } + + } + catch (JMSException e) + { + //Have to assume our commit failed but do not rollback here as channel closed + _log.error(e); + e.printStackTrace(); + throw new UndeliveredMessageException("Cannot deliver immediate message", e); + } + + _log.info(_name + " finished sending message: " + message); + return true; + } + + /* + * Publishes a non-persistent message using transacted session + */ public boolean sendImmediateMessage(Message message) throws UndeliveredMessageException { try { - _producer = (BasicMessageProducer)_session.createProducer(_destination); + _producer = (BasicMessageProducer) _session.createProducer(_destination); //Send message via our producer which is not persistent and is immediate //NB: not available via jms interface MessageProducer @@ -62,7 +95,7 @@ public class MonitorPublisher extends Publisher //Have to assume our commit failed but do not rollback here as channel closed _log.error(e); e.printStackTrace(); - throw new UndeliveredMessageException("Cannot deliver immediate message",e); + throw new UndeliveredMessageException("Cannot deliver immediate message", e); } _log.info(_name + " finished sending message: " + message); diff --git a/java/client/example/src/main/java/org/apache/qpid/example/pubsub/Client.java b/java/client/example/src/main/java/org/apache/qpid/example/pubsub/Client.java new file mode 100644 index 0000000000..e32ee0ba73 --- /dev/null +++ b/java/client/example/src/main/java/org/apache/qpid/example/pubsub/Client.java @@ -0,0 +1,72 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + * + */ +package org.apache.qpid.example.pubsub; + +import javax.jms.Connection; +import javax.jms.Destination; +import javax.jms.JMSException; +import javax.jms.Session; +import javax.naming.NamingException; + +/** + * An abstract base class that wraps up the creation of a JMS client utilising JNDI + */ +public abstract class Client +{ + protected ConnectionSetup _setup; + + protected Connection _connection; + protected Destination _destination; + protected Session _session; + + public Client(String destination) + { + if (destination == null) + { + destination = ConnectionSetup.TOPIC_JNDI_NAME; + } + + try + { + _setup = new ConnectionSetup(); + } + catch (NamingException e) + { + //ignore + } + + if (_setup != null) + { + try + { + _connection = _setup.getConnectionFactory().createConnection(); + _destination = _setup.getDestination(destination); + } + catch (JMSException e) + { + System.err.println(e.getMessage()); + } + } + } + + public abstract void start(); + +} \ No newline at end of file diff --git a/java/client/example/src/main/java/org/apache/qpid/example/pubsub/ConnectionSetup.java b/java/client/example/src/main/java/org/apache/qpid/example/pubsub/ConnectionSetup.java new file mode 100644 index 0000000000..c4edd9034f --- /dev/null +++ b/java/client/example/src/main/java/org/apache/qpid/example/pubsub/ConnectionSetup.java @@ -0,0 +1,123 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + * + */ +package org.apache.qpid.example.pubsub; + +import javax.jms.ConnectionFactory; +import javax.jms.Destination; +import javax.naming.Context; +import javax.naming.InitialContext; +import javax.naming.NamingException; +import java.util.Properties; + +/** + * This ConnectionSetup is a wrapper around JNDI it creates a number of entries. + * + * It is equivalent to a PropertyFile of value: + * + * connectionfactory.local=amqp://guest:guest@clientid/test?brokerlist='localhost' + * connectionfactory.vm=amqp://guest:guest@clientid/test?brokerlist='vm://:1' + * + * queue.queue=example.MyQueue + * topic.topic=example.hierarical.topic + * + */ +public class ConnectionSetup +{ + final static String INITIAL_CONTEXT_FACTORY = "org.apache.qpid.jndi.PropertiesFileInitialContextFactory"; + + final static String CONNECTION_JNDI_NAME = "local"; + final static String CONNECTION_NAME = "amqp://guest:guest@clientid/test?brokerlist='localhost'"; + + public static final String QUEUE_JNDI_NAME = "queue"; + final static String QUEUE_NAME = "example.MyQueue"; + + public static final String TOPIC_JNDI_NAME = "topic"; + final static String TOPIC_NAME = "example.hierarical.topic"; + + private Context _ctx; + + public ConnectionSetup() throws NamingException + { + + // Set the properties ... + Properties properties = new Properties(); + properties.put(Context.INITIAL_CONTEXT_FACTORY, INITIAL_CONTEXT_FACTORY); + properties.put("connectionfactory." + CONNECTION_JNDI_NAME, CONNECTION_NAME); + properties.put("connectionfactory." + "vm", "amqp://guest:guest@clientid/test?brokerlist='vm://:1'"); + + properties.put("queue." + QUEUE_JNDI_NAME, QUEUE_NAME); + properties.put("topic." + TOPIC_JNDI_NAME, TOPIC_NAME); + // Create the initial context + _ctx = new InitialContext(properties); + + } + + public ConnectionSetup(Properties properties) throws NamingException + { + _ctx = new InitialContext(properties); + } + + public ConnectionFactory getConnectionFactory() + { + + // Perform the lookups + try + { + return (ConnectionFactory) _ctx.lookup(CONNECTION_JNDI_NAME); + } + catch (NamingException e) + { + //ignore + } + return null; + } + + public Destination getDestination(String jndiName) + { + // Perform the lookups + try + { + return (Destination) _ctx.lookup(jndiName); + } + catch (ClassCastException cce) + { + //ignore + } + catch (NamingException ne) + { + //ignore + } + return null; + } + + + public void close() + { + try + { + _ctx.close(); + } + catch (NamingException e) + { + //ignore + } + } +} diff --git a/java/client/example/src/main/java/org/apache/qpid/example/pubsub/Publisher.java b/java/client/example/src/main/java/org/apache/qpid/example/pubsub/Publisher.java new file mode 100644 index 0000000000..dd936e429f --- /dev/null +++ b/java/client/example/src/main/java/org/apache/qpid/example/pubsub/Publisher.java @@ -0,0 +1,81 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + * + */ +package org.apache.qpid.example.pubsub; + +import javax.jms.JMSException; +import javax.jms.MessageProducer; +import javax.jms.Session; + +/** + * A simple Publisher example. + * + * The class can take two arguments. + * java Publisher + * Where: + * destination is either 'topic' or 'queue' (Default: topic) + * msgCount is the number of messages to send (Default : 100) + * + */ +public class Publisher extends Client +{ + int _msgCount; + + public Publisher(String destination, int msgCount) + { + super(destination); + _msgCount = msgCount; + } + + public void start() + { + try + { + _session = _connection.createSession(false, Session.AUTO_ACKNOWLEDGE); + + MessageProducer _producer = _session.createProducer(_destination); + + for (int msgCount = 0; msgCount < _msgCount; msgCount++) + { + _producer.send(_session.createTextMessage("msg:" + msgCount)); + System.out.println("Sent:" + msgCount); + } + + System.out.println("Done."); + _connection.close(); + } + catch (JMSException e) + { + e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates. + } + } + + + public static void main(String[] args) + { + + String destination = args.length > 2 ? args[1] : null; + + int msgCount = args.length > 2 ? Integer.parseInt(args[2]) : 100; + + new Publisher(destination, msgCount).start(); + } + +} diff --git a/java/client/example/src/main/java/org/apache/qpid/example/pubsub/Subscriber.java b/java/client/example/src/main/java/org/apache/qpid/example/pubsub/Subscriber.java new file mode 100644 index 0000000000..f2d736701f --- /dev/null +++ b/java/client/example/src/main/java/org/apache/qpid/example/pubsub/Subscriber.java @@ -0,0 +1,98 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + * + */ +package org.apache.qpid.example.pubsub; + +import javax.jms.JMSException; +import javax.jms.Message; +import javax.jms.MessageListener; +import javax.jms.Session; +import javax.jms.TextMessage; +import javax.jms.Topic; +import java.util.concurrent.CountDownLatch; + + +/** + * Simple client that listens for the specified number of msgs on the given Destinaton + * + * The class can take two arguments. + * java Subscriber + * Where: + * destination is either 'topic' or 'queue' (Default: topic) + * msgCount is the number of messages to send (Default : 100) + */ +public class Subscriber extends Client implements MessageListener +{ + + CountDownLatch _count; + + public Subscriber(String destination, int msgCount) + { + super(destination); + _count = new CountDownLatch(msgCount); + } + + + public void start() + { + try + { + _session = _connection.createSession(false, Session.AUTO_ACKNOWLEDGE); + + _session.createDurableSubscriber((Topic) _setup.getDestination(ConnectionSetup.TOPIC_JNDI_NAME), + "exampleClient").setMessageListener(this); + _connection.start(); + _count.await(); + + System.out.println("Done"); + + _connection.close(); + } + catch (JMSException e) + { + e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates. + } + catch (InterruptedException e) + { + e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates. + } + } + + public static void main(String[] args) + { + String destination = args.length > 2 ? args[1] : null; + int msgCount = args.length > 2 ? Integer.parseInt(args[2]) : 100; + + new Subscriber(destination, msgCount).start(); + } + + public void onMessage(Message message) + { + try + { + _count.countDown(); + System.out.println("Received msg:" + ((TextMessage) message).getText()); + } + catch (JMSException e) + { + e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates. + } + } +} diff --git a/java/client/pom.xml b/java/client/pom.xml index c36c54a10f..b51e540c2d 100644 --- a/java/client/pom.xml +++ b/java/client/pom.xml @@ -123,6 +123,50 @@ + + + minijar-maven-plugin + org.codehaus.mojo + + + package + + ueberjar + + + false + [artifactId]-[version]-single.jar + single + true + + + + + + + org.codehaus.mojo + build-helper-maven-plugin + + + attach-artifacts + package + + attach-artifact + + + + + target/${artifactId}-${version}-single.jar + jar + single + + + + + + + + org.apache.maven.plugins maven-antrun-plugin diff --git a/java/client/src/main/java/org/apache/qpid/client/AMQConnection.java b/java/client/src/main/java/org/apache/qpid/client/AMQConnection.java index d59412fdba..ddce0db7ff 100644 --- a/java/client/src/main/java/org/apache/qpid/client/AMQConnection.java +++ b/java/client/src/main/java/org/apache/qpid/client/AMQConnection.java @@ -46,7 +46,6 @@ import org.apache.qpid.jms.ConnectionURL; import org.apache.qpid.jms.FailoverPolicy; import org.apache.qpid.protocol.AMQConstant; import org.apache.qpid.url.URLSyntaxException; - import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -68,7 +67,6 @@ import javax.naming.NamingException; import javax.naming.Reference; import javax.naming.Referenceable; import javax.naming.StringRefAddr; - import java.io.IOException; import java.net.ConnectException; import java.nio.channels.UnresolvedAddressException; @@ -1148,7 +1146,7 @@ public class AMQConnection extends Closeable implements Connection, QueueConnect } else { - _logger.info("Not a hard-error connection not closing."); + _logger.info("Not a hard-error connection not closing: " + cause.getMessage()); } } diff --git a/java/client/src/main/java/org/apache/qpid/client/AMQConnectionURL.java b/java/client/src/main/java/org/apache/qpid/client/AMQConnectionURL.java index b3fbd1f510..24f5ead2d0 100644 --- a/java/client/src/main/java/org/apache/qpid/client/AMQConnectionURL.java +++ b/java/client/src/main/java/org/apache/qpid/client/AMQConnectionURL.java @@ -20,6 +20,14 @@ */ package org.apache.qpid.client; +import org.apache.qpid.framing.AMQShortString; +import org.apache.qpid.jms.BrokerDetails; +import org.apache.qpid.jms.ConnectionURL; +import org.apache.qpid.url.URLHelper; +import org.apache.qpid.url.URLSyntaxException; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + import java.net.URI; import java.net.URISyntaxException; import java.util.HashMap; @@ -27,14 +35,10 @@ import java.util.LinkedList; import java.util.List; import java.util.StringTokenizer; -import org.apache.qpid.framing.AMQShortString; -import org.apache.qpid.jms.BrokerDetails; -import org.apache.qpid.jms.ConnectionURL; -import org.apache.qpid.url.URLHelper; -import org.apache.qpid.url.URLSyntaxException; - public class AMQConnectionURL implements ConnectionURL { + private static final Logger _logger = LoggerFactory.getLogger(AMQConnectionURL.class); + private String _url; private String _failoverMethod; private HashMap _failoverOptions; @@ -162,7 +166,7 @@ public class AMQConnectionURL implements ConnectionURL if ((slash != 0) && (fullURL.charAt(slash - 1) == ':')) { throw URLHelper.parseError(slash - 2, fullURL.indexOf('?') - slash + 2, - "Virtual host looks like a windows path, forward slash not allowed in URL", fullURL); + "Virtual host looks like a windows path, forward slash not allowed in URL", fullURL); } else { @@ -182,7 +186,7 @@ public class AMQConnectionURL implements ConnectionURL if (colonIndex == -1) { throw URLHelper.parseError(AMQ_PROTOCOL.length() + 3, userinfo.length(), - "Null password in user information not allowed.", _url); + "Null password in user information not allowed.", _url); } else { @@ -387,7 +391,14 @@ public class AMQConnectionURL implements ConnectionURL if (_password != null) { sb.append(':'); - sb.append(_password); + if (_logger.isDebugEnabled()) + { + sb.append(_password); + } + else + { + sb.append("********"); + } } sb.append('@'); @@ -432,7 +443,7 @@ public class AMQConnectionURL implements ConnectionURL public static void main(String[] args) throws URLSyntaxException { String url2 = - "amqp://ritchiem:bob@temp?brokerlist='tcp://localhost:5672;jcp://fancyserver:3000/',failover='roundrobin'"; + "amqp://ritchiem:bob@temp?brokerlist='tcp://localhost:5672;jcp://fancyserver:3000/',failover='roundrobin'"; // "amqp://user:pass@clientid/virtualhost?brokerlist='tcp://host:1?option1=\'value\',option2=\'value\';vm://:3?option1=\'value\'',failover='method?option1=\'value\',option2='value''"; ConnectionURL connectionurl2 = new AMQConnectionURL(url2); diff --git a/java/client/src/main/java/org/apache/qpid/client/AMQSession.java b/java/client/src/main/java/org/apache/qpid/client/AMQSession.java index 879578bd6c..8f0ad3947a 100644 --- a/java/client/src/main/java/org/apache/qpid/client/AMQSession.java +++ b/java/client/src/main/java/org/apache/qpid/client/AMQSession.java @@ -2319,6 +2319,16 @@ public class AMQSession extends Closeable implements Session, QueueSession, Topi } } + public void declareAndBind(AMQDestination amqd) + throws + AMQException + { + AMQProtocolHandler protocolHandler = getProtocolHandler(); + declareExchange(amqd, protocolHandler, false); + AMQShortString queueName = declareQueue(amqd, protocolHandler); + bindQueue(queueName, amqd.getRoutingKey(), new FieldTable(), amqd.getExchangeName()); + } + /** * Callers must hold the failover mutex before calling this method. * diff --git a/java/client/src/main/java/org/apache/qpid/client/handler/ExchangeBoundOkMethodHandler.java b/java/client/src/main/java/org/apache/qpid/client/handler/ExchangeBoundOkMethodHandler.java index 8f9a84a3a6..862a9be8d4 100644 --- a/java/client/src/main/java/org/apache/qpid/client/handler/ExchangeBoundOkMethodHandler.java +++ b/java/client/src/main/java/org/apache/qpid/client/handler/ExchangeBoundOkMethodHandler.java @@ -1,18 +1,21 @@ /* * - * Copyright (c) 2006 The Apache Software Foundation + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * http://www.apache.org/licenses/LICENSE-2.0 * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. * */ package org.apache.qpid.client.handler; diff --git a/java/client/src/main/java/org/apache/qpid/client/handler/QueueDeleteOkMethodHandler.java b/java/client/src/main/java/org/apache/qpid/client/handler/QueueDeleteOkMethodHandler.java index 81228b4cdc..65060d44d2 100644 --- a/java/client/src/main/java/org/apache/qpid/client/handler/QueueDeleteOkMethodHandler.java +++ b/java/client/src/main/java/org/apache/qpid/client/handler/QueueDeleteOkMethodHandler.java @@ -1,18 +1,21 @@ /* * - * Copyright (c) 2006 The Apache Software Foundation + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * http://www.apache.org/licenses/LICENSE-2.0 * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. * */ package org.apache.qpid.client.handler; diff --git a/java/client/src/test/java/org/apache/qpid/test/unit/client/channelclose/CloseWithBlockingReceiveTest.java b/java/client/src/test/java/org/apache/qpid/test/unit/client/channelclose/CloseWithBlockingReceiveTest.java index d19a6095d5..9600d1e9d3 100644 --- a/java/client/src/test/java/org/apache/qpid/test/unit/client/channelclose/CloseWithBlockingReceiveTest.java +++ b/java/client/src/test/java/org/apache/qpid/test/unit/client/channelclose/CloseWithBlockingReceiveTest.java @@ -1,18 +1,21 @@ /* * - * Copyright (c) 2006 The Apache Software Foundation + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * http://www.apache.org/licenses/LICENSE-2.0 * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. * */ package org.apache.qpid.test.unit.client.channelclose; diff --git a/java/client/src/test/java/org/apache/qpid/test/unit/client/forwardall/CombinedTest.java b/java/client/src/test/java/org/apache/qpid/test/unit/client/forwardall/CombinedTest.java index 9c354ee260..9cde24dd92 100644 --- a/java/client/src/test/java/org/apache/qpid/test/unit/client/forwardall/CombinedTest.java +++ b/java/client/src/test/java/org/apache/qpid/test/unit/client/forwardall/CombinedTest.java @@ -21,9 +21,7 @@ package org.apache.qpid.test.unit.client.forwardall; import junit.framework.TestCase; - import org.apache.qpid.testutil.VMBrokerSetup; - import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -34,6 +32,7 @@ import org.slf4j.LoggerFactory; public class CombinedTest extends TestCase { private static final Logger _logger = LoggerFactory.getLogger(CombinedTest.class); + private int run = 0; protected void setUp() throws Exception { @@ -48,14 +47,18 @@ public class CombinedTest extends TestCase public void testForwardAll() throws Exception { - int services = 2; - ServiceCreator.start("vm://:1", services); + while (run < 10) + { + int services = 2; + ServiceCreator.start("vm://:1", services); + + _logger.info("Starting " + ++run + " client..."); - _logger.info("Starting client..."); + new Client("vm://:1", services).shutdownWhenComplete(); - new Client("vm://:1", services).shutdownWhenComplete(); - _logger.info("Completed successfully!"); + _logger.info("Completed " + run + " successfully!"); + } } public static junit.framework.Test suite() diff --git a/java/client/src/test/java/org/apache/qpid/test/unit/transacted/CommitRollbackTest.java b/java/client/src/test/java/org/apache/qpid/test/unit/transacted/CommitRollbackTest.java index df2a38d0fc..1a45773907 100644 --- a/java/client/src/test/java/org/apache/qpid/test/unit/transacted/CommitRollbackTest.java +++ b/java/client/src/test/java/org/apache/qpid/test/unit/transacted/CommitRollbackTest.java @@ -21,12 +21,10 @@ package org.apache.qpid.test.unit.transacted; import junit.framework.TestCase; - import org.apache.qpid.AMQException; import org.apache.qpid.client.AMQConnection; import org.apache.qpid.client.transport.TransportConnection; import org.apache.qpid.url.URLSyntaxException; - import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -57,6 +55,9 @@ public class CommitRollbackTest extends TestCase private static final Logger _logger = LoggerFactory.getLogger(CommitRollbackTest.class); private static final String BROKER = "vm://:1"; + private boolean _gotone = false; + private boolean _gottwo = false; + private boolean _gottwoRedelivered = false; protected void setUp() throws Exception { @@ -340,57 +341,98 @@ public class CommitRollbackTest extends TestCase * * @throws Exception On error */ - /*public void testSend2ThenRollback() throws Exception + public void testSend2ThenRollback() throws Exception { - assertTrue("session is not transacted", _session.getTransacted()); - assertTrue("session is not transacted", _pubSession.getTransacted()); + int run = 0; + while (run < 10) + { + run++; + _logger.info("Run:" + run); + assertTrue("session is not transacted", _session.getTransacted()); + assertTrue("session is not transacted", _pubSession.getTransacted()); - _logger.info("sending two test messages"); - _publisher.send(_pubSession.createTextMessage("1")); - _publisher.send(_pubSession.createTextMessage("2")); - _pubSession.commit(); + _logger.info("sending two test messages"); + _publisher.send(_pubSession.createTextMessage("1")); + _publisher.send(_pubSession.createTextMessage("2")); + _pubSession.commit(); - _logger.info("getting test message"); - assertEquals("1", ((TextMessage) _consumer.receive(1000)).getText()); + _logger.info("getting test message"); + assertEquals("1", ((TextMessage) _consumer.receive(1000)).getText()); - _logger.info("rolling back"); - _session.rollback(); + _logger.info("rolling back"); + _session.rollback(); - _logger.info("receiving result"); - Message result = _consumer.receive(1000); + _logger.info("receiving result"); + Message result = _consumer.receive(1000); - assertNotNull("test message was consumed and rolled back, but is gone", result); + assertNotNull("test message was consumed and rolled back, but is gone", result); + // Message Order is: - if (((TextMessage) result).getText().equals("2")) - { - assertTrue("Messasge is marked as redelivered", !result.getJMSRedelivered()); + // Send 1 , 2 + // Retrieve 1 and then rollback + // Receieve 1 (redelivered) , 2 (may or may not be redelivered??) - result = _consumer.receive(1000); - assertEquals("1", ((TextMessage) result).getText()); - assertTrue("Messasge is not marked as redelivered", result.getJMSRedelivered()); + verifyMessages(result); + + // Occassionally get message 2 first! +// assertEquals("Should get message one first", "1", ((TextMessage) result).getText()); +// assertTrue("Message is not marked as redelivered", result.getJMSRedelivered()); +// +// result = _consumer.receive(1000); +// assertEquals("Second message should be message 2", "2", ((TextMessage) result).getText()); +// assertTrue("Message is not marked as redelivered", result.getJMSRedelivered()); +// +// result = _consumer.receive(1000); +// assertNull("There should be no more messages", result); + + _session.commit(); } - else + } + + private void verifyMessages(Message result) throws JMSException + { + + if (result == null) { - assertEquals("1", ((TextMessage) result).getText()); - assertTrue("Messasge is not marked as redelivered", result.getJMSRedelivered()); - result = _consumer.receive(1000); - assertNotNull("test message was consumed and rolled back, but is gone", result); - assertEquals("2", ((TextMessage) result).getText()); - assertTrue("Messasge is not marked as redelivered", result.getJMSRedelivered()); + assertTrue("Didn't receive redelivered message one", _gotone); + assertTrue("Didn't receive message two at all", _gottwo | _gottwoRedelivered); + _gotone = false; + _gottwo = false; + _gottwoRedelivered = false; + return; } - result = _consumer.receive(1000); + if (((TextMessage) result).getText().equals("1")) + { + _logger.info("Got 1 redelivered"); + assertTrue("Message is not marked as redelivered", result.getJMSRedelivered()); + assertFalse("Already received message one", _gotone); + _gotone = true; - if (result != null) + } + else { assertEquals("2", ((TextMessage) result).getText()); - assertTrue("Messasge is not marked as redelivered", result.getJMSRedelivered()); - result = _consumer.receive(1000); + + if (result.getJMSRedelivered()) + { + _logger.info("Got 2 redelivered, message was prefetched"); + assertFalse("Already received message redelivered two", _gottwoRedelivered); + + _gottwoRedelivered = true; + } + else + { + _logger.warn("Got 2, message prefetched wasn't cleared or messages was in transit when rollback occured"); + assertFalse("Already received message two", _gottwo); + + _gottwo = true; + } } - assertNull("test message should be null", result); - }*/ + verifyMessages(_consumer.receive(1000)); + } public void testSend2ThenCloseAfter1andTryAgain() throws Exception { @@ -417,12 +459,12 @@ public class CommitRollbackTest extends TestCase _logger.info("receiving result"); - // NOTE: Both msg 1 & 2 will be marked as redelivered as they have both will have been rejected. - // Only the occasion where it is not rejected will it mean it hasn't arrived at the client yet. +// NOTE: Both msg 1 & 2 will be marked as redelivered as they have both will have been rejected. +// Only the occasion where it is not rejected will it mean it hasn't arrived at the client yet. result = _consumer.receive(1000); assertNotNull("test message was consumed and rolled back, but is gone", result); - // The first message back will be either 1 or 2 being redelivered +// The first message back will be either 1 or 2 being redelivered if (result.getJMSRedelivered()) { assertTrue("Messasge is not marked as redelivered" + result, result.getJMSRedelivered()); diff --git a/java/cluster/src/main/java/org/apache/qpid/server/cluster/SimpleBodySendable.java b/java/cluster/src/main/java/org/apache/qpid/server/cluster/SimpleBodySendable.java index f7c40c60b3..bd3757bf97 100644 --- a/java/cluster/src/main/java/org/apache/qpid/server/cluster/SimpleBodySendable.java +++ b/java/cluster/src/main/java/org/apache/qpid/server/cluster/SimpleBodySendable.java @@ -1,18 +1,21 @@ /* * - * Copyright (c) 2006 The Apache Software Foundation + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * http://www.apache.org/licenses/LICENSE-2.0 * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. * */ package org.apache.qpid.server.cluster; diff --git a/java/common/pom.xml b/java/common/pom.xml index 92177b2418..77065345d6 100644 --- a/java/common/pom.xml +++ b/java/common/pom.xml @@ -100,22 +100,34 @@ - + - + + commons-configuration + commons-configuration + + + + commons-cli + commons-cli + + + + + org.slf4j - slf4j-api + slf4j-api 1.4.0 - - org.slf4j - slf4j-log4j12 - 1.4.0 + + org.slf4j + slf4j-log4j12 + 1.4.0 test diff --git a/java/common/src/main/java/org/apache/qpid/framing/AMQShortString.java b/java/common/src/main/java/org/apache/qpid/framing/AMQShortString.java index 05e9473463..df99f6589d 100644 --- a/java/common/src/main/java/org/apache/qpid/framing/AMQShortString.java +++ b/java/common/src/main/java/org/apache/qpid/framing/AMQShortString.java @@ -26,6 +26,10 @@ import org.apache.mina.common.ByteBuffer; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import java.util.Map; +import java.util.WeakHashMap; +import java.lang.ref.WeakReference; + /** * A short string is a representation of an AMQ Short String * Short strings differ from the Java String class by being limited to on ASCII characters (0-127) @@ -34,6 +38,19 @@ import org.slf4j.LoggerFactory; */ public final class AMQShortString implements CharSequence, Comparable { + + private static final ThreadLocal>> _localInternMap = + new ThreadLocal>>() + { + protected Map> initialValue() + { + return new WeakHashMap>(); + }; + }; + + private static final Map> _globalInternMap = + new WeakHashMap>(); + private static final Logger _logger = LoggerFactory.getLogger(AMQShortString.class); private final ByteBuffer _data; @@ -376,4 +393,43 @@ public final class AMQShortString implements CharSequence, Comparable> localMap = + _localInternMap.get(); + + WeakReference ref = localMap.get(this); + AMQShortString internString; + + if(ref != null) + { + internString = ref.get(); + if(internString != null) + { + return internString; + } + } + + + synchronized(_globalInternMap) + { + + ref = _globalInternMap.get(this); + if((ref == null) || ((internString = ref.get()) == null)) + { + internString = new AMQShortString(getBytes()); + ref = new WeakReference(internString); + _globalInternMap.put(internString, ref); + } + + } + localMap.put(internString, ref); + return internString; + + } } diff --git a/java/common/src/main/java/org/apache/qpid/framing/abstraction/MessagePublishInfoConverter.java b/java/common/src/main/java/org/apache/qpid/framing/abstraction/MessagePublishInfoConverter.java index c9e15f18e3..42e2f7ad97 100644 --- a/java/common/src/main/java/org/apache/qpid/framing/abstraction/MessagePublishInfoConverter.java +++ b/java/common/src/main/java/org/apache/qpid/framing/abstraction/MessagePublishInfoConverter.java @@ -1,18 +1,21 @@ /* * - * Copyright (c) 2006 The Apache Software Foundation + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * http://www.apache.org/licenses/LICENSE-2.0 * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. * */ diff --git a/java/common/src/main/java/org/apache/qpid/framing/abstraction/ProtocolVersionMethodConverter.java b/java/common/src/main/java/org/apache/qpid/framing/abstraction/ProtocolVersionMethodConverter.java index 52e82cdf07..99588a0908 100644 --- a/java/common/src/main/java/org/apache/qpid/framing/abstraction/ProtocolVersionMethodConverter.java +++ b/java/common/src/main/java/org/apache/qpid/framing/abstraction/ProtocolVersionMethodConverter.java @@ -1,18 +1,21 @@ /* * - * Copyright (c) 2006 The Apache Software Foundation + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * http://www.apache.org/licenses/LICENSE-2.0 * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. * */ diff --git a/java/common/src/main/java/org/apache/qpid/util/CommandLineParser.java b/java/common/src/main/java/org/apache/qpid/util/CommandLineParser.java index 9bb4a6635f..64e61fe5ff 100644 --- a/java/common/src/main/java/org/apache/qpid/util/CommandLineParser.java +++ b/java/common/src/main/java/org/apache/qpid/util/CommandLineParser.java @@ -483,9 +483,9 @@ public class CommandLineParser } /** - * If a command line has been parsed, calling this method sets all of its parsed options as system properties. + * If a command line has been parsed, calling this method sets all of its parsed options into the specified properties. */ - public void addCommandLineToSysProperties() + public void addCommandLineToProperties(Properties properties) { if (parsedProperties != null) { @@ -494,7 +494,7 @@ public class CommandLineParser String name = (String) propKey; String value = parsedProperties.getProperty(name); - System.setProperty(name, value); + properties.setProperty(name, value); } } } @@ -607,7 +607,9 @@ public class CommandLineParser * instrucitons and calling System.exit on errors. Extracts all trailing name=value pairs from the command line, * and sets them all as system properties and also returns a map of properties containing them. * - * @param args The command line. + * @param args The command line. + * @param commandLine The command line parser. + * @param properties The properties object to inject all parsed properties into (optional may be null). * * @return A set of properties containing all name=value pairs from the command line. * @@ -619,7 +621,7 @@ public class CommandLineParser * @todo Allow the Properties to add trailing options to be specified as an argument rather than hard coding * system properties. Again, gives the caller the option to decide. */ - public static Properties processCommandLine(String[] args, CommandLineParser commandLine) + public static Properties processCommandLine(String[] args, CommandLineParser commandLine, Properties properties) { // Capture the command line arguments or display errors and correct usage and then exit. Properties options = null; @@ -630,7 +632,7 @@ public class CommandLineParser // Add all the trailing command line options (name=value pairs) to system properties. They may be picked up // from there. - commandLine.addCommandLineToSysProperties(); + commandLine.addCommandLineToProperties(properties); } catch (IllegalArgumentException e) { diff --git a/java/distribution/pom.xml b/java/distribution/pom.xml index 8774b04c18..7899ef8912 100644 --- a/java/distribution/pom.xml +++ b/java/distribution/pom.xml @@ -39,8 +39,11 @@ 1.5 ${pom.version} ${project.build.directory} + + + true - + repo1.maven.org @@ -131,6 +134,8 @@ + + assembly:assembly diff --git a/java/distribution/src/main/assembly/bin-test.xml b/java/distribution/src/main/assembly/bin-test.xml index a9e769e312..04d83916e4 100644 --- a/java/distribution/src/main/assembly/bin-test.xml +++ b/java/distribution/src/main/assembly/bin-test.xml @@ -27,38 +27,32 @@ + - src/main/release + ../resources qpid-${qpid.version} DISCLAIMER - LICENSE.txt - NOTICE.txt - README.txt + LICENSE + NOTICE + README + 0444 + + - .. + src/main/release qpid-${qpid.version} - - *.txt - - - - src/main/release/etc - qpid-${qpid.version}/etc - - logging.properties - log4j.properties - + + - src/main/release/docs - qpid-${qpid.version}/docs - - RELEASE_NOTES.txt - + ../release-docs + qpid-${qpid.version} + + target qpid-${qpid.version}/lib @@ -66,107 +60,40 @@ qpid-incubating.jar - - - - - ../common/etc/qpid-run.conf - qpid-${qpid.version}/etc - qpid-run.conf - 420 - - - ../broker/etc/config.xml - qpid-${qpid.version}/etc - config.xml - 420 - - - ../broker/etc/log4j.xml - qpid-${qpid.version}/etc - log4j.xml - 420 - - - ../broker/etc/passwd - qpid-${qpid.version}/etc - passwd - 420 - - - ../broker/etc/qpid-server.conf + + + + ../common/etc qpid-${qpid.version}/etc - qpid-server.conf - 420 - - - ../broker/etc/virtualhosts.xml + 0640 + + + ../broker/etc qpid-${qpid.version}/etc - virtualhosts.xml - 420 - - - ../broker/bin/qpid.start - qpid-${qpid.version}/bin - qpid.start - 493 - - - ../broker/bin/qpid.stop - qpid-${qpid.version}/bin - qpid.stop - 493 - - - ../broker/bin/qpid.stopall - qpid-${qpid.version}/bin - qpid.stopall - 493 - - - ../common/bin/qpid-run - qpid-${qpid.version}/bin - qpid-run - 493 - - - ../broker/bin/qpid-server - qpid-${qpid.version}/bin - qpid-server - 493 - - - ../broker/bin/qpid-server.bat - qpid-${qpid.version}/bin - qpid-server.bat - 493 - - - ../broker/bin/run.bat - qpid-${qpid.version}/bin - run.bat - 493 - - - ../broker/bin/run.sh + 0640 + + + + + ../broker/bin qpid-${qpid.version}/bin - run.sh - 493 - - - ../broker/bin/runAll + 0750 + + + ../common/bin qpid-${qpid.version}/bin - runAll - 493 - - + 0750 + + + qpid-${qpid.version}/lib false + org.apache.qpid:qpid-distribution + org.apache.qpid.management:org.apache.qpid.management.ui org.eclipse.core:org.eclipse.core.commands org.eclipse.core:org.eclipse.core.contenttype diff --git a/java/distribution/src/main/assembly/bin.xml b/java/distribution/src/main/assembly/bin.xml index 0461f0f643..3620659e48 100644 --- a/java/distribution/src/main/assembly/bin.xml +++ b/java/distribution/src/main/assembly/bin.xml @@ -27,38 +27,38 @@ + - src/main/release + ../resources qpid-${qpid.version} DISCLAIMER - LICENSE.txt - NOTICE.txt - README.txt + LICENSE + NOTICE + README + 0444 + + - .. + src/main/release qpid-${qpid.version} - - *.txt - + + - src/main/release/etc - qpid-${qpid.version}/etc - - logging.properties - log4j.properties - + ..//release-docs + qpid-${qpid.version} + + - src/main/release/docs - qpid-${qpid.version}/docs - - RELEASE_NOTES.txt - + ../release-docs + qpid-${qpid.version} + + target qpid-${qpid.version}/lib @@ -66,131 +66,41 @@ qpid-incubating.jar - - - - - ../common/etc/qpid-run.conf - qpid-${qpid.version}/etc - qpid-run.conf - 420 - - - ../broker/etc/config.xml - qpid-${qpid.version}/etc - config.xml - 420 - - - ../broker/etc/jmxremote.access - qpid-${qpid.version}/etc - jmxremote.access - 420 - - - ../broker/etc/transient_config.xml - qpid-${qpid.version}/etc - transient_config.xml - 420 - - - ../broker/etc/persistent_config.xml - qpid-${qpid.version}/etc - persistent_config.xml - 420 - - - ../broker/etc/log4j.xml - qpid-${qpid.version}/etc - log4j.xml - 420 - - - ../broker/etc/passwd - qpid-${qpid.version}/etc - passwd - 420 - - - ../broker/etc/passwdVhost - qpid-${qpid.version}/etc - passwdVhost - 420 - - - ../broker/etc/qpid-server.conf + + + + ../common/etc qpid-${qpid.version}/etc - qpid-server.conf - 420 - - - ../broker/etc/virtualhosts.xml + 0640 + + + ../broker/etc qpid-${qpid.version}/etc - virtualhosts.xml - 420 - - - ../broker/bin/qpid.start - qpid-${qpid.version}/bin - qpid.start - 493 - - - ../broker/bin/qpid.stop - qpid-${qpid.version}/bin - qpid.stop - 493 - - - ../broker/bin/qpid.stopall - qpid-${qpid.version}/bin - qpid.stopall - 493 - - - ../common/bin/qpid-run - qpid-${qpid.version}/bin - qpid-run - 493 - - - ../broker/bin/qpid-server - qpid-${qpid.version}/bin - qpid-server - 493 - - - ../broker/bin/qpid-server.bat - qpid-${qpid.version}/bin - qpid-server.bat - 493 - - - ../broker/bin/run.bat - qpid-${qpid.version}/bin - run.bat - 493 - - - ../broker/bin/run.sh + 0640 + + + + + ../broker/bin qpid-${qpid.version}/bin - run.sh - 493 - - - ../broker/bin/runAll + 0750 + + + ../common/bin qpid-${qpid.version}/bin - runAll - 493 - - + 0750 + + + + qpid-${qpid.version}/lib false + org.apache.qpid:qpid-distribution + org.apache.qpid.management:org.apache.qpid.management.ui org.eclipse.core:org.eclipse.core.commands org.eclipse.core:org.eclipse.core.contenttype diff --git a/java/distribution/src/main/assembly/management-eclipse-plugin-unix.xml b/java/distribution/src/main/assembly/management-eclipse-plugin-unix.xml index 1318248b2a..02ede019e5 100644 --- a/java/distribution/src/main/assembly/management-eclipse-plugin-unix.xml +++ b/java/distribution/src/main/assembly/management-eclipse-plugin-unix.xml @@ -38,13 +38,21 @@ --> + + + - src/main/release - qpidmc + ../resources + qpid-${qpid.version} - DISCLAIMER + DISCLAIMER + LICENSE + NOTICE + README + 0444 + .. qpidmc @@ -52,20 +60,23 @@ *.txt + - src/main/release/docs - qpidmc/docs - - RELEASE_NOTES.txt - + src/main/release + qpidmc + + + + ../release-docs + qpidmc + + ../management/eclipse-plugin/src/main/resources/unix/configuration qpidmc/configuration - - ** - + ../management/eclipse-plugin/src/main/resources qpidmc @@ -73,6 +84,7 @@ license.eclipse.txt + ../management/eclipse-plugin qpidmc @@ -80,13 +92,14 @@ README.txt + ../management/eclipse-plugin/bin qpidmc/bin qpidmc*.sh - 777 + 0777 @@ -100,7 +113,7 @@ runtime - + qpidmc/eclipse/plugins ${artifactId}_${version}.${extension} diff --git a/java/distribution/src/main/assembly/management-eclipse-plugin.xml b/java/distribution/src/main/assembly/management-eclipse-plugin.xml index 826128b42f..05df2c030b 100644 --- a/java/distribution/src/main/assembly/management-eclipse-plugin.xml +++ b/java/distribution/src/main/assembly/management-eclipse-plugin.xml @@ -24,55 +24,55 @@ zip - + + + - src/main/release + ../resources qpidmc - DISCLAIMER + DISCLAIMER + LICENSE + NOTICE + README + 0444 + - .. + src/main/release + qpidmc + + + + + ../release-docs qpidmc - - *.txt - + + - src/main/release/docs - qpidmc/docs + .. + qpidmc - RELEASE_NOTES.txt + *.txt + ../management/eclipse-plugin/src/main/resources/win32/configuration qpidmc/configuration - - ** - + ../management/eclipse-plugin/src/main/resources qpidmc/eclipse *.* - + + ../management/eclipse-plugin qpidmc @@ -80,14 +80,20 @@ README.txt + ../management/eclipse-plugin/bin qpidmc/bin - - ** - - 777 + + + qpidmc*.sh + + 0777 + + + + ../management/eclipse-plugin/src/main/resources/sasl qpidmc/eclipse/plugins/jmxremote.sasl_1.0.1/META-INF @@ -107,7 +113,7 @@ org.apache.qpid:qpid-common org.apache.qpid:qpid-broker org.apache.qpid:qpid-client - commons-cli:commons-cli + commons-cli:commons-cli commons-configuration:commons-configuration commons-lang:commons-lang org.apache.mina:mina-filter-ssl diff --git a/java/distribution/src/main/assembly/src.xml b/java/distribution/src/main/assembly/src.xml index 8aa6183b4d..efdc4d98f4 100644 --- a/java/distribution/src/main/assembly/src.xml +++ b/java/distribution/src/main/assembly/src.xml @@ -27,24 +27,31 @@ - - src/main/release + + ../resources qpid-${qpid.version}-src - DISCLAIMER - LICENSE.txt - licenses/*.* - NOTICE.txt - README.txt - BUILDING.txt + DISCLAIMER + LICENSE + NOTICE + README + + + src/main/release + qpid-${qpid.version}-src + + + + + ../release-docs + qpid-${qpid.version}-src + + .. qpid-${qpid.version}-src/java - - **/* - build.xml distribution/build.xml @@ -71,24 +78,29 @@ **/eclipse-plugin/src/main/resources/** + ../../gentools qpid-${qpid.version}-src/gentools - - **/* - **/build **/build/**/* **/*.class + ../../specs qpid-${qpid.version}-src/specs - **/* + amqp.0-8.xml + cluster.0-8.xml + + + + ../../python + qpid-${qpid.version}-src/python diff --git a/java/distribution/src/main/release/DISCLAIMER b/java/distribution/src/main/release/DISCLAIMER deleted file mode 100644 index c321113c9e..0000000000 --- a/java/distribution/src/main/release/DISCLAIMER +++ /dev/null @@ -1,5 +0,0 @@ -Apache Qpid is an effort undergoing incubation at the Apache Software Foundation (ASF), sponsored by the Apache Incubator PMC. - -Incubation is required of all newly accepted projects until a further review indicates that the infrastructure, communications, and decision making process have stabilized in a manner consistent with other successful ASF projects. - -While incubation status is not necessarily a reflection of the completeness or stability of the code, it does indicate that the project has yet to be fully endorsed by the ASF. diff --git a/java/distribution/src/main/release/LICENSE.txt b/java/distribution/src/main/release/LICENSE.txt deleted file mode 100755 index 6b0b1270ff..0000000000 --- a/java/distribution/src/main/release/LICENSE.txt +++ /dev/null @@ -1,203 +0,0 @@ - - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright [yyyy] [name of copyright owner] - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. - diff --git a/java/distribution/src/main/release/NOTICE.txt b/java/distribution/src/main/release/NOTICE.txt deleted file mode 100644 index 82d3dbc632..0000000000 --- a/java/distribution/src/main/release/NOTICE.txt +++ /dev/null @@ -1,36 +0,0 @@ -========================================================================= -== NOTICE file corresponding to the section 4 d of == -== the Apache License, Version 2.0, == -== in this case for the Apache Qpid distribution. == -========================================================================= - -This product includes software developed by the Apache Software Foundation -(http://www.apache.org/). - -Please read the LICENSE.txt file present in the root directory of this -distribution. - - -Aside from contributions to the Apache Qpid project, this software also -includes (binary only): - - - The SAXON XSLT Processor from Michael Kay distributed under the - Mozilla Public License v1.0, which is available for download at - http://saxon.sourceforge.net/ - - - The JUnit regression testing framework written by Erich Gamma - and Kent Beck and distributed under the Common Public License v1.0. - JUnit is available for download at - http://sourceforge.net/projects/junit/ - - - The Simple Logging Facade For Java (slf4j), Copyright (c) - 2004-2005 SLF4J.ORG, Copyright (c) 2004-2005 QOS.ch. slf4j is - licensed under identical terms to the MIT/X11 license and - available for download at http://www.slf4j.org/ - - - Software from the Eclipse project. The binaries from this project are - distributed under the Eclipse Public License and can be donwloaded - from http://www.eclipse.org/ - - - diff --git a/java/distribution/src/main/release/README.txt b/java/distribution/src/main/release/README.txt deleted file mode 100644 index 14706170bc..0000000000 --- a/java/distribution/src/main/release/README.txt +++ /dev/null @@ -1,104 +0,0 @@ - -Documentation --------------- -All of our user documentation for the Qpid Java components can be accessed on our wiki at: - -http://cwiki.apache.org/confluence/display/qpid/Qpid+Java+Documentation - -This includes a Getting Started Guide and FAQ as well as detailed developer documentation. -However, here's a VERY quick guide to running the installed Qpid broker, once you have installed it somewhere ! - - -Running the Broker ------------------- - -To run the broker, set the QPID_HOME environment variable to -distribution directory and add $QPID_HOME/bin to your PATH. Then run -the qpid-server shell script or qpid-server.bat batch file to start -the broker. By default, the broker will use $QPID_HOME/etc to find -the configuration files. You can supply a custom configuration using -the -c argument. - -For example: - -qpid-server -c ~/etc/config.xml - -You can get a list of all command line arguments by using the -h argument. - - -Developing ----------- - -In order to build Qpid you need Ant 1.6.5. Use ant -p to list the -available targets. The default ant target, build, creates a working -development-mode distribution in the build directory. To run the -scripts in build/bin set QPID_HOME to the build directory and put -${QPID_HOME}/bin on your PATH. The scripts in that directory include -the standard ones in the distribution and a number of testing scripts. - - -Running Tests -------------- - -The simplest test to ensure everything is working is the "service -request reply" test. This involves one client that is known as a -"service provider" and it listens on a well-known queue for -requests. Another client, known as the "service requester" creates a -private (temporary) response queue, creates a message with the private -response queue set as the "reply to" field and then publishes the -message to the well known service queue. The test allows you to time -how long it takes to send messages and receive the response back. It -also allows varying of the message size. - -You must start the service provider first: - -serviceProvidingClient.sh nop host:port - -where host:port is the host and port you are running the broker -on. - -To run the service requester: - -serviceRequestingClient.sh nop host:post - -This requests messages, each of size . After -receiving all the messages the client outputs the rate it achieved. - -A more realistic test is the "headers test", which tests the -performance of routing messages based on message headers to a -configurable number of clients (e.g. 50). A publisher sends 10000 -messages to each client and waits to receive a message from each -client when it has received all the messages. - -You run the listener processes first: - -run_many.sh 10 header "headersListener.sh -host 10.0.0.1 -port 5672" - -In this command, the first argument means start 10 processes, the -second is just a name use in the log files generated and the third -argument is the command to run. In this case it runs another shell -script but it could be anything. - -Then run the publisher process: - -headersPublisher.sh -host 10.0.0.1 -port 5672 10000 10 - -The last two arguments are: the number of messages to send to each -client, and the number of clients. - -Note that before starting the publisher you should wait about 30 -seconds to ensure all the clients are registered with the broker (you -can see this from the broker output). Otherwise the numbers will be -slightly skewed. - -A third useful test, which can easily be ported to other JMS -implementations is the "topic test". It does the same as the headers -test but using a standard topic (e.g. pub sub). - -To run the listeners: - -run_many.sh 10 topic "topicListener.sh -host 10.0.0.1 -port 5672" - -and to run the publisher: - -topicPublisher.sh -host 10.0.0.1 -port 5672 -clients 10 -messages 10000 diff --git a/java/etc/coding_standards.xml b/java/etc/coding_standards.xml index 00b1a9516a..8f8b808884 100644 --- a/java/etc/coding_standards.xml +++ b/java/etc/coding_standards.xml @@ -1,8 +1,9 @@ + - + diff --git a/java/integrationtests/docs/RunningSustainedTests.txt b/java/integrationtests/docs/RunningSustainedTests.txt index 2b37f4c5a7..db4405a32d 100644 --- a/java/integrationtests/docs/RunningSustainedTests.txt +++ b/java/integrationtests/docs/RunningSustainedTests.txt @@ -1,15 +1,17 @@ In addition to the integration tests the framework provided by this package also allows for sustained tests to be run. Currently avaible tests: -- org.apache.qpid.sustained.SustainedTestClient : Pub Sub test to determine steady state throughput. +- org.apache.qpid.sustained.SustainedClientTestCase : Pub Sub test to determine steady state throughput. Running Tests. Run the tests as per the integration tests. - - Start a broker - - Start at least one Client [java org.apache.qpid.sustained.TestClient], ensuring unique naming - - Start Test Controller [java org.apache.qpid.sustained.TestCoordinator] - - Additional Test clients can be started: - [java org.apache.qpid.sustained.TestClient -j org.apache.qpid.sustained.SustainedTestClient] +- Start a broker +- Start at least one test client [java org.apache.qpid.interop.TestClient], ensuring unique naming. + +- Start the test coordinator with the 'fanout' engine, on the sustained test case [java org.apache.qpid.test.framework.distributedtesting.Coordinator] + +- Additional Test clients can be started and joined into the running test: [java org.apache.qpid.interop.TestClient -j] + diff --git a/java/integrationtests/pom.xml b/java/integrationtests/pom.xml index 9ccd153f54..89fd5ede28 100644 --- a/java/integrationtests/pom.xml +++ b/java/integrationtests/pom.xml @@ -40,12 +40,16 @@ - org.apache.qpid qpid-client + + org.apache.qpid + qpid-systests + + org.slf4j slf4j-log4j12 diff --git a/java/integrationtests/src/main/java/org/apache/qpid/interop/clienttestcases/TestCase1DummyRun.java b/java/integrationtests/src/main/java/org/apache/qpid/interop/clienttestcases/TestCase1DummyRun.java new file mode 100644 index 0000000000..b119d13a3d --- /dev/null +++ b/java/integrationtests/src/main/java/org/apache/qpid/interop/clienttestcases/TestCase1DummyRun.java @@ -0,0 +1,133 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +package org.apache.qpid.interop.clienttestcases; + +import org.apache.log4j.Logger; + +import org.apache.qpid.test.framework.distributedtesting.InteropClientTestCase; + +import javax.jms.JMSException; +import javax.jms.Message; +import javax.jms.Session; + +/** + * Implements tet case 1, dummy run. This test case sends no test messages, it exists to confirm that the test harness + * is interacting with the coordinator correctly. + * + *

+ *
CRC Card
Responsibilities Collaborations + *
Supply the name of the test case that this implements. + *
Accept/Reject invites based on test parameters. + *
Adapt to assigned roles. + *
Perform test case actions. + *
Generate test reports. + *
+ */ +public class TestCase1DummyRun implements InteropClientTestCase +{ + /** Used for debugging. */ + private static final Logger log = Logger.getLogger(TestCase1DummyRun.class); + + /** + * Should provide the name of the test case that this class implements. The exact names are defined in the + * interop testing spec. + * + * @return The name of the test case that this implements. + */ + public String getName() + { + log.debug("public String getName(): called"); + + return "TC1_DummyRun"; + } + + /** + * Determines whether the test invite that matched this test case is acceptable. + * + * @param inviteMessage The invitation to accept or reject. + * + * @return true to accept the invitation, false to reject it. + * + * @throws JMSException Any JMSException resulting from reading the message are allowed to fall through. + */ + public boolean acceptInvite(Message inviteMessage) throws JMSException + { + log.debug("public boolean acceptInvite(Message inviteMessage): called"); + + // Test parameters don't matter, accept all invites. + return true; + } + + /** + * Assigns the role to be played by this test case. The test parameters are fully specified in the + * assignment message. When this method return the test case will be ready to execute. + * + * @param role The role to be played; sender or receivers. + * @param assignRoleMessage The role assingment message, contains the full test parameters. + * + * @throws JMSException Any JMSException resulting from reading the message are allowed to fall through. + */ + public void assignRole(Roles role, Message assignRoleMessage) throws JMSException + { + log.debug("public void assignRole(Roles role, Message assignRoleMessage): called"); + + // Do nothing, both roles are the same. + } + + /** + * Performs the test case actions. Returning from here, indicates that the sending role has completed its test. + */ + public void start() + { + log.debug("public void start(): called"); + + // Do nothing. + } + + /** + * Gets a report on the actions performed by the test case in its assigned role. + * + * @param session The session to create the report message in. + * + * @return The report message. + * + * @throws JMSException Any JMSExceptions resulting from creating the report are allowed to fall through. + */ + public Message getReport(Session session) throws JMSException + { + log.debug("public Message getReport(Session session): called"); + + // Generate a dummy report, the coordinator expects a report but doesn't care what it is. + return session.createTextMessage("Dummy Run, Ok."); + } + + /** + * Handles incoming test messages. Does nothing. + * + * @param message The incoming test message. + */ + public void onMessage(Message message) + { + log.debug("public void onMessage(Message message = " + message + "): called"); + + // Ignore any messages. + } +} diff --git a/java/integrationtests/src/main/java/org/apache/qpid/interop/clienttestcases/TestCase2BasicP2P.java b/java/integrationtests/src/main/java/org/apache/qpid/interop/clienttestcases/TestCase2BasicP2P.java new file mode 100644 index 0000000000..080bd846ee --- /dev/null +++ b/java/integrationtests/src/main/java/org/apache/qpid/interop/clienttestcases/TestCase2BasicP2P.java @@ -0,0 +1,207 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +package org.apache.qpid.interop.clienttestcases; + +import org.apache.log4j.Logger; + +import org.apache.qpid.test.framework.distributedtesting.InteropClientTestCase; +import org.apache.qpid.test.framework.distributedtesting.TestClient; +import org.apache.qpid.test.framework.TestUtils; + +import javax.jms.*; + +/** + * Implements test case 2, basic P2P. Sends/received a specified number of messages to a specified route on the + * default direct exchange. Produces reports on the actual number of messages sent/received. + * + *

+ *
CRC Card
Responsibilities Collaborations + *
Supply the name of the test case that this implements. + *
Accept/Reject invites based on test parameters. + *
Adapt to assigned roles. + *
Send required number of test messages. + *
Generate test reports. + *
+ */ +public class TestCase2BasicP2P implements InteropClientTestCase +{ + /** Used for debugging. */ + private static final Logger log = Logger.getLogger(TestCase2BasicP2P.class); + + /** Holds the count of test messages received. */ + private int messageCount; + + /** The role to be played by the test. */ + private Roles role; + + /** The number of test messages to send. */ + private int numMessages; + + /** The connection to send the test messages on. */ + private Connection connection; + + /** The session to send the test messages on. */ + private Session session; + + /** The producer to send the test messages with. */ + MessageProducer producer; + + /** + * Should provide the name of the test case that this class implements. The exact names are defined in the + * interop testing spec. + * + * @return The name of the test case that this implements. + */ + public String getName() + { + log.debug("public String getName(): called"); + + return "TC2_BasicP2P"; + } + + /** + * Determines whether the test invite that matched this test case is acceptable. + * + * @param inviteMessage The invitation to accept or reject. + * + * @return true to accept the invitation, false to reject it. + * + * @throws JMSException Any JMSException resulting from reading the message are allowed to fall through. + */ + public boolean acceptInvite(Message inviteMessage) throws JMSException + { + log.debug("public boolean acceptInvite(Message inviteMessage = " + inviteMessage + "): called"); + + // All invites are acceptable. + return true; + } + + /** + * Assigns the role to be played by this test case. The test parameters are fully specified in the + * assignment message. When this method return the test case will be ready to execute. + * + * @param role The role to be played; sender or receivers. + * + * @param assignRoleMessage The role assingment message, contains the full test parameters. + * + * @throws JMSException Any JMSException resulting from reading the message are allowed to fall through. + */ + public void assignRole(Roles role, Message assignRoleMessage) throws JMSException + { + log.debug("public void assignRole(Roles role = " + role + ", Message assignRoleMessage = " + assignRoleMessage + + "): called"); + + // Reset the message count for a new test. + messageCount = 0; + + // Take note of the role to be played. + this.role = role; + + // Create a new connection to pass the test messages on. + connection = TestUtils.createConnection(TestClient.testContextProperties); + session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE); + + // Extract and retain the test parameters. + numMessages = assignRoleMessage.getIntProperty("P2P_NUM_MESSAGES"); + Destination sendDestination = session.createQueue(assignRoleMessage.getStringProperty("P2P_QUEUE_AND_KEY_NAME")); + + log.debug("numMessages = " + numMessages); + log.debug("sendDestination = " + sendDestination); + log.debug("role = " + role); + + switch (role) + { + // Check if the sender role is being assigned, and set up a message producer if so. + case SENDER: + producer = session.createProducer(sendDestination); + break; + + // Otherwise the receivers role is being assigned, so set this up to listen for messages. + case RECEIVER: + MessageConsumer consumer = session.createConsumer(sendDestination); + consumer.setMessageListener(this); + break; + } + + connection.start(); + } + + /** + * Performs the test case actions. Returning from here, indicates that the sending role has completed its test. + * + * @throws JMSException Any JMSException resulting from reading the message are allowed to fall through. + */ + public void start() throws JMSException + { + log.debug("public void start(): called"); + + // Check that the sender role is being performed. + if (role.equals(Roles.SENDER)) + { + Message testMessage = session.createTextMessage("test"); + + for (int i = 0; i < numMessages; i++) + { + producer.send(testMessage); + + // Increment the message count. + messageCount++; + } + } + } + + /** + * Gets a report on the actions performed by the test case in its assigned role. + * + * @param session The session to create the report message in. + * + * @return The report message. + * + * @throws JMSException Any JMSExceptions resulting from creating the report are allowed to fall through. + */ + public Message getReport(Session session) throws JMSException + { + log.debug("public Message getReport(Session session): called"); + + // Close the test connection. + connection.close(); + + // Generate a report message containing the count of the number of messages passed. + Message report = session.createMessage(); + report.setStringProperty("CONTROL_TYPE", "REPORT"); + report.setIntProperty("MESSAGE_COUNT", messageCount); + + return report; + } + + /** + * Counts incoming test messages. + * + * @param message The incoming test message. + */ + public void onMessage(Message message) + { + log.debug("public void onMessage(Message message = " + message + "): called"); + + // Increment the message count. + messageCount++; + } +} diff --git a/java/integrationtests/src/main/java/org/apache/qpid/interop/clienttestcases/TestCase3BasicPubSub.java b/java/integrationtests/src/main/java/org/apache/qpid/interop/clienttestcases/TestCase3BasicPubSub.java new file mode 100644 index 0000000000..a11d045e89 --- /dev/null +++ b/java/integrationtests/src/main/java/org/apache/qpid/interop/clienttestcases/TestCase3BasicPubSub.java @@ -0,0 +1,237 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +package org.apache.qpid.interop.clienttestcases; + +import org.apache.log4j.Logger; + +import org.apache.qpid.test.framework.distributedtesting.InteropClientTestCase; +import org.apache.qpid.test.framework.distributedtesting.TestClient; +import org.apache.qpid.test.framework.TestUtils; + +import javax.jms.*; + +/** + * Implements test case 3, basic pub/sub. Sends/received a specified number of messages to a specified route on the + * default topic exchange, using the specified number of receivers connections. Produces reports on the actual number of + * messages sent/received. + * + *

+ *
CRC Card
Responsibilities Collaborations + *
Supply the name of the test case that this implements. + *
Accept/Reject invites based on test parameters. + *
Adapt to assigned roles. + *
Send required number of test messages using pub/sub. + *
Generate test reports. + *
+ */ +public class TestCase3BasicPubSub implements InteropClientTestCase +{ + /** Used for debugging. */ + private static final Logger log = Logger.getLogger(TestCase3BasicPubSub.class); + + /** Holds the count of test messages received. */ + private int messageCount; + + /** The role to be played by the test. */ + private Roles role; + + /** The number of test messages to send. */ + private int numMessages; + + /** The connections to send/receive the test messages on. */ + private Connection[] connection; + + /** The sessions to send/receive the test messages on. */ + private Session[] session; + + /** The producer to send the test messages with. */ + MessageProducer producer; + + /** + * Should provide the name of the test case that this class implements. The exact names are defined in the + * interop testing spec. + * + * @return The name of the test case that this implements. + */ + public String getName() + { + log.debug("public String getName(): called"); + + return "TC3_BasicPubSub"; + } + + /** + * Determines whether the test invite that matched this test case is acceptable. + * + * @param inviteMessage The invitation to accept or reject. + * + * @return true to accept the invitation, false to reject it. + * + * @throws javax.jms.JMSException Any JMSException resulting from reading the message are allowed to fall through. + */ + public boolean acceptInvite(Message inviteMessage) throws JMSException + { + log.debug("public boolean acceptInvite(Message inviteMessage = " + inviteMessage + "): called"); + + // All invites are acceptable. + return true; + } + + /** + * Assigns the role to be played by this test case. The test parameters are fully specified in the + * assignment message. When this method return the test case will be ready to execute. + * + * @param role The role to be played; sender or receivers. + * + * @param assignRoleMessage The role assingment message, contains the full test parameters. + * + * @throws JMSException Any JMSException resulting from reading the message are allowed to fall through. + */ + public void assignRole(Roles role, Message assignRoleMessage) throws JMSException + { + log.debug("public void assignRole(Roles role = " + role + ", Message assignRoleMessage = " + assignRoleMessage + + "): called"); + + // Reset the message count for a new test. + messageCount = 0; + + // Take note of the role to be played. + this.role = role; + + // Extract and retain the test parameters. + numMessages = assignRoleMessage.getIntProperty("PUBSUB_NUM_MESSAGES"); + int numReceivers = assignRoleMessage.getIntProperty("PUBSUB_NUM_RECEIVERS"); + String sendKey = assignRoleMessage.getStringProperty("PUBSUB_KEY"); + + log.debug("numMessages = " + numMessages); + log.debug("numReceivers = " + numReceivers); + log.debug("sendKey = " + sendKey); + log.debug("role = " + role); + + switch (role) + { + // Check if the sender role is being assigned, and set up a single message producer if so. + case SENDER: + // Create a new connection to pass the test messages on. + connection = new Connection[1]; + session = new Session[1]; + + connection[0] = TestUtils.createConnection(TestClient.testContextProperties); + session[0] = connection[0].createSession(false, Session.AUTO_ACKNOWLEDGE); + + // Extract and retain the test parameters. + Destination sendDestination = session[0].createTopic(sendKey); + + producer = session[0].createProducer(sendDestination); + break; + + // Otherwise the receivers role is being assigned, so set this up to listen for messages on the required number + // of receivers connections. + case RECEIVER: + // Create the required number of receivers connections. + connection = new Connection[numReceivers]; + session = new Session[numReceivers]; + + for (int i = 0; i < numReceivers; i++) + { + connection[i] = TestUtils.createConnection(TestClient.testContextProperties); + session[i] = connection[i].createSession(false, Session.AUTO_ACKNOWLEDGE); + + sendDestination = session[i].createTopic(sendKey); + + MessageConsumer consumer = session[i].createConsumer(sendDestination); + consumer.setMessageListener(this); + } + + break; + } + + // Start all the connection dispatcher threads running. + for (Connection conn : connection) + { + conn.start(); + } + } + + /** + * Performs the test case actions. Returning from here, indicates that the sending role has completed its test. + * + * @throws JMSException Any JMSException resulting from reading the message are allowed to fall through. + */ + public void start() throws JMSException + { + log.debug("public void start(): called"); + + // Check that the sender role is being performed. + if (role.equals(Roles.SENDER)) + { + Message testMessage = session[0].createTextMessage("test"); + + for (int i = 0; i < numMessages; i++) + { + producer.send(testMessage); + + // Increment the message count. + messageCount++; + } + } + } + + /** + * Gets a report on the actions performed by the test case in its assigned role. + * + * @param session The session to create the report message in. + * + * @return The report message. + * + * @throws JMSException Any JMSExceptions resulting from creating the report are allowed to fall through. + */ + public Message getReport(Session session) throws JMSException + { + log.debug("public Message getReport(Session session): called"); + + // Close the test connections. + for (Connection conn : connection) + { + conn.close(); + } + + // Generate a report message containing the count of the number of messages passed. + Message report = session.createMessage(); + report.setStringProperty("CONTROL_TYPE", "REPORT"); + report.setIntProperty("MESSAGE_COUNT", messageCount); + + return report; + } + + /** + * Counts incoming test messages. + * + * @param message The incoming test message. + */ + public void onMessage(Message message) + { + log.debug("public void onMessage(Message message = " + message + "): called"); + + // Increment the message count. + messageCount++; + } +} diff --git a/java/integrationtests/src/main/java/org/apache/qpid/interop/coordinator/CoordinatingTestCase.java b/java/integrationtests/src/main/java/org/apache/qpid/interop/coordinator/CoordinatingTestCase.java deleted file mode 100644 index d2042be741..0000000000 --- a/java/integrationtests/src/main/java/org/apache/qpid/interop/coordinator/CoordinatingTestCase.java +++ /dev/null @@ -1,263 +0,0 @@ -/* - * - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - * - */ -package org.apache.qpid.interop.coordinator; - -import junit.framework.TestCase; - -import org.apache.log4j.Logger; - -import org.apache.qpid.util.ConversationFactory; - -import javax.jms.*; - -import java.util.Map; - -/** - * A CoordinatingTestCase is a JUnit test case extension that knows how to coordinate test clients that take part in a - * test case as defined in the interop testing specification - * (http://cwiki.apache.org/confluence/display/qpid/Interop+Testing+Specification). - * - *

The real logic of the test cases built on top of this, is embeded in the comparison of the sender and receiver - * reports. An example test method might look like: - * - *

- * public void testExample()
- * {
- *   Properties testConfig = new Properties();
- *   testConfig.add("TEST_CASE", "example");
- *   ...
- *
- *   Report[] reports = sequenceTest(testConfig);
- *
- *   // Compare sender and receiver reports.
- *   if (report[0] ... report[1] ...)
- *   {
- *     Assert.fail("Sender and receiver reports did not match up.");
- *   }
- * }
- *
- * 
- * - *

- *
CRC Card
Responsibilities Collaborations - *
Accept notification of test case participants. {@link InvitingTestDecorator} - *
Accpet JMS Connection to carry out the coordination over. - *
Coordinate the test sequence amongst participants. {@link ConversationFactory} - *
Supply test properties - *
- */ -public abstract class CoordinatingTestCase extends TestCase -{ - /** Used for debugging. */ - private static final Logger log = Logger.getLogger(CoordinatingTestCase.class); - - /** Holds the contact details for the sending test client. */ - protected TestClientDetails sender; - - /** Holds the contact details for the receving test client. */ - protected TestClientDetails receiver; - - /** Holds the conversation factory over which to coordinate the test. */ - protected ConversationFactory conversationFactory; - - /** - * Creates a new coordinating test case with the specified name. - * - * @param name The test case name. - */ - public CoordinatingTestCase(String name) - { - super(name); - } - - /** - * Sets the sender test client to coordinate the test with. - * - * @param sender The contact details of the sending client in the test. - */ - public void setSender(TestClientDetails sender) - { - log.debug("public void setSender(TestClientDetails sender = " + sender + "): called"); - - this.sender = sender; - } - - /** - * Sets the receiving test client to coordinate the test with. - * - * @param receiver The contact details of the sending client in the test. - */ - public void setReceiver(TestClientDetails receiver) - { - log.debug("public void setReceiver(TestClientDetails receiver = " + receiver + "): called"); - - this.receiver = receiver; - } - - /** - * Supplies the sending test client. - * - * @return The sending test client. - */ - public TestClientDetails getSender() - { - return sender; - } - - /** - * Supplies the receiving test client. - * - * @return The receiving test client. - */ - public TestClientDetails getReceiver() - { - return receiver; - } - - /** - * Returns the name of the current test method of this test class, with the sending and receiving client names - * appended on to it, so that the resulting name unqiuely identifies the test and the clients that participated - * in it. - * - * @return The unique test and client name. - */ - public String getName() - { - if ((sender == null) || (receiver == null)) - { - return super.getName(); - } - else - { - return super.getName() + "_sender_" + sender.clientName + "_receiver_" + receiver.clientName; - } - } - - /** - * Should provide a translation from the junit method name of a test to its test case name as defined in the - * interop testing specification. For example the method "testP2P" might map onto the interop test case name - * "TC2_BasicP2P". - * - * @param methodName The name of the JUnit test method. - * - * @return The name of the corresponding interop test case. - */ - public abstract String getTestCaseNameForTestMethod(String methodName); - - /** - * Accepts the conversation factory over which to hold the test coordinating conversation. - * - * @param conversationFactory The conversation factory to coordinate the test over. - */ - public void setConversationFactory(ConversationFactory conversationFactory) - { - this.conversationFactory = conversationFactory; - } - - /** - * Holds a test coordinating conversation with the test clients. This is the basic implementation of the inner - * loop of Use Case 5. It consists of assigning the test roles, begining the test and gathering the test reports - * from the participants. - * - * @param testProperties The test case definition. - * - * @return The test results from the senders and receivers. - * - * @throws JMSException All underlying JMSExceptions are allowed to fall through. - */ - protected Message[] sequenceTest(Map testProperties) throws JMSException - { - log.debug("protected Message[] sequenceTest(Object... testProperties = " + testProperties + "): called"); - - Session session = conversationFactory.getSession(); - Destination senderControlTopic = session.createTopic(sender.privateControlKey); - Destination receiverControlTopic = session.createTopic(receiver.privateControlKey); - - ConversationFactory.Conversation senderConversation = conversationFactory.startConversation(); - ConversationFactory.Conversation receiverConversation = conversationFactory.startConversation(); - - // Assign the sender role to the sending test client. - Message assignSender = conversationFactory.getSession().createMessage(); - setPropertiesOnMessage(assignSender, testProperties); - assignSender.setStringProperty("CONTROL_TYPE", "ASSIGN_ROLE"); - assignSender.setStringProperty("ROLE", "SENDER"); - - senderConversation.send(senderControlTopic, assignSender); - - // Assign the receiver role the receiving client. - Message assignReceiver = session.createMessage(); - setPropertiesOnMessage(assignReceiver, testProperties); - assignReceiver.setStringProperty("CONTROL_TYPE", "ASSIGN_ROLE"); - assignReceiver.setStringProperty("ROLE", "RECEIVER"); - - receiverConversation.send(receiverControlTopic, assignReceiver); - - // Wait for the senders and receivers to confirm their roles. - senderConversation.receive(); - receiverConversation.receive(); - - // Start the test. - Message start = session.createMessage(); - start.setStringProperty("CONTROL_TYPE", "START"); - - senderConversation.send(senderControlTopic, start); - - // Wait for the test sender to return its report. - Message senderReport = senderConversation.receive(); - - try - { - Thread.sleep(500); - } - catch (InterruptedException e) - { } - - // Ask the receiver for its report. - Message statusRequest = session.createMessage(); - statusRequest.setStringProperty("CONTROL_TYPE", "STATUS_REQUEST"); - - receiverConversation.send(receiverControlTopic, statusRequest); - - // Wait for the receiver to send its report. - Message receiverReport = receiverConversation.receive(); - - return new Message[] { senderReport, receiverReport }; - } - - /** - * Sets properties of different types on a JMS Message. - * - * @param message The message to set properties on. - * @param properties The property name/value pairs to set. - * - * @throws JMSException All underlying JMSExceptions are allowed to fall through. - */ - public void setPropertiesOnMessage(Message message, Map properties) throws JMSException - { - for (Map.Entry entry : properties.entrySet()) - { - String name = entry.getKey(); - Object value = entry.getValue(); - - message.setObjectProperty(name, value); - } - } -} diff --git a/java/integrationtests/src/main/java/org/apache/qpid/interop/coordinator/Coordinator.java b/java/integrationtests/src/main/java/org/apache/qpid/interop/coordinator/Coordinator.java deleted file mode 100644 index 6eec20769a..0000000000 --- a/java/integrationtests/src/main/java/org/apache/qpid/interop/coordinator/Coordinator.java +++ /dev/null @@ -1,388 +0,0 @@ -/* - * - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - * - */ -package org.apache.qpid.interop.coordinator; - -import java.io.*; -import java.util.*; -import java.util.concurrent.LinkedBlockingQueue; -import javax.jms.*; -import junit.framework.Test; -import junit.framework.TestResult; -import junit.framework.TestSuite; -import org.apache.log4j.Logger; -import org.apache.qpid.interop.coordinator.testcases.CoordinatingTestCase1DummyRun; -import org.apache.qpid.interop.coordinator.testcases.CoordinatingTestCase2BasicP2P; -import org.apache.qpid.interop.coordinator.testcases.CoordinatingTestCase3BasicPubSub; -import org.apache.qpid.interop.testclient.TestClient; -import org.apache.qpid.util.CommandLineParser; -import org.apache.qpid.util.ConversationFactory; -import org.apache.qpid.util.PrettyPrintingUtils; -import uk.co.thebadgerset.junit.extensions.TKTestResult; -import uk.co.thebadgerset.junit.extensions.TKTestRunner; -import uk.co.thebadgerset.junit.extensions.WrappedSuiteTestDecorator; -import uk.co.thebadgerset.junit.extensions.util.TestContextProperties; - -/** - *

Implements the coordinator client described in the interop testing specification - * (http://cwiki.apache.org/confluence/display/qpid/Interop+Testing+Specification). This coordinator is built on - * top of the JUnit testing framework. - * - *

- *
CRC Card
Responsibilities Collaborations - *
Find out what test clients are available. {@link ConversationFactory} - *
Decorate available tests to run all available clients. {@link InvitingTestDecorator} - *
Attach XML test result logger. - *
Terminate the interop testing framework. - *
- */ -public class Coordinator extends TKTestRunner -{ - private static final Logger log = Logger.getLogger(Coordinator.class); - - public static final String DEFAULT_CONNECTION_PROPS_RESOURCE = "org/apache/qpid/interop/connection.properties"; - - /** Holds the URL of the broker to coordinate the tests on. */ - protected String brokerUrl; - - /** Holds the virtual host to coordinate the tests on. If null, then the default virtual host is used. */ - protected String virtualHost; - - /** Holds the list of all clients that enlisted, when the compulsory invite was issued. */ - protected Set enlistedClients = new HashSet(); - - /** Holds the conversation helper for the control conversation. */ - protected ConversationFactory conversationFactory; - - /** Holds the connection that the coordinating messages are sent over. */ - protected Connection connection; - - /** - * Holds the name of the class of the test currently being run. Ideally passed into the {@link #createTestResult} - * method, but as the signature is already fixed for this, the current value gets pushed here as a member variable. - */ - protected String currentTestClassName; - - /** Holds the path of the directory to output test results too, if one is defined. */ - protected static String _reportDir; - - /** - * Creates an interop test coordinator on the specified broker and virtual host. - * - * @param brokerUrl The URL of the broker to connect to. - * @param virtualHost The virtual host to run all tests on. Optional, may be null. - */ - public Coordinator(String brokerUrl, String virtualHost) - { - log.debug("Coordinator(String brokerUrl = " + brokerUrl + ", String virtualHost = " + virtualHost + "): called"); - - // Retain the connection parameters. - this.brokerUrl = brokerUrl; - this.virtualHost = virtualHost; - } - - /** - * The entry point for the interop test coordinator. This client accepts the following command line arguments: - * - *

- *
-b The broker URL. Mandatory. - *
-h The virtual host. Optional. - *
name=value Trailing argument define name/value pairs. Added to system properties. Optional. - *
- * - * @param args The command line arguments. - */ - public static void main(String[] args) - { - try - { - // Use the command line parser to evaluate the command line with standard handling behaviour (print errors - // and usage then exit if there are errors). - Properties options = - CommandLineParser.processCommandLine(args, - new CommandLineParser( - new String[][] - { - {"b", "The broker URL.", "broker", "false"}, - {"h", "The virtual host to use.", "virtual host", "false"}, - {"o", "The name of the directory to output test timings to.", "dir", "false"} - })); - - // Extract the command line options. - String brokerUrl = options.getProperty("b"); - String virtualHost = options.getProperty("h"); - _reportDir = options.getProperty("o"); - _reportDir = (_reportDir == null) ? "." : _reportDir; - - // Scan for available test cases using a classpath scanner. - Collection> testCaseClasses = - new ArrayList>(); - // ClasspathScanner.getMatches(CoordinatingTestCase.class, "^Test.*", true); - // Hard code the test classes till the classpath scanner is fixed. - Collections.addAll(testCaseClasses, - CoordinatingTestCase1DummyRun.class, - CoordinatingTestCase2BasicP2P.class, - CoordinatingTestCase3BasicPubSub.class); - - // Check that some test classes were actually found. - if (testCaseClasses.isEmpty()) - { - throw new RuntimeException( - "No test classes implementing CoordinatingTestCase were found on the class path."); - } - - int i = 0; - String[] testClassNames = new String[testCaseClasses.size()]; - - for (Class testClass : testCaseClasses) - { - testClassNames[i++] = testClass.getName(); - } - - // Create a coordinator and begin its test procedure. - Coordinator coordinator = new Coordinator(brokerUrl, virtualHost); - - boolean failure = false; - - TestResult testResult = coordinator.start(testClassNames); - - if (failure) - { - System.exit(FAILURE_EXIT); - } - else - { - System.exit(SUCCESS_EXIT); - } - } - catch (Exception e) - { - System.err.println(e.getMessage()); - log.error("Top level handler caught execption.", e); - System.exit(EXCEPTION_EXIT); - } - } - - /** - * Starts all of the test classes to be run by this coordinator running. - * - * @param testClassNames An array of all the coordinating test case implementations. - * - * @return A JUnit TestResult to run the tests with. - * - * @throws Exception Any underlying exceptions are allowed to fall through, and fail the test process. - */ - public TestResult start(String[] testClassNames) throws Exception - { - log.debug("public TestResult start(String[] testClassNames = " + PrettyPrintingUtils.printArray(testClassNames) - + ": called"); - - // Connect to the broker. - connection = TestClient.createConnection(DEFAULT_CONNECTION_PROPS_RESOURCE, brokerUrl, virtualHost); - Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE); - - Destination controlTopic = session.createTopic("iop.control"); - Destination responseQueue = session.createQueue("coordinator"); - - conversationFactory = new ConversationFactory(connection, responseQueue, LinkedBlockingQueue.class); - ConversationFactory.Conversation conversation = conversationFactory.startConversation(); - - connection.start(); - - // Broadcast the compulsory invitation to find out what clients are available to test. - Message invite = session.createMessage(); - invite.setStringProperty("CONTROL_TYPE", "INVITE"); - invite.setJMSReplyTo(responseQueue); - - conversation.send(controlTopic, invite); - - // Wait for a short time, to give test clients an opportunity to reply to the invitation. - Collection enlists = conversation.receiveAll(0, 3000); - - enlistedClients = extractEnlists(enlists); - - // Run the test in the suite using JUnit. - TestResult result = null; - - for (String testClassName : testClassNames) - { - // Record the current test class, so that the test results can be output to a file incorporating this name. - this.currentTestClassName = testClassName; - - result = super.start(new String[]{testClassName}); - } - - // At this point in time, all tests have completed. Broadcast the shutdown message. - Message terminate = session.createMessage(); - terminate.setStringProperty("CONTROL_TYPE", "TERMINATE"); - - conversation.send(controlTopic, terminate); - - return result; - } - - /** - * For a collection of enlist messages, this method pulls out of the client details for the enlisting clients. - * - * @param enlists The enlist messages. - * - * @return A set of enlisting clients, extracted from the enlist messages. - * - * @throws JMSException Any underlying JMSException is allowed to fall through. - */ - public static Set extractEnlists(Collection enlists) throws JMSException - { - log.debug("public static Set extractEnlists(Collection enlists = " + enlists - + "): called"); - - Set enlistedClients = new HashSet(); - - // Retain the list of all available clients. - for (Message enlist : enlists) - { - TestClientDetails clientDetails = new TestClientDetails(); - clientDetails.clientName = enlist.getStringProperty("CLIENT_NAME"); - clientDetails.privateControlKey = enlist.getStringProperty("CLIENT_PRIVATE_CONTROL_KEY"); - - enlistedClients.add(clientDetails); - } - - return enlistedClients; - } - - /** - * Runs a test or suite of tests, using the super class implemenation. This method wraps the test to be run - * in any test decorators needed to add in the coordinators ability to invite test clients to participate in - * tests. - * - * @param test The test to run. - * @param wait Undocumented. Nothing in the JUnit javadocs to say what this is for. - * - * @return The results of the test run. - */ - public TestResult doRun(Test test, boolean wait) - { - log.debug("public TestResult doRun(Test \"" + test + "\", boolean " + wait + "): called"); - - // Wrap all tests in the test suite with WrappedSuiteTestDecorators. This is quite ugly and a bit baffling, - // but the reason it is done is because the JUnit implementation of TestDecorator has some bugs in it. - WrappedSuiteTestDecorator targetTest = null; - - if (test instanceof TestSuite) - { - log.debug("targetTest is a TestSuite"); - - TestSuite suite = (TestSuite) test; - - int numTests = suite.countTestCases(); - log.debug("There are " + numTests + " in the suite."); - - for (int i = 0; i < numTests; i++) - { - Test nextTest = suite.testAt(i); - log.debug("suite.testAt(" + i + ") = " + nextTest); - - if (nextTest instanceof CoordinatingTestCase) - { - log.debug("nextTest is a CoordinatingTestCase"); - } - } - - targetTest = new WrappedSuiteTestDecorator(suite); - log.debug("Wrapped with a WrappedSuiteTestDecorator."); - } - // Wrap the tests in an inviting test decorator, to perform the invite/test cycle. - - targetTest = newTestDecorator(targetTest, enlistedClients, conversationFactory, connection); - - TestSuite suite = new TestSuite(); - suite.addTest(targetTest); - - // Wrap the tests in a scaled test decorator to them them as a 'batch' in one thread. - // targetTest = new ScaledTestDecorator(targetTest, new int[] { 1 }); - - return super.doRun(suite, wait); - } - - protected WrappedSuiteTestDecorator newTestDecorator(WrappedSuiteTestDecorator targetTest, Set enlistedClients, ConversationFactory conversationFactory, Connection connection) - { - return new InvitingTestDecorator(targetTest, enlistedClients, conversationFactory, connection); - } - - /** - * Creates the TestResult object to be used for test runs. - * - * @return An instance of the test result object. - */ - protected TestResult createTestResult() - { - log.debug("protected TestResult createTestResult(): called"); - - TKTestResult result = new TKTestResult(fPrinter.getWriter(), delay, verbose, testCaseName); - - // Check if a directory to output reports to has been specified and attach test listeners if so. - if (_reportDir != null) - { - // Create the report directory if it does not already exist. - File reportDirFile = new File(_reportDir); - - if (!reportDirFile.exists()) - { - reportDirFile.mkdir(); - } - - // Create the timings file (make the name of this configurable as a command line parameter). - Writer timingsWriter = null; - - try - { - File timingsFile = new File(reportDirFile, "TEST." + currentTestClassName + ".xml"); - timingsWriter = new BufferedWriter(new FileWriter(timingsFile), 20000); - } - catch (IOException e) - { - throw new RuntimeException("Unable to create the log file to write test results to: " + e, e); - } - - // Set up a CSV results listener to output the timings to the results file. - XMLTestListener listener = new XMLTestListener(timingsWriter, currentTestClassName); - result.addListener(listener); - result.addTKTestListener(listener); - - // Register the results listeners shutdown hook to flush its data if the test framework is shutdown - // prematurely. - // registerShutdownHook(listener); - - // Record the start time of the batch. - // result.notifyStartBatch(); - - // At this point in time the test class has been instantiated, giving it an opportunity to read its parameters. - // Inform any test listers of the test properties. - result.notifyTestProperties(TestContextProperties.getAccessedProps()); - } - - return result; - } - - public void setReportDir(String reportDir) - { - _reportDir = reportDir; - } -} diff --git a/java/integrationtests/src/main/java/org/apache/qpid/interop/coordinator/InvitingTestDecorator.java b/java/integrationtests/src/main/java/org/apache/qpid/interop/coordinator/InvitingTestDecorator.java deleted file mode 100644 index 8695f7f66f..0000000000 --- a/java/integrationtests/src/main/java/org/apache/qpid/interop/coordinator/InvitingTestDecorator.java +++ /dev/null @@ -1,220 +0,0 @@ -/* - * - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - * - */ -package org.apache.qpid.interop.coordinator; - -import java.util.*; - -import javax.jms.Connection; -import javax.jms.Destination; -import javax.jms.JMSException; -import javax.jms.Message; - -import junit.framework.Test; -import junit.framework.TestResult; - -import org.apache.log4j.Logger; - -import org.apache.qpid.util.ConversationFactory; - -import uk.co.thebadgerset.junit.extensions.WrappedSuiteTestDecorator; - -/** - *

- *
CRC Card
Responsibilities Collaborations - *
Broadcast test invitations and collect enlists. {@link ConversationFactory}. - *
Output test failures for clients unwilling to run the test case. {@link Coordinator} - *
Execute coordinated test cases. {@link CoordinatingTestCase} - *
- */ -public class InvitingTestDecorator extends WrappedSuiteTestDecorator -{ - private static final Logger log = Logger.getLogger(InvitingTestDecorator.class); - - /** Holds the contact information for all test clients that are available and that may take part in the test. */ - Set allClients; - - /** Holds the conversation helper for the control level conversation for coordinating the test through. */ - ConversationFactory conversationFactory; - - /** Holds the connection that the control conversation is held over. */ - Connection connection; - - /** Holds the underlying {@link CoordinatingTestCase}s that this decorator wraps. */ - WrappedSuiteTestDecorator testSuite; - - /** - * Creates a wrapped suite test decorator from another one. - * - * @param suite The test suite. - * @param availableClients The list of all clients that responded to the compulsory invite. - * @param controlConversation The conversation helper for the control level, test coordination conversation. - * @param controlConnection The connection that the coordination messages are sent over. - */ - public InvitingTestDecorator(WrappedSuiteTestDecorator suite, Set availableClients, - ConversationFactory controlConversation, Connection controlConnection) - { - super(suite); - - log.debug("public InvitingTestDecorator(WrappedSuiteTestDecorator suite, Set allClients = " - + availableClients + ", ConversationHelper controlConversation = " + controlConversation + "): called"); - - testSuite = suite; - allClients = availableClients; - conversationFactory = controlConversation; - connection = controlConnection; - } - - /** - * Broadcasts a test invitation and accetps enlisting from participating clients. The wrapped test case is - * then repeated for every combination of test clients (provided the wrapped test case extends - * {@link CoordinatingTestCase}. - * - *

Any JMSExceptions during the invite/enlist conversation will be allowed to fall through as runtime exceptions, - * resulting in the non-completion of the test run. - * - * @todo Better error recovery for failure of the invite/enlist conversation could be added. - * - * @param testResult The the results object to monitor the test results with. - */ - public void run(TestResult testResult) - { - log.debug("public void run(TestResult testResult): called"); - - Collection tests = testSuite.getAllUnderlyingTests(); - - for (Test test : tests) - { - CoordinatingTestCase coordTest = (CoordinatingTestCase) test; - - // Broadcast the invitation to find out what clients are available to test. - Set enlists; - try - { - Message invite = conversationFactory.getSession().createMessage(); - Destination controlTopic = conversationFactory.getSession().createTopic("iop.control"); - ConversationFactory.Conversation conversation = conversationFactory.startConversation(); - - invite.setStringProperty("CONTROL_TYPE", "INVITE"); - invite.setStringProperty("TEST_NAME", coordTest.getTestCaseNameForTestMethod(coordTest.getName())); - - conversation.send(controlTopic, invite); - - // Wait for a short time, to give test clients an opportunity to reply to the invitation. - Collection replies = conversation.receiveAll(allClients.size(), 3000); - enlists = Coordinator.extractEnlists(replies); - } - catch (JMSException e) - { - throw new RuntimeException("There was a JMSException during the invite/enlist conversation.", e); - } - - // Compare the list of willing clients to the list of all available. - Set optOuts = new HashSet(allClients); - optOuts.removeAll(enlists); - - // Output test failures for clients that will not particpate in the test. - Set> failPairs = allPairs(optOuts, allClients); - - for (List failPair : failPairs) - { - CoordinatingTestCase failTest = new OptOutTestCase("testOptOut"); - failTest.setSender(failPair.get(0)); - failTest.setReceiver(failPair.get(1)); - - failTest.run(testResult); - } - - // Loop over all combinations of clients, willing to run the test. - Set> enlistedPairs = allPairs(enlists, enlists); - - for (List enlistedPair : enlistedPairs) - { - // Set the sending and receiving client details on the test case. - coordTest.setSender(enlistedPair.get(0)); - coordTest.setReceiver(enlistedPair.get(1)); - - // Pass down the connection to hold the coordination conversation over. - coordTest.setConversationFactory(conversationFactory); - - // Execute the test case. - coordTest.run(testResult); - } - } - } - - /** - * Prints a string summarizing this test decorator, mainly for debugging purposes. - * - * @return String representation for debugging purposes. - */ - public String toString() - { - return "InvitingTestDecorator: [ testSuite = " + testSuite + " ]"; - } - - /** - * Produces all pairs of combinations of elements from two sets. The ordering of the elements in the pair is - * important, that is the pair is distinct from ; both pairs are generated. For any element, i, in - * both the left and right sets, the reflexive pair is not generated. - * - * @param left The left set. - * @param right The right set. - * - * @return All pairs formed from the permutations of all elements of the left and right sets. - */ - private Set> allPairs(Set left, Set right) - { - log.debug("private Set> allPairs(Set left = " + left + ", Set right = " + right + "): called"); - - Set> results = new HashSet>(); - - // Form all pairs from left to right. - // Form all pairs from right to left. - for (E le : left) - { - for (E re : right) - { - if (!le.equals(re)) - { - results.add(new Pair(le, re)); - results.add(new Pair(re, le)); - } - } - } - - log.debug("results = " + results); - - return results; - } - - /** - * A simple implementation of a pair, using a list. - */ - private class Pair extends ArrayList - { - public Pair(T first, T second) - { - super(); - super.add(first); - super.add(second); - } - } -} diff --git a/java/integrationtests/src/main/java/org/apache/qpid/interop/coordinator/ListeningCoordinatorTest.java b/java/integrationtests/src/main/java/org/apache/qpid/interop/coordinator/ListeningCoordinatorTest.java deleted file mode 100644 index 1b4461f8c2..0000000000 --- a/java/integrationtests/src/main/java/org/apache/qpid/interop/coordinator/ListeningCoordinatorTest.java +++ /dev/null @@ -1,28 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - * - * - */ -package org.apache.qpid.interop.coordinator; - -import javax.jms.Message; - -public interface ListeningCoordinatorTest -{ - public void latejoin(Message message); -} diff --git a/java/integrationtests/src/main/java/org/apache/qpid/interop/coordinator/ListeningTestDecorator.java b/java/integrationtests/src/main/java/org/apache/qpid/interop/coordinator/ListeningTestDecorator.java deleted file mode 100644 index 4312dfbcc6..0000000000 --- a/java/integrationtests/src/main/java/org/apache/qpid/interop/coordinator/ListeningTestDecorator.java +++ /dev/null @@ -1,200 +0,0 @@ -/* - * - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - * - */ -package org.apache.qpid.interop.coordinator; - -import junit.framework.Test; -import junit.framework.TestResult; -import org.apache.log4j.Logger; -import org.apache.qpid.util.ConversationFactory; -import uk.co.thebadgerset.junit.extensions.WrappedSuiteTestDecorator; - -import javax.jms.Connection; -import javax.jms.Destination; -import javax.jms.JMSException; -import javax.jms.Message; -import javax.jms.MessageListener; -import java.util.Collection; -import java.util.Iterator; -import java.util.Set; - -/** - *

CRC Card
Responsibilities Collaborations
Broadcast test - * invitations and collect enlists. {@link ConversationFactory}.
Output test failures for clients - * unwilling to run the test case. {@link Coordinator}
Execute coordinated test cases. {@link - * CoordinatingTestCase}
- */ -public class ListeningTestDecorator extends WrappedSuiteTestDecorator implements MessageListener -{ - private static final Logger log = Logger.getLogger(ListeningTestDecorator.class); - - /** Holds the contact information for all test clients that are available and that may take part in the test. */ - Set allClients; - - /** Holds the conversation helper for the control level conversation for coordinating the test through. */ - ConversationFactory conversationFactory; - - /** Holds the connection that the control conversation is held over. */ - Connection connection; - - /** Holds the underlying {@link CoordinatingTestCase}s that this decorator wraps. */ - WrappedSuiteTestDecorator testSuite; - - /** Hold the current running test case. */ - CoordinatingTestCase _currentTest = null; - - /** - * Creates a wrapped suite test decorator from another one. - * - * @param suite The test suite. - * @param availableClients The list of all clients that responded to the compulsory invite. - * @param controlConversation The conversation helper for the control level, test coordination conversation. - * @param controlConnection The connection that the coordination messages are sent over. - */ - public ListeningTestDecorator(WrappedSuiteTestDecorator suite, Set availableClients, - ConversationFactory controlConversation, Connection controlConnection) - { - super(suite); - - log.debug("public InvitingTestDecorator(WrappedSuiteTestDecorator suite, Set allClients = " - + availableClients + ", ConversationHelper controlConversation = " + controlConversation + "): called"); - - testSuite = suite; - allClients = availableClients; - conversationFactory = controlConversation; - connection = controlConnection; - } - - /** - * Broadcasts a test invitation and accetps enlisting from participating clients. The wrapped test case is then - * repeated for every combination of test clients (provided the wrapped test case extends {@link - * CoordinatingTestCase}. - * - *

Any JMSExceptions during the invite/enlist conversation will be allowed to fall through as runtime - * exceptions, resulting in the non-completion of the test run. - * - * @param testResult The the results object to monitor the test results with. - * - * @todo Better error recovery for failure of the invite/enlist conversation could be added. - */ - public void run(TestResult testResult) - { - log.debug("public void run(TestResult testResult): called"); - - Collection tests = testSuite.getAllUnderlyingTests(); - - for (Test test : tests) - { - CoordinatingTestCase coordTest = (CoordinatingTestCase) test; - - Set enlists = signupClients(coordTest); - - if (enlists.size() == 0) - { - throw new RuntimeException("No clients to test with"); - } - - Iterator clients = enlists.iterator(); - coordTest.setSender(clients.next()); - - while (clients.hasNext()) - { - // Set the sending and receiving client details on the test case. - coordTest.setReceiver(clients.next()); - } - - // Pass down the connection to hold the coordination conversation over. - coordTest.setConversationFactory(conversationFactory); - - - if (coordTest instanceof ListeningCoordinatorTest) - { - _currentTest = coordTest; - } - // Execute the test case. - coordTest.run(testResult); - - _currentTest = null; - } - } - - private Set signupClients(CoordinatingTestCase coordTest) - { - // Broadcast the invitation to find out what clients are available to test. - Set enlists; - try - { - Message invite = conversationFactory.getSession().createMessage(); - Destination controlTopic = conversationFactory.getSession().createTopic("iop.control"); - ConversationFactory.Conversation conversation = conversationFactory.startConversation(); - - invite.setStringProperty("CONTROL_TYPE", "INVITE"); - invite.setStringProperty("TEST_NAME", coordTest.getTestCaseNameForTestMethod(coordTest.getName())); - - conversation.send(controlTopic, invite); - - // Wait for a short time, to give test clients an opportunity to reply to the invitation. - Collection replies = conversation.receiveAll(allClients.size(), 5000); - - log.debug("Received " + replies.size() + " enlist replies"); - - enlists = Coordinator.extractEnlists(replies); - - //Create topic to listen on for latejoiners - Destination listenTopic = conversationFactory.getSession().createTopic("iop.control.test." + coordTest.getTestCaseNameForTestMethod(coordTest.getName())); - - //Listen for joiners - conversationFactory.getSession().createConsumer(listenTopic).setMessageListener(this); - log.debug("Created consumer on :" + listenTopic); - } - catch (JMSException e) - { - throw new RuntimeException("There was a JMSException during the invite/enlist conversation.", e); - } - - return enlists; - } - - /** - * Prints a string summarizing this test decorator, mainly for debugging purposes. - * - * @return String representation for debugging purposes. - */ - public String toString() - { - return "ListeningTestDecorator: [ testSuite = " + testSuite + " ]"; - } - - - public void onMessage(Message message) - { - try - { - if (message.getStringProperty("CONTROL_TYPE").equals("LATEJOIN")) - { - ((ListeningCoordinatorTest) _currentTest).latejoin(message); - } - } - catch (JMSException e) - { - log.debug("Unable to process message:" + message); - } - } -} diff --git a/java/integrationtests/src/main/java/org/apache/qpid/interop/coordinator/OptOutTestCase.java b/java/integrationtests/src/main/java/org/apache/qpid/interop/coordinator/OptOutTestCase.java deleted file mode 100644 index 42a382a898..0000000000 --- a/java/integrationtests/src/main/java/org/apache/qpid/interop/coordinator/OptOutTestCase.java +++ /dev/null @@ -1,65 +0,0 @@ -/* - * - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - * - */ -package org.apache.qpid.interop.coordinator; - -import junit.framework.Assert; - -/** - * An OptOutTestCase is a test case that automatically fails. It is used when a list of test clients has been generated - * from a compulsory invite, but only some of those clients have responded to a specific test case invite. The clients - * that did not respond, are automatically given a fail for the test. - * - *

- *
CRC Card
Responsibilities Collaborations - *
Fail the test with a suitable reason. - *
- */ -public class OptOutTestCase extends CoordinatingTestCase -{ - /** - * Creates a new coordinating test case with the specified name. - * - * @param name The test case name. - */ - public OptOutTestCase(String name) - { - super(name); - } - - /** Generates an appropriate test failure assertion. */ - public void testOptOut() - { - Assert.fail("One of " + getSender() + " and " + getReceiver() + " opted out of the test."); - } - - /** - * Should provide a translation from the junit method name of a test to its test case name as defined in the - * interop testing specification. For example the method "testP2P" might map onto the interop test case name - * "TC2_BasicP2P". - * - * @param methodName The name of the JUnit test method. - * @return The name of the corresponding interop test case. - */ - public String getTestCaseNameForTestMethod(String methodName) - { - return "OptOutTest"; - } -} diff --git a/java/integrationtests/src/main/java/org/apache/qpid/interop/coordinator/TestClientDetails.java b/java/integrationtests/src/main/java/org/apache/qpid/interop/coordinator/TestClientDetails.java deleted file mode 100644 index c4a9d39cd8..0000000000 --- a/java/integrationtests/src/main/java/org/apache/qpid/interop/coordinator/TestClientDetails.java +++ /dev/null @@ -1,87 +0,0 @@ -/* - * - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - * - */ -package org.apache.qpid.interop.coordinator; - -/** - *

- *
CRC Card
Responsibilities Collaborations - *
- */ -public class TestClientDetails -{ - /** The test clients name. */ - public String clientName; - - /* The test clients unique sequence number. Not currently used. */ - - /** The routing key of the test clients control topic. */ - public String privateControlKey; - - /** - * Two TestClientDetails are considered to be equal, iff they have the same client name. - * - * @param o The object to compare to. - * - * @return If the object to compare to is a TestClientDetails equal to this one, false otherwise. - */ - public boolean equals(Object o) - { - if (this == o) - { - return true; - } - - if (!(o instanceof TestClientDetails)) - { - return false; - } - - final TestClientDetails testClientDetails = (TestClientDetails) o; - - if ((clientName != null) ? (!clientName.equals(testClientDetails.clientName)) - : (testClientDetails.clientName != null)) - { - return false; - } - - return true; - } - - /** - * Computes a hash code compatible with the equals method; based on the client name alone. - * - * @return A hash code for this. - */ - public int hashCode() - { - return ((clientName != null) ? clientName.hashCode() : 0); - } - - /** - * Outputs the client name and address details. Mostly used for debugging purposes. - * - * @return The client name and address. - */ - public String toString() - { - return "TestClientDetails: [ clientName = " + clientName + ", privateControlKey = " + privateControlKey + " ]"; - } -} diff --git a/java/integrationtests/src/main/java/org/apache/qpid/interop/coordinator/XMLTestListener.java b/java/integrationtests/src/main/java/org/apache/qpid/interop/coordinator/XMLTestListener.java deleted file mode 100644 index 747ba0dd0b..0000000000 --- a/java/integrationtests/src/main/java/org/apache/qpid/interop/coordinator/XMLTestListener.java +++ /dev/null @@ -1,402 +0,0 @@ -/* - * - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - * - */ - -package org.apache.qpid.interop.coordinator; - -import java.io.IOException; -import java.io.PrintWriter; -import java.io.Writer; -import java.util.*; - -import junit.framework.AssertionFailedError; -import junit.framework.Test; -import junit.framework.TestCase; - -import org.apache.log4j.Logger; - -import uk.co.thebadgerset.junit.extensions.listeners.TKTestListener; - -/** - * Listens for test results for a named test and outputs these in the standard JUnit XML format to the specified - * writer. - * - *

The API for this listener accepts notifications about different aspects of a tests results through different - * methods, so some assumption needs to be made as to which test result a notification refers to. For example - * {@link #startTest} will be called, then possibly {@link #timing} will be called, even though the test instance is - * passed in both cases, it is not enough to distinguish a particular run of the test, as the test case instance may - * be being shared between multiple threads, or being run a repeated number of times, and can therfore be re-used - * between calls. The listeners make the assumption that, for every test, a unique thread will call {@link #startTest} - * and {@link #endTest} to delimit each test. All calls to set test parameters, timings, state and so on, will occur - * between the start and end and will be given with the same thread id as the start and end, so the thread id provides - * a unqiue value to identify a particular test run against. - * - *

- *
CRC Card
Responsibilities Collaborations - *
- * - * @todo Merge this class with CSV test listener, making the collection of results common to both, and only factoring - * out the results printing code into sub-classes. Provide a simple XML results formatter with the same format as - * the ant XML formatter, and a more structured one for outputing results with timings and summaries from - * performance tests. - */ -public class XMLTestListener implements TKTestListener -{ - /** Used for debugging. */ - private static final Logger log = Logger.getLogger(XMLTestListener.class); - - /** The results file writer. */ - protected Writer writer; - - /** Holds the results for individual tests. */ - // protected Map results = new LinkedHashMap(); - // protected List results = new ArrayList(); - - /** - * Map for holding results on a per thread basis as they come in. A ThreadLocal is not used as sometimes an - * explicit thread id must be used, where notifications come from different threads than the ones that called - * the test method. - */ - Map threadLocalResults = Collections.synchronizedMap(new LinkedHashMap()); - - /** - * Holds results for tests that have ended. Transferring these results here from the per-thread results map, means - * that the thread id is freed for the thread to generate more results. - */ - List results = new ArrayList(); - - /** Holds the overall error count. */ - protected int errors = 0; - - /** Holds the overall failure count. */ - protected int failures = 0; - - /** Holds the overall tests run count. */ - protected int runs = 0; - - /** Holds the name of the class that tests are being run for. */ - String testClassName; - - /** - * Creates a new XML results output listener that writes to the specified location. - * - * @param writer The location to write results to. - */ - public XMLTestListener(Writer writer, String testClassName) - { - log.debug("public XMLTestListener(Writer writer, String testClassName = " + testClassName + "): called"); - - this.writer = writer; - this.testClassName = testClassName; - } - - /** - * Resets the test results to the default state of time zero, memory usage zero, parameter zero, test passed. - * - * @param test The test to resest any results for. - * @param threadId Optional thread id if not calling from thread that started the test method. May be null. - */ - public void reset(Test test, Long threadId) - { - log.debug("public void reset(Test test = " + test + ", Long threadId = " + threadId + "): called"); - - XMLTestListener.Result r = - (threadId == null) ? threadLocalResults.get(Thread.currentThread().getId()) : threadLocalResults.get(threadId); - - r.error = null; - r.failure = null; - - } - - /** - * A test started. - */ - public void startTest(Test test) - { - log.debug("public void startTest(Test test = " + test + "): called"); - - Result newResult = new Result(test.getClass().getName(), ((TestCase) test).getName()); - - // Initialize the thread local test results. - threadLocalResults.put(Thread.currentThread().getId(), newResult); - runs++; - } - - /** - * Should be called every time a test completes with the run time of that test. - * - * @param test The name of the test. - * @param nanos The run time of the test in nanoseconds. - * @param threadId Optional thread id if not calling from thread that started the test method. May be null. - */ - public void timing(Test test, long nanos, Long threadId) - { } - - /** - * Should be called every time a test completed with the amount of memory used before and after the test was run. - * - * @param test The test which memory was measured for. - * @param memStart The total JVM memory used before the test was run. - * @param memEnd The total JVM memory used after the test was run. - * @param threadId Optional thread id if not calling from thread that started the test method. May be null. - */ - public void memoryUsed(Test test, long memStart, long memEnd, Long threadId) - { } - - /** - * Should be called every time a parameterized test completed with the int value of its test parameter. - * - * @param test The test which memory was measured for. - * @param parameter The int parameter value. - * @param threadId Optional thread id if not calling from thread that started the test method. May be null. - */ - public void parameterValue(Test test, int parameter, Long threadId) - { } - - /** - * Should be called every time a test completes with the current number of test threads running. - * - * @param test The test for which the measurement is being generated. - * @param threads The number of tests being run concurrently. - * @param threadId Optional thread id if not calling from thread that started the test method. May be null. - */ - public void concurrencyLevel(Test test, int threads, Long threadId) - { } - - /** - * Notifies listeners of the tests read/set properties. - * - * @param properties The tests read/set properties. - */ - public void properties(Properties properties) - { } - - /** - * A test ended. - */ - public void endTest(Test test) - { - log.debug("public void endTest(Test test = " + test + "): called"); - - // Move complete test results into the completed tests list. - Result r = threadLocalResults.get(Thread.currentThread().getId()); - results.add(r); - - // Clear all the test results for the thread. - threadLocalResults.remove(Thread.currentThread().getId()); - } - - /** - * Called when a test completes. Success, failure and errors. This method should be used when registering an - * end test from a different thread than the one that started the test. - * - * @param test The test which completed. - * @param threadId Optional thread id if not calling from thread that started the test method. May be null. - */ - public void endTest(Test test, Long threadId) - { - log.debug("public void endTest(Test test = " + test + ", Long threadId = " + threadId + "): called"); - - // Move complete test results into the completed tests list. - Result r = - (threadId == null) ? threadLocalResults.get(Thread.currentThread().getId()) : threadLocalResults.get(threadId); - results.add(r); - - // Clear all the test results for the thread. - threadLocalResults.remove(Thread.currentThread().getId()); - } - - /** - * An error occurred. - */ - public void addError(Test test, Throwable t) - { - log.debug("public void addError(Test test = " + test + ", Throwable t = " + t + "): called"); - - Result r = threadLocalResults.get(Thread.currentThread().getId()); - r.error = t; - errors++; - } - - /** - * A failure occurred. - */ - public void addFailure(Test test, AssertionFailedError t) - { - log.debug("public void addFailure(Test test = " + test + ", AssertionFailedError t = " + t + "): called"); - - Result r = threadLocalResults.get(Thread.currentThread().getId()); - r.failure = t; - failures++; - } - - /** - * Called when a test completes to mark it as a test fail. This method should be used when registering a - * failure from a different thread than the one that started the test. - * - * @param test The test which failed. - * @param e The assertion that failed the test. - * @param threadId Optional thread id if not calling from thread that started the test method. May be null. - */ - public void addFailure(Test test, AssertionFailedError e, Long threadId) - { - log.debug("public void addFailure(Test test, AssertionFailedError e, Long threadId): called"); - - Result r = - (threadId == null) ? threadLocalResults.get(Thread.currentThread().getId()) : threadLocalResults.get(threadId); - r.failure = e; - failures++; - } - - /** - * Notifies listeners of the start of a complete run of tests. - */ - public void startBatch() - { - log.debug("public void startBatch(): called"); - - // Reset all results counts. - threadLocalResults = Collections.synchronizedMap(new HashMap()); - errors = 0; - failures = 0; - runs = 0; - - // Write out the file header. - try - { - writer.write("\n"); - } - catch (IOException e) - { - throw new RuntimeException("Unable to write the test results.", e); - } - } - - /** - * Notifies listeners of the end of a complete run of tests. - * - * @param parameters The optional test parameters to log out with the batch results. - */ - public void endBatch(Properties parameters) - { - log.debug("public void endBatch(Properties parameters = " + parameters + "): called"); - - // Write out the results. - try - { - // writer.write("\n"); - writer.write("\n"); - - for (Result result : results) - { - writer.write(" \n"); - - if (result.error != null) - { - writer.write(" "); - result.error.printStackTrace(new PrintWriter(writer)); - writer.write(" "); - } - else if (result.failure != null) - { - writer.write(" "); - result.failure.printStackTrace(new PrintWriter(writer)); - writer.write(" "); - } - - writer.write(" \n"); - } - - writer.write("\n"); - writer.flush(); - } - catch (IOException e) - { - throw new RuntimeException("Unable to write the test results.", e); - } - } - - /** - * Used to capture the results of a particular test run. - */ - protected static class Result - { - public Result(String testClass, String testName) - { - this.testClass = testClass; - this.testName = testName; - } - - public String testClass; - public String testName; - - /** Holds the exception that caused error in this test. */ - public Throwable error; - - /** Holds the assertion exception that caused failure in this test. */ - public AssertionFailedError failure; - - /** Holds the error count for this test. */ - // public int errors = 0; - - /** Holds the failure count for this tests. */ - // public int failures = 0; - - /** Holds the overall tests run count for this test. */ - // public int runs = 0; - - /*public boolean equals(Object o) - { - if (this == o) - { - return true; - } - - if (!(o instanceof Result)) - { - return false; - } - - final Result result = (Result) o; - - if ((testClass != null) ? (!testClass.equals(result.testClass)) : (result.testClass != null)) - { - return false; - } - - if ((testName != null) ? (!testName.equals(result.testName)) : (result.testName != null)) - { - return false; - } - - return true; - } - - public int hashCode() - { - int result; - result = ((testClass != null) ? testClass.hashCode() : 0); - result = (29 * result) + ((testName != null) ? testName.hashCode() : 0); - - return result; - }*/ - } -} diff --git a/java/integrationtests/src/main/java/org/apache/qpid/interop/coordinator/testcases/CoordinatingTestCase1DummyRun.java b/java/integrationtests/src/main/java/org/apache/qpid/interop/coordinator/testcases/CoordinatingTestCase1DummyRun.java deleted file mode 100644 index e642ef792b..0000000000 --- a/java/integrationtests/src/main/java/org/apache/qpid/interop/coordinator/testcases/CoordinatingTestCase1DummyRun.java +++ /dev/null @@ -1,85 +0,0 @@ -/* - * - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - * - */ - -package org.apache.qpid.interop.coordinator.testcases; - -import java.util.HashMap; -import java.util.Map; - -import javax.jms.Message; - -import junit.framework.Assert; - -import org.apache.log4j.Logger; - -import org.apache.qpid.interop.coordinator.CoordinatingTestCase; - -/** - *

- *
CRC Card
Responsibilities Collaborations - *
Exercises the interop testing framework without actually sending any test messages. - * {@link org.apache.qpid.interop.coordinator.CoordinatingTestCase} - *
- */ -public class CoordinatingTestCase1DummyRun extends CoordinatingTestCase -{ - /** Used for debugging. */ - private static final Logger log = Logger.getLogger(CoordinatingTestCase1DummyRun.class); - - /** - * Creates a new coordinating test case with the specified name. - * - * @param name The test case name. - */ - public CoordinatingTestCase1DummyRun(String name) - { - super(name); - } - - /** - * Performs the basic P2P test case, "Test Case 2" in the specification. - */ - public void testDummyRun() throws Exception - { - log.debug("public void testDummyRun(): called"); - - Map testConfig = new HashMap(); - testConfig.put("TEST_NAME", "TC1_DummyRun"); - - Message[] reports = sequenceTest(testConfig); - - // Compare sender and receiver reports. - Assert.assertEquals("Expected to get 2 dummy reports.", 2, reports.length); - } - - /** - * Should provide a translation from the junit method name of a test to its test case name as defined in the - * interop testing specification. For example the method "testP2P" might map onto the interop test case name - * "TC2_BasicP2P". - * - * @param methodName The name of the JUnit test method. - * @return The name of the corresponding interop test case. - */ - public String getTestCaseNameForTestMethod(String methodName) - { - return "TC1_DummyRun"; - } -} diff --git a/java/integrationtests/src/main/java/org/apache/qpid/interop/coordinator/testcases/CoordinatingTestCase2BasicP2P.java b/java/integrationtests/src/main/java/org/apache/qpid/interop/coordinator/testcases/CoordinatingTestCase2BasicP2P.java deleted file mode 100644 index b1b2d9f847..0000000000 --- a/java/integrationtests/src/main/java/org/apache/qpid/interop/coordinator/testcases/CoordinatingTestCase2BasicP2P.java +++ /dev/null @@ -1,90 +0,0 @@ -/* - * - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - * - */ - -package org.apache.qpid.interop.coordinator.testcases; - -import java.util.HashMap; -import java.util.Map; - -import javax.jms.Message; - -import junit.framework.Assert; - -import org.apache.log4j.Logger; - -import org.apache.qpid.interop.coordinator.CoordinatingTestCase; - -/** - *

- *
CRC Card
Responsibilities Collaborations - *
Setup p2p test parameters and compare with test output. {@link CoordinatingTestCase} - *
- */ -public class CoordinatingTestCase2BasicP2P extends CoordinatingTestCase -{ - /** Used for debugging. */ - private static final Logger log = Logger.getLogger(CoordinatingTestCase2BasicP2P.class); - - /** - * Creates a new coordinating test case with the specified name. - * - * @param name The test case name. - */ - public CoordinatingTestCase2BasicP2P(String name) - { - super(name); - } - - /** - * Performs the basic P2P test case, "Test Case 2" in the specification. - */ - public void testBasicP2P() throws Exception - { - log.debug("public void testBasicP2P(): called"); - - Map testConfig = new HashMap(); - testConfig.put("TEST_NAME", "TC2_BasicP2P"); - testConfig.put("P2P_QUEUE_AND_KEY_NAME", "tc2queue"); - testConfig.put("P2P_NUM_MESSAGES", 50); - - Message[] reports = sequenceTest(testConfig); - - // Compare sender and receiver reports. - int messagesSent = reports[0].getIntProperty("MESSAGE_COUNT"); - int messagesReceived = reports[1].getIntProperty("MESSAGE_COUNT"); - - Assert.assertEquals("The requested number of messages were not sent.", 50, messagesSent); - Assert.assertEquals("Sender and receiver messages sent did not match up.", messagesSent, messagesReceived); - } - - /** - * Should provide a translation from the junit method name of a test to its test case name as defined in the - * interop testing specification. For example the method "testP2P" might map onto the interop test case name - * "TC2_BasicP2P". - * - * @param methodName The name of the JUnit test method. - * @return The name of the corresponding interop test case. - */ - public String getTestCaseNameForTestMethod(String methodName) - { - return "TC2_BasicP2P"; - } -} diff --git a/java/integrationtests/src/main/java/org/apache/qpid/interop/coordinator/testcases/CoordinatingTestCase3BasicPubSub.java b/java/integrationtests/src/main/java/org/apache/qpid/interop/coordinator/testcases/CoordinatingTestCase3BasicPubSub.java deleted file mode 100644 index 702c240e9a..0000000000 --- a/java/integrationtests/src/main/java/org/apache/qpid/interop/coordinator/testcases/CoordinatingTestCase3BasicPubSub.java +++ /dev/null @@ -1,92 +0,0 @@ -/* - * - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - * - */ - -package org.apache.qpid.interop.coordinator.testcases; - -import java.util.HashMap; -import java.util.Map; - -import javax.jms.Message; - -import junit.framework.Assert; - -import org.apache.log4j.Logger; - -import org.apache.qpid.interop.coordinator.CoordinatingTestCase; - -/** - *

- *
CRC Card
Responsibilities Collaborations - *
Setup pub/sub test parameters and compare with test output. {@link CoordinatingTestCase} - *
- */ -public class CoordinatingTestCase3BasicPubSub extends CoordinatingTestCase -{ - /** Used for debugging. */ - private static final Logger log = Logger.getLogger(CoordinatingTestCase3BasicPubSub.class); - - /** - * Creates a new coordinating test case with the specified name. - * - * @param name The test case name. - */ - public CoordinatingTestCase3BasicPubSub(String name) - { - super(name); - } - - /** - * Performs the basic P2P test case, "Test Case 2" in the specification. - */ - public void testBasicPubSub() throws Exception - { - log.debug("public void testBasicPubSub(): called"); - - Map testConfig = new HashMap(); - testConfig.put("TEST_NAME", "TC3_BasicPubSub"); - testConfig.put("PUBSUB_KEY", "tc3route"); - testConfig.put("PUBSUB_NUM_MESSAGES", 10); - testConfig.put("PUBSUB_NUM_RECEIVERS", 5); - - Message[] reports = sequenceTest(testConfig); - - // Compare sender and receiver reports. - int messagesSent = reports[0].getIntProperty("MESSAGE_COUNT"); - int messagesReceived = reports[1].getIntProperty("MESSAGE_COUNT"); - - Assert.assertEquals("The requested number of messages were not sent.", 10, messagesSent); - Assert.assertEquals("Received messages did not match up to num sent * num receivers.", messagesSent * 5, - messagesReceived); - } - - /** - * Should provide a translation from the junit method name of a test to its test case name as defined in the - * interop testing specification. For example the method "testP2P" might map onto the interop test case name - * "TC2_BasicP2P". - * - * @param methodName The name of the JUnit test method. - * @return The name of the corresponding interop test case. - */ - public String getTestCaseNameForTestMethod(String methodName) - { - return "TC3_BasicPubSub"; - } -} diff --git a/java/integrationtests/src/main/java/org/apache/qpid/interop/old/Listener.java b/java/integrationtests/src/main/java/org/apache/qpid/interop/old/Listener.java deleted file mode 100644 index 5545f8d2dc..0000000000 --- a/java/integrationtests/src/main/java/org/apache/qpid/interop/old/Listener.java +++ /dev/null @@ -1,291 +0,0 @@ -/* - * - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - * - */ -package org.apache.qpid.interop.old; - -import java.util.Random; - -import javax.jms.*; - -import org.apache.log4j.Logger; -import org.apache.log4j.NDC; - -import org.apache.qpid.AMQException; -import org.apache.qpid.client.AMQConnection; -import org.apache.qpid.client.AMQQueue; -import org.apache.qpid.client.AMQSession; -import org.apache.qpid.client.AMQTopic; -import org.apache.qpid.exchange.ExchangeDefaults; -import org.apache.qpid.url.URLSyntaxException; - -/** - * Listener implements the listening end of the Qpid interop tests. It is capable of being run as a standalone listener - * that responds to the test messages send by the publishing end of the tests implemented by {@link org.apache.qpid.interop.old.Publisher}. - * - *

- *
CRC Card
Responsibilities Collaborations - *
Count messages received on a topic. {@link org.apache.qpid.interop.old.Publisher} - *
Send reports on messages received, when requested to. {@link org.apache.qpid.interop.old.Publisher} - *
Shutdown, when requested to. {@link org.apache.qpid.interop.old.Publisher} - *
- * - * @todo This doesn't implement the interop test spec yet. Its a port of the old topic tests but has been adapted with - * interop spec in mind. - * - * @todo I've added lots of field table types in the report message, just to check if the other end can decode them - * correctly. Not really the right place to test this, so remove them from {@link #sendReport()} once a better - * test exists. - */ -public class Listener implements MessageListener -{ - private static Logger log = Logger.getLogger(Listener.class); - - /** The default AMQ connection URL to use for tests. */ - public static final String DEFAULT_URI = "amqp://guest:guest@default/test?brokerlist='tcp://localhost:5672'"; - - /** Holds the name of (routing key for) the topic to receive test messages on. */ - public static final String CONTROL_TOPIC = "topic_control"; - - /** Holds the name of (routing key for) the queue to send reports to. */ - public static final String RESPONSE_QUEUE = "response"; - - /** Holds the JMS Topic to receive test messages on. */ - private final Topic _topic; - - /** Holds the JMS Queue to send reports to. */ - private final Queue _response; - - /** Holds the connection to listen on. */ - private final Connection _connection; - - /** Holds the producer to send control messages on. */ - private final MessageProducer _controller; - - /** Holds the JMS session. */ - private final javax.jms.Session _session; - - /** Holds a flag to indicate that a timer has begun on the first message. Reset when report is sent. */ - private boolean init; - - /** Holds the count of messages received by this listener. */ - private int count; - - /** Used to hold the start time of the first message. */ - private long start; - - /** - * Creates a topic listener using the specified broker URL. - * - * @param connectionUrl The broker URL to listen on. - * - * @throws AMQException If the broker connection cannot be established. - * @throws URLSyntaxException If the broker URL syntax is not correct. - * @throws JMSException Any underlying JMSException is allowed to fall through. - */ - Listener(String connectionUrl) throws AMQException, JMSException, URLSyntaxException - { - log.debug("Listener(String connectionUrl = " + connectionUrl + "): called"); - - // Create a connection to the broker. - _connection = new AMQConnection(connectionUrl); - - // Establish a session on the broker. - _session = _connection.createSession(false, Session.AUTO_ACKNOWLEDGE); - - // Set up the destinations to listen for test and control messages on. - _topic = _session.createTopic(CONTROL_TOPIC); - _response = _session.createQueue(RESPONSE_QUEUE); - - // Set this listener up to listen for incoming messages on the test topic. - _session.createConsumer(_topic).setMessageListener(this); - - // Set up this listener with a producer to send the reports on. - _controller = _session.createProducer(_response); - - _connection.start(); - System.out.println("Waiting for messages..."); - } - - /** - * Starts a test subscriber. The broker URL must be specified as the first command line argument. - * - * @param argv The command line arguments, ignored. - * - * @todo Add command line arguments to configure all aspects of the test. - */ - public static void main(String[] argv) - { - try - { - new Listener(DEFAULT_URI); - } - catch (Exception e) - { - e.printStackTrace(); - } - } - - /** - * Handles all message received by this listener. Test messages are counted, report messages result in a report being sent and - * shutdown messages result in this listener being terminated. - * - * @param message The received message. - */ - public void onMessage(Message message) - { - log.debug("public void onMessage(Message message = " + message + "): called"); - - // Take the start time of the first message if this is the first message. - if (!init) - { - start = System.nanoTime() / 1000000; - count = 0; - init = true; - } - - try - { - // Check if the message is a control message telling this listener to shut down. - if (isShutdown(message)) - { - log.debug("Got a shutdown message."); - shutdown(); - } - // Check if the message is a report request message asking this listener to respond with the message count. - else if (isReport(message)) - { - log.debug("Got a report request message."); - - // Send the message count report. - sendReport(); - - // Reset the initialization flag so that the next message is considered to be the first. - init = false; - } - // Otherwise it is an ordinary test message, so increment the message count. - else - { - count++; - } - } - catch (JMSException e) - { - log.warn("There was a JMSException during onMessage.", e); - } - } - - /** - * Checks a message to see if it is a termination request control message. - * - * @param m The message to check. - * - * @return true if it is a termination request control message, false otherwise. - * - * @throws JMSException Any underlying JMSException is allowed to fall through. - */ - boolean isShutdown(Message m) throws JMSException - { - boolean result = checkTextField(m, "TYPE", "TERMINATION_REQUEST"); - - return result; - } - - /** - * Checks a message to see if it is a report request control message. - * - * @param m The message to check. - * - * @return true if it is a report request control message, false otherwise. - * - * @throws JMSException Any underlying JMSException is allowed to fall through. - */ - boolean isReport(Message m) throws JMSException - { - boolean result = checkTextField(m, "TYPE", "REPORT_REQUEST"); - - return result; - } - - /** - * Checks whether or not a text field on a message has the specified value. - * - * @param m The message to check. - * @param fieldName The name of the field to check. - * @param value The expected value of the field to compare with. - * - * @return trueIf the specified field has the specified value, fals otherwise. - * - * @throws JMSException Any JMSExceptions are allowed to fall through. - */ - private static boolean checkTextField(Message m, String fieldName, String value) throws JMSException - { - //log.debug("private static boolean checkTextField(Message m = " + m + ", String fieldName = " + fieldName - // + ", String value = " + value + "): called"); - - String comp = m.getStringProperty(fieldName); - //log.debug("comp = " + comp); - - boolean result = (comp != null) && comp.equals(value); - //log.debug("result = " + result); - - return result; - } - - /** - * Closes down the connection to the broker. - * - * @throws JMSException Any underlying JMSException is allowed to fall through. - */ - private void shutdown() throws JMSException - { - _session.close(); - _connection.stop(); - _connection.close(); - } - - /** - * Send the report message to the response queue. - * - * @throws JMSException Any underlying JMSException is allowed to fall through. - */ - private void sendReport() throws JMSException - { - log.debug("private void report(): called"); - - // Create the report message. - long time = ((System.nanoTime() / 1000000) - start); - String msg = "Received " + count + " in " + time + "ms"; - Message message = _session.createTextMessage(msg); - - // Shove some more field table types in the message just to see if the other end can handle it. - message.setBooleanProperty("BOOLEAN", true); - //message.setByteProperty("BYTE", (byte) 5); - message.setDoubleProperty("DOUBLE", Math.PI); - message.setFloatProperty("FLOAT", 1.0f); - message.setIntProperty("INT", 1); - message.setShortProperty("SHORT", (short) 1); - message.setLongProperty("LONG", (long) 1827361278); - message.setStringProperty("STRING", "hello"); - - // Send the report message. - _controller.send(message); - log.debug("Sent report: " + msg); - } -} diff --git a/java/integrationtests/src/main/java/org/apache/qpid/interop/old/Publisher.java b/java/integrationtests/src/main/java/org/apache/qpid/interop/old/Publisher.java deleted file mode 100644 index f3a545f580..0000000000 --- a/java/integrationtests/src/main/java/org/apache/qpid/interop/old/Publisher.java +++ /dev/null @@ -1,244 +0,0 @@ -/* - * - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - * - */ -package org.apache.qpid.interop.old; - -import java.util.concurrent.CountDownLatch; -import java.util.concurrent.TimeUnit; - -import javax.jms.*; - -import org.apache.log4j.Logger; - -import org.apache.qpid.AMQException; -import org.apache.qpid.client.AMQConnection; -import org.apache.qpid.url.URLSyntaxException; - -/** - * Publisher is the sending end of Qpid interop tests. It is capable of being run as a standalone publisher - * that sends test messages to the listening end of the tests implemented by {@link org.apache.qpid.interop.old.Listener}. - * - *

- *
CRC Card
Responsibilities Collaborations - *
- * - * @todo This doesn't implement the interop test spec yet. Its a port of the old topic tests but has been adapted with - * interop spec in mind. - * - * @todo I've added lots of field table types in the report request message, just to check if the other end can decode - * them correctly. Not really the right place to test this, so remove them from {@link #doTest()} once a better - * test exists. - */ -public class Publisher implements MessageListener -{ - private static Logger log = Logger.getLogger(Publisher.class); - - /** The default AMQ connection URL to use for tests. */ - public static final String DEFAULT_URI = "amqp://guest:guest@default/test?brokerlist='tcp://localhost:5672'"; - - /** Holds the default test timeout for broker communications before tests give up. */ - public static final int TIMEOUT = 3000; - - /** Holds the routing key for the topic to send test messages on. */ - public static final String CONTROL_TOPIC = "topic_control"; - - /** Holds the routing key for the queue to receive reports on. */ - public static final String RESPONSE_QUEUE = "response"; - - /** Holds the JMS Topic to send test messages on. */ - private final Topic _topic; - - /** Holds the JMS Queue to receive reports on. */ - private final Queue _response; - - /** Holds the number of messages to send in each test run. */ - private int numMessages; - - /** A monitor used to wait for all reports to arrive back from consumers on. */ - private CountDownLatch allReportsReceivedEvt; - - /** Holds the connection to listen on. */ - private Connection _connection; - - /** Holds the channel for all test messages.*/ - private Session _session; - - /** Holds the producer to send test messages on. */ - private MessageProducer publisher; - - /** - * Creates a topic publisher that will send the specifed number of messages and expect the specifed number of report back from test - * subscribers. - * - * @param connectionUri The broker URL. - * @param numMessages The number of messages to send in each test. - * @param numSubscribers The number of subscribes that are expected to reply with a report. - */ - Publisher(String connectionUri, int numMessages, int numSubscribers) - throws AMQException, JMSException, URLSyntaxException - { - log.debug("Publisher(String connectionUri = " + connectionUri + ", int numMessages = " + numMessages - + ", int numSubscribers = " + numSubscribers + "): called"); - - // Create a connection to the broker. - _connection = new AMQConnection(connectionUri); - - // Establish a session on the broker. - _session = _connection.createSession(false, Session.AUTO_ACKNOWLEDGE); - - // Set up the destinations to send test messages and listen for reports on. - _topic = _session.createTopic(CONTROL_TOPIC); - _response = _session.createQueue(RESPONSE_QUEUE); - - // Set this listener up to listen for reports on the response queue. - _session.createConsumer(_response).setMessageListener(this); - - // Set up this listener with a producer to send the test messages and report requests on. - publisher = _session.createProducer(_topic); - - // Keep the test parameters. - this.numMessages = numMessages; - - // Set up a countdown to count all subscribers sending their reports. - allReportsReceivedEvt = new CountDownLatch(numSubscribers); - - _connection.start(); - System.out.println("Sending messages and waiting for reports..."); - } - - /** - * Start a test publisher. The broker URL must be specified as the first command line argument. - * - * @param argv The command line arguments, ignored. - * - * @todo Add command line arguments to configure all aspects of the test. - */ - public static void main(String[] argv) - { - try - { - // Create an instance of this publisher with the command line parameters. - Publisher publisher = new Publisher(DEFAULT_URI, 1, 1); - - // Publish the test messages. - publisher.doTest(); - } - catch (Exception e) - { - e.printStackTrace(); - } - } - - /** - * Sends the test messages and waits for all subscribers to reply with a report. - * - * @throws JMSException Any underlying JMSException is allowed to fall through. - */ - public void doTest() throws JMSException - { - log.debug("public void DoTest(): called"); - - // Create a test message to send. - Message testMessage = _session.createTextMessage("test"); - - // Send the desired number of test messages. - for (int i = 0; i < numMessages; i++) - { - publisher.send(testMessage); - } - - log.debug("Sent " + numMessages + " test messages."); - - // Send the report request. - Message reportRequestMessage = _session.createTextMessage("Report request message."); - reportRequestMessage.setStringProperty("TYPE", "REPORT_REQUEST"); - - reportRequestMessage.setBooleanProperty("BOOLEAN", false); - //reportRequestMessage.Headers.SetByte("BYTE", 5); - reportRequestMessage.setDoubleProperty("DOUBLE", 3.141); - reportRequestMessage.setFloatProperty("FLOAT", 1.0f); - reportRequestMessage.setIntProperty("INT", 1); - reportRequestMessage.setLongProperty("LONG", 1); - reportRequestMessage.setStringProperty("STRING", "hello"); - reportRequestMessage.setShortProperty("SHORT", (short) 2); - - publisher.send(reportRequestMessage); - - log.debug("Sent the report request message, waiting for all replies..."); - - // Wait until all the reports come in. - try - { - allReportsReceivedEvt.await(TIMEOUT, TimeUnit.MILLISECONDS); - } - catch (InterruptedException e) - { } - - // Check if all reports were really received or if the timeout occurred. - if (allReportsReceivedEvt.getCount() == 0) - { - log.debug("Got all reports."); - } - else - { - log.debug("Waiting for reports timed out, still waiting for " + allReportsReceivedEvt.getCount() + "."); - } - - // Send the termination request. - Message terminationRequestMessage = _session.createTextMessage("Termination request message."); - terminationRequestMessage.setStringProperty("TYPE", "TERMINATION_REQUEST"); - publisher.send(terminationRequestMessage); - - log.debug("Sent the termination request message."); - - // Close all message producers and consumers and the connection to the broker. - shutdown(); - } - - /** - * Handles all report messages from subscribers. This decrements the count of subscribers that are still to reply, until this becomes - * zero, at which time waiting threads are notified of this event. - * - * @param message The received report message. - */ - public void onMessage(Message message) - { - log.debug("public void OnMessage(Message message = " + message + "): called"); - - // Decrement the count of expected messages and release the wait monitor when this becomes zero. - allReportsReceivedEvt.countDown(); - - if (allReportsReceivedEvt.getCount() == 0) - { - log.debug("Got reports from all subscribers."); - } - } - - /** - * Stops the message consumers and closes the connection. - * - * @throws JMSException Any underlying JMSException is allowed to fall through. - */ - private void shutdown() throws JMSException - { - _session.close(); - _connection.close(); - } -} diff --git a/java/integrationtests/src/main/java/org/apache/qpid/interop/testcases/CircuitTestCase.java b/java/integrationtests/src/main/java/org/apache/qpid/interop/testcases/CircuitTestCase.java new file mode 100644 index 0000000000..966a545e16 --- /dev/null +++ b/java/integrationtests/src/main/java/org/apache/qpid/interop/testcases/CircuitTestCase.java @@ -0,0 +1,101 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +package org.apache.qpid.interop.testcases; + +import org.apache.log4j.Logger; + +import org.apache.qpid.test.framework.sequencers.TestCaseSequencer; +import org.apache.qpid.test.framework.Circuit; +import org.apache.qpid.test.framework.FrameworkBaseCase; +import org.apache.qpid.test.framework.MessagingTestConfigProperties; + +import uk.co.thebadgerset.junit.extensions.util.ParsedProperties; +import uk.co.thebadgerset.junit.extensions.util.TestContextProperties; + +/** + * CircuitTestCase runs a test over a {@link Circuit} controlled by the test parameters. + * + *

+ *
CRC Card
Responsibilities Collaborations + *
+ *
+ * + * @todo When working with test context properties, add overrides to defaults to the singleton instance, but when taking + * a starting point to add specific test case parameters to, take a copy. Use the copy with test case specifics + * to control the test. + */ +public class CircuitTestCase extends FrameworkBaseCase +{ + /** Used for debugging. */ + private static final Logger log = Logger.getLogger(CircuitTestCase.class); + + /** + * Creates a new test case with the specified name. + * + * @param name The test case name. + */ + public CircuitTestCase(String name) + { + super(name); + } + + /** + * Performs the a basic P2P test case. + * + * @throws Exception Any exceptions are allowed to fall through and fail the test. + */ + public void testBasicP2P() throws Exception + { + log.debug("public void testBasicP2P(): called"); + + // Get the test parameters, any overrides on the command line will have been applied. + ParsedProperties testProps = TestContextProperties.getInstance(MessagingTestConfigProperties.defaults); + + // Customize the test parameters. + testProps.setProperty("TEST_NAME", "DEFAULT_CIRCUIT_TEST"); + testProps.setProperty(MessagingTestConfigProperties.SEND_DESTINATION_NAME_ROOT_PROPNAME, "testqueue"); + + // Get the test sequencer to create test circuits and run the standard test procedure through. + TestCaseSequencer sequencer = getTestSequencer(); + + // Send the test messages, and check that there were no errors doing so. + Circuit testCircuit = sequencer.createCircuit(testProps); + sequencer.sequenceTest(testCircuit, assertionList(testCircuit.getPublisher().noExceptionsAssertion()), testProps); + + // Check that all of the message were sent. + // Check that the receiving end got the same number of messages as the publishing end. + } + + /** + * Should provide a translation from the junit method name of a test to its test case name as known to the test + * clients that will run the test. The purpose of this is to convert the JUnit method name into the correct test + * case name to place into the test invite. For example the method "testP2P" might map onto the interop test case + * name "TC2_BasicP2P". + * + * @param methodName The name of the JUnit test method. + * + * @return The name of the corresponding interop test case. + */ + public String getTestCaseNameForTestMethod(String methodName) + { + return "DEFAULT_CIRCUIT_TEST"; + } +} diff --git a/java/integrationtests/src/main/java/org/apache/qpid/interop/testcases/InteropTestCase1DummyRun.java b/java/integrationtests/src/main/java/org/apache/qpid/interop/testcases/InteropTestCase1DummyRun.java new file mode 100644 index 0000000000..73e08b578e --- /dev/null +++ b/java/integrationtests/src/main/java/org/apache/qpid/interop/testcases/InteropTestCase1DummyRun.java @@ -0,0 +1,84 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +package org.apache.qpid.interop.testcases; + +import org.apache.log4j.Logger; + +import org.apache.qpid.test.framework.distributedtesting.DistributedTestCase; + +import java.util.Properties; + +/** + * Coordinates test case 1, from the interop test specification. This test connects up the sender and receivers roles, + * and gets some dummy test reports from them, in order to check that the test framework itself is operational. + * + *

+ *
CRC Card
Responsibilities Collaborations + *
Exercises the interop testing framework without actually sending any test messages. + * {@link org.apache.qpid.test.framework.distributedtesting.DistributedTestCase} + *
+ */ +public class InteropTestCase1DummyRun extends DistributedTestCase +{ + /** Used for debugging. */ + private static final Logger log = Logger.getLogger(InteropTestCase1DummyRun.class); + + /** + * Creates a new coordinating test case with the specified name. + * + * @param name The test case name. + */ + public InteropTestCase1DummyRun(String name) + { + super(name); + } + + /** + * Performs the basic P2P test case, "Test Case 2" in the specification. + * + * @throws Exception Any exceptions are allowed to fall through and fail the test. + */ + public void testDummyRun() throws Exception + { + log.debug("public void testDummyRun(): called"); + + Properties testConfig = new Properties(); + testConfig.put("TEST_NAME", "TC1_DummyRun"); + + /*Message[] reports =*/ getTestSequencer().sequenceTest(null, null, testConfig); + + // Compare sender and receivers reports. + // Assert.assertEquals("Expected to get 2 dummy reports.", 2, reports.length); + } + + /** + * Should provide a translation from the junit method name of a test to its test case name as defined in the + * interop testing specification. For example the method "testP2P" might map onto the interop test case name + * "TC2_BasicP2P". + * + * @param methodName The name of the JUnit test method. + * @return The name of the corresponding interop test case. + */ + public String getTestCaseNameForTestMethod(String methodName) + { + return "TC1_DummyRun"; + } +} diff --git a/java/integrationtests/src/main/java/org/apache/qpid/interop/testcases/InteropTestCase2BasicP2P.java b/java/integrationtests/src/main/java/org/apache/qpid/interop/testcases/InteropTestCase2BasicP2P.java new file mode 100644 index 0000000000..f77bbf032f --- /dev/null +++ b/java/integrationtests/src/main/java/org/apache/qpid/interop/testcases/InteropTestCase2BasicP2P.java @@ -0,0 +1,90 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +package org.apache.qpid.interop.testcases; + +import org.apache.log4j.Logger; + +import org.apache.qpid.test.framework.distributedtesting.DistributedTestCase; + +import java.util.Properties; + +/** + * Implements test case 2, from the interop test specification. This test sets up the TC2_BasicP2P test for 50 + * messages. It checks that the sender and receivers reports both indicate that all the test messages were transmitted + * successfully. + * + *

+ *
CRC Card
Responsibilities Collaborations + *
Setup p2p test parameters and compare with test output. {@link DistributedTestCase} + *
+ */ +public class InteropTestCase2BasicP2P extends DistributedTestCase +{ + /** Used for debugging. */ + private static final Logger log = Logger.getLogger(InteropTestCase2BasicP2P.class); + + /** + * Creates a new coordinating test case with the specified name. + * + * @param name The test case name. + */ + public InteropTestCase2BasicP2P(String name) + { + super(name); + } + + /** + * Performs the basic P2P test case, "Test Case 2" in the specification. + * + * @throws Exception Any exceptions are allowed to fall through and fail the test. + */ + public void testBasicP2P() throws Exception + { + log.debug("public void testBasicP2P(): called"); + + Properties testConfig = new Properties(); + testConfig.setProperty("TEST_NAME", "TC2_BasicP2P"); + testConfig.setProperty("P2P_QUEUE_AND_KEY_NAME", "tc2queue"); + testConfig.put("P2P_NUM_MESSAGES", 50); + + /*Message[] reports =*/ getTestSequencer().sequenceTest(null, null, testConfig); + + // Compare sender and receivers reports. + /*int messagesSent = reports[0].getIntProperty("MESSAGE_COUNT"); + int messagesReceived = reports[1].getIntProperty("MESSAGE_COUNT"); + + Assert.assertEquals("The requested number of messages were not sent.", 50, messagesSent); + Assert.assertEquals("Sender and receivers messages sent did not match up.", messagesSent, messagesReceived);*/ + } + + /** + * Should provide a translation from the junit method name of a test to its test case name as defined in the + * interop testing specification. For example the method "testP2P" might map onto the interop test case name + * "TC2_BasicP2P". + * + * @param methodName The name of the JUnit test method. + * @return The name of the corresponding interop test case. + */ + public String getTestCaseNameForTestMethod(String methodName) + { + return "TC2_BasicP2P"; + } +} diff --git a/java/integrationtests/src/main/java/org/apache/qpid/interop/testcases/InteropTestCase3BasicPubSub.java b/java/integrationtests/src/main/java/org/apache/qpid/interop/testcases/InteropTestCase3BasicPubSub.java new file mode 100644 index 0000000000..ad27ca63bd --- /dev/null +++ b/java/integrationtests/src/main/java/org/apache/qpid/interop/testcases/InteropTestCase3BasicPubSub.java @@ -0,0 +1,88 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +package org.apache.qpid.interop.testcases; + +import org.apache.log4j.Logger; + +import org.apache.qpid.test.framework.distributedtesting.DistributedTestCase; + +import java.util.Properties; + +/** + *

+ *
CRC Card
Responsibilities Collaborations + *
Setup pub/sub test parameters and compare with test output. {@link DistributedTestCase} + *
+ */ +public class InteropTestCase3BasicPubSub extends DistributedTestCase +{ + /** Used for debugging. */ + private static final Logger log = Logger.getLogger(InteropTestCase3BasicPubSub.class); + + /** + * Creates a new coordinating test case with the specified name. + * + * @param name The test case name. + */ + public InteropTestCase3BasicPubSub(String name) + { + super(name); + } + + /** + * Performs the basic P2P test case, "Test Case 2" in the specification. + * + * @throws Exception Any exceptions are allowed to fall through and fail the test. + */ + public void testBasicPubSub() throws Exception + { + log.debug("public void testBasicPubSub(): called"); + + Properties testConfig = new Properties(); + testConfig.put("TEST_NAME", "TC3_BasicPubSub"); + testConfig.put("PUBSUB_KEY", "tc3route"); + testConfig.put("PUBSUB_NUM_MESSAGES", 10); + testConfig.put("PUBSUB_NUM_RECEIVERS", 5); + + /*Message[] reports =*/ getTestSequencer().sequenceTest(null, null, testConfig); + + // Compare sender and receivers reports. + /*int messagesSent = reports[0].getIntProperty("MESSAGE_COUNT"); + int messagesReceived = reports[1].getIntProperty("MESSAGE_COUNT"); + + Assert.assertEquals("The requested number of messages were not sent.", 10, messagesSent); + Assert.assertEquals("Received messages did not match up to num sent * num receivers.", messagesSent * 5, + messagesReceived);*/ + } + + /** + * Should provide a translation from the junit method name of a test to its test case name as defined in the + * interop testing specification. For example the method "testP2P" might map onto the interop test case name + * "TC2_BasicP2P". + * + * @param methodName The name of the JUnit test method. + * @return The name of the corresponding interop test case. + */ + public String getTestCaseNameForTestMethod(String methodName) + { + return "TC3_BasicPubSub"; + } +} diff --git a/java/integrationtests/src/main/java/org/apache/qpid/interop/testclient/InteropClientTestCase.java b/java/integrationtests/src/main/java/org/apache/qpid/interop/testclient/InteropClientTestCase.java deleted file mode 100644 index 37952d08c8..0000000000 --- a/java/integrationtests/src/main/java/org/apache/qpid/interop/testclient/InteropClientTestCase.java +++ /dev/null @@ -1,104 +0,0 @@ -/* - * - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - * - */ -package org.apache.qpid.interop.testclient; - -import javax.jms.JMSException; -import javax.jms.Message; -import javax.jms.MessageListener; -import javax.jms.Session; - -/** - * InteropClientTestCase provides an interface that classes implementing test cases from the interop testing spec - * (http://cwiki.apache.org/confluence/display/qpid/Interop+Testing+Specification) should implement. Implementations - * must be Java beans, that is, to provide a default constructor and to implement the {@link #getName} method. - * - *

- *
CRC Card
Responsibilities - *
Supply the name of the test case that this implements. - *
Accept/Reject invites based on test parameters. - *
Adapt to assigned roles. - *
Perform test case actions. - *
Generate test reports. - *
- */ -public interface InteropClientTestCase extends MessageListener -{ - /** Defines the possible test case roles that an interop test case can take on. */ - public enum Roles - { - SENDER, RECEIVER; - } - - /** - * Should provide the name of the test case that this class implements. The exact names are defined in the - * interop testing spec. - * - * @return The name of the test case that this implements. - */ - public String getName(); - - /** - * Determines whether the test invite that matched this test case is acceptable. - * - * @param inviteMessage The invitation to accept or reject. - * - * @return true to accept the invitation, false to reject it. - * - * @throws JMSException Any JMSException resulting from reading the message are allowed to fall through. - */ - public boolean acceptInvite(Message inviteMessage) throws JMSException; - - /** - * Assigns the role to be played by this test case. The test parameters are fully specified in the - * assignment message. When this method return the test case will be ready to execute. - * - * @param role The role to be played; sender or receiver. - * @param assignRoleMessage The role assingment message, contains the full test parameters. - * - * @throws JMSException Any JMSException resulting from reading the message are allowed to fall through. - */ - public void assignRole(Roles role, Message assignRoleMessage) throws JMSException; - - /** - * Performs the test case actions. - * return from here when you have finished the test.. this will signal the controller that the test has ended. - * @throws JMSException Any JMSException resulting from reading the message are allowed to fall through. - */ - public void start() throws JMSException; - - /** - * Gives notice of termination of the test case actions. - * - * @throws JMSException Any JMSException resulting from allowed to fall through. - */ - public void terminate() throws JMSException, InterruptedException; - - /** - * Gets a report on the actions performed by the test case in its assigned role. - * - * @param session The session to create the report message in. - * - * @return The report message. - * - * @throws JMSException Any JMSExceptions resulting from creating the report are allowed to fall through. - */ - public Message getReport(Session session) throws JMSException; -} diff --git a/java/integrationtests/src/main/java/org/apache/qpid/interop/testclient/TestClient.java b/java/integrationtests/src/main/java/org/apache/qpid/interop/testclient/TestClient.java deleted file mode 100644 index a904bfa419..0000000000 --- a/java/integrationtests/src/main/java/org/apache/qpid/interop/testclient/TestClient.java +++ /dev/null @@ -1,422 +0,0 @@ -/* - * - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - * - */ -package org.apache.qpid.interop.testclient; - -import org.apache.log4j.Logger; -import org.apache.qpid.interop.testclient.testcases.TestCase1DummyRun; -import org.apache.qpid.interop.testclient.testcases.TestCase2BasicP2P; -import org.apache.qpid.util.CommandLineParser; -import org.apache.qpid.util.PropertiesUtils; - -import javax.jms.Connection; -import javax.jms.ConnectionFactory; -import javax.jms.JMSException; -import javax.jms.Message; -import javax.jms.MessageConsumer; -import javax.jms.MessageListener; -import javax.jms.MessageProducer; -import javax.jms.Session; -import javax.naming.Context; -import javax.naming.InitialContext; -import javax.naming.NamingException; -import java.io.IOException; -import java.util.ArrayList; -import java.util.Collection; -import java.util.Collections; -import java.util.HashMap; -import java.util.Map; -import java.util.Properties; - -/** - * Implements a test client as described in the interop testing spec - * (http://cwiki.apache.org/confluence/display/qpid/Interop+Testing+Specification). A test client is an agent that - * reacts to control message sequences send by the test {@link org.apache.qpid.interop.coordinator.Coordinator}. - * - *

- *
Messages Handled by TestClient
Message Action - *
Invite(compulsory) Reply with Enlist. - *
Invite(test case) Reply with Enlist if test case available. - *
AssignRole(test case) Reply with Accept Role if matches an enlisted test. Keep test parameters. - *
Start Send test messages defined by test parameters. Send report on messages sent. - *
Status Request Send report on messages received. - *
- * - *

- *
CRC Card
Responsibilities Collaborations - *
Handle all incoming control messages. {@link InteropClientTestCase} - *
Configure and look up test cases by name. {@link InteropClientTestCase} - *
- */ -public class TestClient implements MessageListener -{ - private static Logger log = Logger.getLogger(TestClient.class); - - public static final String CONNECTION_PROPERTY = "connectionfactory.broker"; - public static final String CONNECTION_NAME = "broker"; - public static final String CLIENT_NAME = "java"; - public static final String DEFAULT_CONNECTION_PROPS_RESOURCE = "org/apache/qpid/interop/connection.properties"; - - /** Holds the URL of the broker to run the tests on. */ - public static String brokerUrl; - - /** Holds the virtual host to run the tests on. If null, then the default virtual host is used. */ - public static String virtualHost; - - /** Holds all the test cases loaded from the classpath. */ - Map testCases = new HashMap(); - - protected InteropClientTestCase currentTestCase; - - protected Connection _connection; - protected MessageProducer producer; - protected Session session; - - protected String clientName = CLIENT_NAME; - - /** - * Creates a new interop test client, listenting to the specified broker and virtual host, with the specified client - * identifying name. - * - * @param brokerUrl The url of the broker to connect to. - * @param virtualHost The virtual host to conect to. - * @param clientName The client name to use. - */ - public TestClient(String brokerUrl, String virtualHost, String clientName) - { - log.debug("public TestClient(String brokerUrl = " + brokerUrl + ", String virtualHost = " + virtualHost - + ", String clientName = " + clientName + "): called"); - - // Retain the connection parameters. - this.brokerUrl = brokerUrl; - this.virtualHost = virtualHost; - this.clientName = clientName; - } - - /** - * The entry point for the interop test coordinator. This client accepts the following command line arguments: - * - *

- *
-b The broker URL. Optional. - *
-h The virtual host. Optional. - *
-n The test client name. Optional. - *
name=value Trailing argument define name/value pairs. Added to system properties. Optional. - *
- * - * @param args The command line arguments. - */ - public static void main(String[] args) - { - // Use the command line parser to evaluate the command line. - CommandLineParser commandLine = - new CommandLineParser( - new String[][] - { - {"b", "The broker URL.", "broker", "false"}, - {"h", "The virtual host to use.", "virtual host", "false"}, - {"n", "The test client name.", "name", "false"} - }); - - // Capture the command line arguments or display errors and correct usage and then exit. - Properties options = null; - - try - { - options = commandLine.parseCommandLine(args); - } - catch (IllegalArgumentException e) - { - System.out.println(commandLine.getErrors()); - System.out.println(commandLine.getUsage()); - System.exit(1); - } - - // Extract the command line options. - String brokerUrl = options.getProperty("b"); - String virtualHost = options.getProperty("h"); - String clientName = options.getProperty("n"); - - // Add all the trailing command line options (name=value pairs) to system properties. Tests may pick up - // overridden values from there. - commandLine.addCommandLineToSysProperties(); - - // Create a test client and start it running. - TestClient client = new TestClient(brokerUrl, virtualHost, (clientName == null) ? CLIENT_NAME : clientName); - - // Use a class path scanner to find all the interop test case implementations. - Collection> testCaseClasses = - new ArrayList>(); - // ClasspathScanner.getMatches(InteropClientTestCase.class, "^TestCase.*", true); - // Hard code the test classes till the classpath scanner is fixed. - Collections.addAll(testCaseClasses, - new Class[]{TestCase1DummyRun.class, TestCase2BasicP2P.class, TestClient.class}); - - try - { - client.start(testCaseClasses); - } - catch (Exception e) - { - log.error("The test client was unable to start.", e); - System.exit(1); - } - } - - /** - * Starts the interop test client running. This causes it to start listening for incoming test invites. - * - * @throws JMSException Any underlying JMSExceptions are allowed to fall through. @param testCaseClasses - */ - protected void start(Collection> testCaseClasses) throws JMSException - { - log.debug("private void start(): called"); - - // Create all the test case implementations and index them by the test names. - for (Class nextClass : testCaseClasses) - { - try - { - InteropClientTestCase testCase = nextClass.newInstance(); - testCases.put(testCase.getName(), testCase); - } - catch (InstantiationException e) - { - log.warn("Could not instantiate test case class: " + nextClass.getName(), e); - // Ignored. - } - catch (IllegalAccessException e) - { - log.warn("Could not instantiate test case class due to illegal access: " + nextClass.getName(), e); - // Ignored. - } - } - - // Open a connection to communicate with the coordinator on. - _connection = createConnection(DEFAULT_CONNECTION_PROPS_RESOURCE, clientName, brokerUrl, virtualHost); - - session = _connection.createSession(false, Session.AUTO_ACKNOWLEDGE); - - // Set this up to listen for control messages. - MessageConsumer consumer = session.createConsumer(session.createTopic("iop.control." + clientName)); - consumer.setMessageListener(this); - - MessageConsumer consumer2 = session.createConsumer(session.createTopic("iop.control")); - consumer2.setMessageListener(this); - - // Create a producer to send replies with. - producer = session.createProducer(null); - - // Start listening for incoming control messages. - _connection.start(); - } - - - public static Connection createConnection(String connectionPropsResource, String brokerUrl, String virtualHost) - { - return createConnection(connectionPropsResource, "clientID", brokerUrl, virtualHost); - } - - /** - * Establishes a JMS connection using a properties file and qpids built in JNDI implementation. This is a simple - * convenience method for code that does anticipate handling connection failures. All exceptions that indicate that - * the connection has failed, are wrapped as rutime exceptions, preumably handled by a top level failure handler. - * - * @param connectionPropsResource The name of the connection properties file. - * @param clientID - * @param brokerUrl The broker url to connect to, null to use the default from the - * properties. - * @param virtualHost The virtual host to connectio to, null to use the default. - * - * @return A JMS conneciton. - * - * @todo Make username/password configurable. Allow multiple urls for fail over. Once it feels right, move it to a - * Utils library class. - */ - public static Connection createConnection(String connectionPropsResource, String clientID, String brokerUrl, String virtualHost) - { - log.debug("public static Connection createConnection(String connectionPropsResource = " + connectionPropsResource - + ", String brokerUrl = " + brokerUrl + ", String clientID = " + clientID - + ", String virtualHost = " + virtualHost + " ): called"); - - try - { - Properties connectionProps = - PropertiesUtils.getProperties(TestClient.class.getClassLoader().getResourceAsStream( - connectionPropsResource)); - - if (brokerUrl != null) - { - String connectionString = - "amqp://guest:guest@" + clientID + "/" + ((virtualHost != null) ? virtualHost : "") + "?brokerlist='" + brokerUrl + "'"; - connectionProps.setProperty(CONNECTION_PROPERTY, connectionString); - } - - Context ctx = new InitialContext(connectionProps); - - ConnectionFactory cf = (ConnectionFactory) ctx.lookup(CONNECTION_NAME); - Connection connection = cf.createConnection(); - - return connection; - } - catch (IOException e) - { - throw new RuntimeException(e); - } - catch (NamingException e) - { - throw new RuntimeException(e); - } - catch (JMSException e) - { - throw new RuntimeException(e); - } - } - - /** - * Handles all incoming control messages. - * - * @param message The incoming message. - */ - public void onMessage(Message message) - { - log.debug("public void onMessage(Message message = " + message + "): called"); - - try - { - String controlType = message.getStringProperty("CONTROL_TYPE"); - String testName = message.getStringProperty("TEST_NAME"); - - log.info("onMessage(Message message = " + message + "): for '" + controlType + "' to '" + testName + "'"); - - // Check if the message is a test invite. - if ("INVITE".equals(controlType)) - { - // Flag used to indicate that an enlist should be sent. Only enlist to compulsory invites or invites - // for which test cases exist. - boolean enlist = false; - - if (testName != null) - { - log.debug("Got an invite to test: " + testName); - - // Check if the requested test case is available. - InteropClientTestCase testCase = testCases.get(testName); - - if (testCase != null) - { - // Make the requested test case the current test case. - currentTestCase = testCase; - enlist = true; - } - else - { - log.warn("'" + testName + "' not part of this clients tests."); - } - } - else - { - log.debug("Got a compulsory invite."); - - enlist = true; - } - - if (enlist) - { - // Reply with the client name in an Enlist message. - Message enlistMessage = session.createMessage(); - enlistMessage.setStringProperty("CONTROL_TYPE", "ENLIST"); - enlistMessage.setStringProperty("CLIENT_NAME", clientName); - enlistMessage.setStringProperty("CLIENT_PRIVATE_CONTROL_KEY", "iop.control." + clientName); - enlistMessage.setJMSCorrelationID(message.getJMSCorrelationID()); - - log.info("Sending Message '" + enlistMessage + "'. to " + message.getJMSReplyTo()); - - producer.send(message.getJMSReplyTo(), enlistMessage); - } - } - else if ("ASSIGN_ROLE".equals(controlType)) - { - // Assign the role to the current test case. - String roleName = message.getStringProperty("ROLE"); - - log.debug("Got a role assignment to role: " + roleName); - - InteropClientTestCase.Roles role = Enum.valueOf(InteropClientTestCase.Roles.class, roleName); - - currentTestCase.assignRole(role, message); - - // Reply by accepting the role in an Accept Role message. - Message acceptRoleMessage = session.createMessage(); - acceptRoleMessage.setStringProperty("CONTROL_TYPE", "ACCEPT_ROLE"); - acceptRoleMessage.setJMSCorrelationID(message.getJMSCorrelationID()); - - producer.send(message.getJMSReplyTo(), acceptRoleMessage); - } - else if ("START".equals(controlType) || "STATUS_REQUEST".equals(controlType)) - { - if ("START".equals(controlType)) - { - log.debug("Got a start notification."); - - // Start the current test case. - currentTestCase.start(); - } - else - { - log.debug("Got a status request."); - } - - // Generate the report from the test case and reply with it as a Report message. - Message reportMessage = currentTestCase.getReport(session); - reportMessage.setStringProperty("CONTROL_TYPE", "REPORT"); - reportMessage.setJMSCorrelationID(message.getJMSCorrelationID()); - - producer.send(message.getJMSReplyTo(), reportMessage); - } - else if ("TERMINATE".equals(controlType)) - { - log.info("Received termination instruction from coordinator."); - -// try -// { -// currentTestCase.terminate(); -// } -// catch (InterruptedException e) -// { -// // -// } - // Is a cleaner shutdown needed? - _connection.close(); - System.exit(0); - } - else - { - // Log a warning about this but otherwise ignore it. - log.warn("Got an unknown control message, controlType = " + controlType + ", message = " + message); - } - } - catch (JMSException e) - { - // Log a warning about this, but otherwise ignore it. - log.warn("A JMSException occurred whilst handling a message."); - log.debug("Got JMSException whilst handling message: " + message, e); - } - } -} diff --git a/java/integrationtests/src/main/java/org/apache/qpid/interop/testclient/testcases/TestCase1DummyRun.java b/java/integrationtests/src/main/java/org/apache/qpid/interop/testclient/testcases/TestCase1DummyRun.java deleted file mode 100644 index 5f257c0b36..0000000000 --- a/java/integrationtests/src/main/java/org/apache/qpid/interop/testclient/testcases/TestCase1DummyRun.java +++ /dev/null @@ -1,96 +0,0 @@ -/* - * - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - * - */ -package org.apache.qpid.interop.testclient.testcases; - -import org.apache.log4j.Logger; - -import org.apache.qpid.interop.testclient.InteropClientTestCase; - -import javax.jms.JMSException; -import javax.jms.Message; -import javax.jms.Session; - -/** - * Implements tet case 1, dummy run. This test case sends no test messages, it exists to confirm that the test harness - * is interacting with the coordinator correctly. - * - *

- *
CRC Card
Responsibilities Collaborations - *
Supply the name of the test case that this implements. - *
Accept/Reject invites based on test parameters. - *
Adapt to assigned roles. - *
Perform test case actions. - *
Generate test reports. - *
- */ -public class TestCase1DummyRun implements InteropClientTestCase -{ - private static final Logger log = Logger.getLogger(TestCase1DummyRun.class); - - public String getName() - { - log.debug("public String getName(): called"); - - return "TC1_DummyRun"; - } - - public boolean acceptInvite(Message inviteMessage) throws JMSException - { - log.debug("public boolean acceptInvite(Message inviteMessage): called"); - - // Test parameters don't matter, accept all invites. - return true; - } - - public void assignRole(Roles role, Message assignRoleMessage) throws JMSException - { - log.debug("public void assignRole(Roles role, Message assignRoleMessage): called"); - - // Do nothing, both roles are the same. - } - - public void start() - { - log.debug("public void start(): called"); - - // Do nothing. - } - - public void terminate() throws JMSException - { - //todo - } - - public Message getReport(Session session) throws JMSException - { - log.debug("public Message getReport(Session session): called"); - - // Generate a dummy report, the coordinator expects a report but doesn't care what it is. - return session.createTextMessage("Dummy Run, Ok."); - } - - public void onMessage(Message message) - { - log.debug("public void onMessage(Message message = " + message + "): called"); - - // Ignore any messages. - } -} diff --git a/java/integrationtests/src/main/java/org/apache/qpid/interop/testclient/testcases/TestCase2BasicP2P.java b/java/integrationtests/src/main/java/org/apache/qpid/interop/testclient/testcases/TestCase2BasicP2P.java deleted file mode 100644 index ff56ee9b93..0000000000 --- a/java/integrationtests/src/main/java/org/apache/qpid/interop/testclient/testcases/TestCase2BasicP2P.java +++ /dev/null @@ -1,214 +0,0 @@ -/* - * - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - * - */ -package org.apache.qpid.interop.testclient.testcases; - -import javax.jms.*; - -import org.apache.log4j.Logger; - -import org.apache.qpid.interop.testclient.InteropClientTestCase; -import org.apache.qpid.interop.testclient.TestClient; - -/** - * Implements test case 2, basic P2P. Sends/received a specified number of messages to a specified route on the - * default direct exchange. Produces reports on the actual number of messages sent/received. - * - *

- *
CRC Card
Responsibilities Collaborations - *
Supply the name of the test case that this implements. - *
Accept/Reject invites based on test parameters. - *
Adapt to assigned roles. - *
Send required number of test messages. - *
Generate test reports. - *
- */ -public class TestCase2BasicP2P implements InteropClientTestCase -{ - /** Used for debugging. */ - private static final Logger log = Logger.getLogger(TestCase2BasicP2P.class); - - /** Holds the count of test messages received. */ - private int messageCount; - - /** The role to be played by the test. */ - private Roles role; - - /** The number of test messages to send. */ - private int numMessages; - - /** The routing key to send them to on the default direct exchange. */ - private Destination sendDestination; - - /** The connection to send the test messages on. */ - private Connection connection; - - /** The session to send the test messages on. */ - private Session session; - - /** The producer to send the test messages with. */ - MessageProducer producer; - - /** - * Should provide the name of the test case that this class implements. The exact names are defined in the - * interop testing spec. - * - * @return The name of the test case that this implements. - */ - public String getName() - { - log.debug("public String getName(): called"); - - return "TC2_BasicP2P"; - } - - /** - * Determines whether the test invite that matched this test case is acceptable. - * - * @param inviteMessage The invitation to accept or reject. - * - * @return true to accept the invitation, false to reject it. - * - * @throws JMSException Any JMSException resulting from reading the message are allowed to fall through. - */ - public boolean acceptInvite(Message inviteMessage) throws JMSException - { - log.debug("public boolean acceptInvite(Message inviteMessage = " + inviteMessage + "): called"); - - // All invites are acceptable. - return true; - } - - /** - * Assigns the role to be played by this test case. The test parameters are fully specified in the - * assignment message. When this method return the test case will be ready to execute. - * - * @param role The role to be played; sender or receiver. - * - * @param assignRoleMessage The role assingment message, contains the full test parameters. - * - * @throws JMSException Any JMSException resulting from reading the message are allowed to fall through. - */ - public void assignRole(Roles role, Message assignRoleMessage) throws JMSException - { - log.debug("public void assignRole(Roles role = " + role + ", Message assignRoleMessage = " + assignRoleMessage - + "): called"); - - // Reset the message count for a new test. - messageCount = 0; - - // Take note of the role to be played. - this.role = role; - - // Create a new connection to pass the test messages on. - connection = - TestClient.createConnection(TestClient.DEFAULT_CONNECTION_PROPS_RESOURCE, TestClient.brokerUrl, - TestClient.virtualHost); - session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE); - - // Extract and retain the test parameters. - numMessages = assignRoleMessage.getIntProperty("P2P_NUM_MESSAGES"); - sendDestination = session.createQueue(assignRoleMessage.getStringProperty("P2P_QUEUE_AND_KEY_NAME")); - - log.debug("numMessages = " + numMessages); - log.debug("sendDestination = " + sendDestination); - log.debug("role = " + role); - - switch (role) - { - // Check if the sender role is being assigned, and set up a message producer if so. - case SENDER: - producer = session.createProducer(sendDestination); - break; - - // Otherwise the receiver role is being assigned, so set this up to listen for messages. - case RECEIVER: - MessageConsumer consumer = session.createConsumer(sendDestination); - consumer.setMessageListener(this); - break; - } - - connection.start(); - } - - /** - * Performs the test case actions. - */ - public void start() throws JMSException - { - log.debug("public void start(): called"); - - // Check that the sender role is being performed. - if (role.equals(Roles.SENDER)) - { - Message testMessage = session.createTextMessage("test"); - - for (int i = 0; i < numMessages; i++) - { - producer.send(testMessage); - - // Increment the message count. - messageCount++; - } - } - } - - public void terminate() throws JMSException - { - //todo - } - - /** - * Gets a report on the actions performed by the test case in its assigned role. - * - * @param session The session to create the report message in. - * - * @return The report message. - * - * @throws JMSException Any JMSExceptions resulting from creating the report are allowed to fall through. - */ - public Message getReport(Session session) throws JMSException - { - log.debug("public Message getReport(Session session): called"); - - // Close the test connection. - connection.close(); - - // Generate a report message containing the count of the number of messages passed. - Message report = session.createMessage(); - report.setStringProperty("CONTROL_TYPE", "REPORT"); - report.setIntProperty("MESSAGE_COUNT", messageCount); - - return report; - } - - /** - * Counts incoming test messages. - * - * @param message The incoming test message. - */ - public void onMessage(Message message) - { - log.debug("public void onMessage(Message message = " + message + "): called"); - - // Increment the message count. - messageCount++; - } -} diff --git a/java/integrationtests/src/main/java/org/apache/qpid/interop/testclient/testcases/TestCase3BasicPubSub.java b/java/integrationtests/src/main/java/org/apache/qpid/interop/testclient/testcases/TestCase3BasicPubSub.java deleted file mode 100644 index 7b35142c82..0000000000 --- a/java/integrationtests/src/main/java/org/apache/qpid/interop/testclient/testcases/TestCase3BasicPubSub.java +++ /dev/null @@ -1,249 +0,0 @@ -/* - * - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - * - */ - -package org.apache.qpid.interop.testclient.testcases; - -import javax.jms.*; - -import org.apache.log4j.Logger; - -import org.apache.qpid.interop.testclient.InteropClientTestCase; - -/** - * Implements test case 3, basic pub/sub. Sends/received a specified number of messages to a specified route on the - * default topic exchange, using the specified number of receiver connections. Produces reports on the actual number of - * messages sent/received. - * - *

- *
CRC Card
Responsibilities Collaborations - *
Supply the name of the test case that this implements. - *
Accept/Reject invites based on test parameters. - *
Adapt to assigned roles. - *
Send required number of test messages using pub/sub. - *
Generate test reports. - *
- */ -public class TestCase3BasicPubSub implements InteropClientTestCase -{ - /** Used for debugging. */ - private static final Logger log = Logger.getLogger(TestCase3BasicPubSub.class); - - /** Holds the count of test messages received. */ - private int messageCount; - - /** The role to be played by the test. */ - private Roles role; - - /** The number of test messages to send. */ - private int numMessages; - - /** The number of receiver connection to use. */ - private int numReceivers; - - /** The routing key to send them to on the default direct exchange. */ - private Destination sendDestination; - - /** The connections to send/receive the test messages on. */ - private Connection[] connection; - - /** The sessions to send/receive the test messages on. */ - private Session[] session; - - /** The producer to send the test messages with. */ - MessageProducer producer; - - /** - * Should provide the name of the test case that this class implements. The exact names are defined in the - * interop testing spec. - * - * @return The name of the test case that this implements. - */ - public String getName() - { - log.debug("public String getName(): called"); - - return "TC3_BasicPubSub"; - } - - /** - * Determines whether the test invite that matched this test case is acceptable. - * - * @param inviteMessage The invitation to accept or reject. - * - * @return true to accept the invitation, false to reject it. - * - * @throws javax.jms.JMSException Any JMSException resulting from reading the message are allowed to fall through. - */ - public boolean acceptInvite(Message inviteMessage) throws JMSException - { - log.debug("public boolean acceptInvite(Message inviteMessage = " + inviteMessage + "): called"); - - // All invites are acceptable. - return true; - } - - /** - * Assigns the role to be played by this test case. The test parameters are fully specified in the - * assignment message. When this method return the test case will be ready to execute. - * - * @param role The role to be played; sender or receiver. - * - * @param assignRoleMessage The role assingment message, contains the full test parameters. - * - * @throws JMSException Any JMSException resulting from reading the message are allowed to fall through. - */ - public void assignRole(Roles role, Message assignRoleMessage) throws JMSException - { - log.debug("public void assignRole(Roles role = " + role + ", Message assignRoleMessage = " + assignRoleMessage - + "): called"); - - // Reset the message count for a new test. - messageCount = 0; - - // Take note of the role to be played. - this.role = role; - - // Extract and retain the test parameters. - numMessages = assignRoleMessage.getIntProperty("PUBSUB_NUM_MESSAGES"); - numReceivers = assignRoleMessage.getIntProperty("PUBSUB_NUM_RECEIVERS"); - String sendKey = assignRoleMessage.getStringProperty("PUBSUB_KEY"); - - log.debug("numMessages = " + numMessages); - log.debug("numReceivers = " + numReceivers); - log.debug("sendKey = " + sendKey); - log.debug("role = " + role); - - switch (role) - { - // Check if the sender role is being assigned, and set up a single message producer if so. - case SENDER: - // Create a new connection to pass the test messages on. - connection = new Connection[1]; - session = new Session[1]; - - connection[0] = - org.apache.qpid.interop.testclient.TestClient.createConnection(org.apache.qpid.interop.testclient.TestClient.DEFAULT_CONNECTION_PROPS_RESOURCE, org.apache.qpid.interop.testclient.TestClient.brokerUrl, - org.apache.qpid.interop.testclient.TestClient.virtualHost); - session[0] = connection[0].createSession(false, Session.AUTO_ACKNOWLEDGE); - - // Extract and retain the test parameters. - sendDestination = session[0].createTopic(sendKey); - - producer = session[0].createProducer(sendDestination); - break; - - // Otherwise the receiver role is being assigned, so set this up to listen for messages on the required number - // of receiver connections. - case RECEIVER: - // Create the required number of receiver connections. - connection = new Connection[numReceivers]; - session = new Session[numReceivers]; - - for (int i = 0; i < numReceivers; i++) - { - connection[i] = - org.apache.qpid.interop.testclient.TestClient.createConnection(org.apache.qpid.interop.testclient.TestClient.DEFAULT_CONNECTION_PROPS_RESOURCE, org.apache.qpid.interop.testclient.TestClient.brokerUrl, - org.apache.qpid.interop.testclient.TestClient.virtualHost); - session[i] = connection[i].createSession(false, Session.AUTO_ACKNOWLEDGE); - - sendDestination = session[i].createTopic(sendKey); - - MessageConsumer consumer = session[i].createConsumer(sendDestination); - consumer.setMessageListener(this); - } - - break; - } - - // Start all the connection dispatcher threads running. - for (int i = 0; i < connection.length; i++) - { - connection[i].start(); - } - } - - /** - * Performs the test case actions. - */ - public void start() throws JMSException - { - log.debug("public void start(): called"); - - // Check that the sender role is being performed. - if (role.equals(Roles.SENDER)) - { - Message testMessage = session[0].createTextMessage("test"); - - for (int i = 0; i < numMessages; i++) - { - producer.send(testMessage); - - // Increment the message count. - messageCount++; - } - } - } - - public void terminate() throws JMSException, InterruptedException - { - //todo - } - - /** - * Gets a report on the actions performed by the test case in its assigned role. - * - * @param session The session to create the report message in. - * - * @return The report message. - * - * @throws JMSException Any JMSExceptions resulting from creating the report are allowed to fall through. - */ - public Message getReport(Session session) throws JMSException - { - log.debug("public Message getReport(Session session): called"); - - // Close the test connections. - for (int i = 0; i < connection.length; i++) - { - connection[i].close(); - } - - // Generate a report message containing the count of the number of messages passed. - Message report = session.createMessage(); - report.setStringProperty("CONTROL_TYPE", "REPORT"); - report.setIntProperty("MESSAGE_COUNT", messageCount); - - return report; - } - - /** - * Counts incoming test messages. - * - * @param message The incoming test message. - */ - public void onMessage(Message message) - { - log.debug("public void onMessage(Message message = " + message + "): called"); - - // Increment the message count. - messageCount++; - } -} diff --git a/java/integrationtests/src/main/java/org/apache/qpid/sustained/SustainedClientTestCase.java b/java/integrationtests/src/main/java/org/apache/qpid/sustained/SustainedClientTestCase.java new file mode 100644 index 0000000000..65e05fab4b --- /dev/null +++ b/java/integrationtests/src/main/java/org/apache/qpid/sustained/SustainedClientTestCase.java @@ -0,0 +1,905 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +package org.apache.qpid.sustained; + +import org.apache.log4j.Logger; + +import org.apache.qpid.client.AMQNoConsumersException; +import org.apache.qpid.client.AMQNoRouteException; +import org.apache.qpid.test.framework.distributedtesting.TestClient; +import org.apache.qpid.interop.clienttestcases.TestCase3BasicPubSub; +import org.apache.qpid.test.framework.TestUtils; + +import javax.jms.Connection; +import javax.jms.Destination; +import javax.jms.ExceptionListener; +import javax.jms.JMSException; +import javax.jms.Message; +import javax.jms.MessageConsumer; +import javax.jms.MessageListener; +import javax.jms.MessageProducer; +import javax.jms.Session; +import javax.jms.TextMessage; + +import java.util.HashMap; +import java.util.Iterator; +import java.util.Map; +import java.util.concurrent.CountDownLatch; + +/** + * Implements test case 3, basic pub/sub. Sends/received a specified number of messages to a specified route on the + * default topic exchange, using the specified number of receivers connections. Produces reports on the actual number of + * messages sent/received. + * + *

+ *
CRC Card
Responsibilities Collaborations + *
Supply the name of the test case that this implements. + *
Accept/Reject invites based on test parameters. + *
Adapt to assigned roles. + *
Send required number of test messages using pub/sub.
Generate test reports. + *
+ */ +public class SustainedClientTestCase extends TestCase3BasicPubSub implements ExceptionListener +{ + /** Used for debugging. */ + private static final Logger log = Logger.getLogger(SustainedClientTestCase.class); + + /** Used to log to the console. */ + private static final Logger console = Logger.getLogger("SustainedTest"); + + /** The role to be played by the test. */ + private Roles role; + + /** The number of receivers connection to use. */ + private int numReceivers; + + /** The routing key to send them to on the default direct exchange. */ + private Destination sendDestination; + + /** The routing key to send updates to on the default direct exchange. */ + private Destination sendUpdateDestination; + + /** The connections to send/receive the test messages on. */ + private Connection[] connection; + + /** The sessions to send/receive the test messages on. */ + private Session[] session; + + /** The producer to send the test messages with. */ + MessageProducer producer; + + /** Adapter that adjusts the send rate based on the updates from clients. */ + SustainedRateAdapter _rateAdapter; + + /** */ + int _batchSize; + + private static final long TEN_MILLI_SEC = 10000000; + private static final int DEBUG_LOG_UPATE_INTERVAL = 10; + private static final int LOG_UPATE_INTERVAL = 10; + private static final boolean SLEEP_PER_MESSAGE = Boolean.getBoolean("sleepPerMessage"); + + /** + * Should provide the name of the test case that this class implements. The exact names are defined in the interop + * testing spec. + * + * @return The name of the test case that this implements. + */ + public String getName() + { + log.debug("public String getName(): called"); + + return "Perf_SustainedPubSub"; + } + + /** + * Assigns the role to be played by this test case. The test parameters are fully specified in the assignment + * message. When this method return the test case will be ready to execute. + * + * @param role The role to be played; sender or receivers. + * @param assignRoleMessage The role assingment message, contains the full test parameters. + * + * @throws JMSException Any JMSException resulting from reading the message are allowed to fall through. + */ + public void assignRole(Roles role, Message assignRoleMessage) throws JMSException + { + log.debug("public void assignRole(Roles role = " + role + ", Message assignRoleMessage = " + assignRoleMessage + + "): called"); + + // Take note of the role to be played. + this.role = role; + + // Extract and retain the test parameters. + numReceivers = assignRoleMessage.getIntProperty("SUSTAINED_NUM_RECEIVERS"); + _batchSize = assignRoleMessage.getIntProperty("SUSTAINED_UPDATE_INTERVAL"); + String sendKey = assignRoleMessage.getStringProperty("SUSTAINED_KEY"); + String sendUpdateKey = assignRoleMessage.getStringProperty("SUSTAINED_UPDATE_KEY"); + int ackMode = assignRoleMessage.getIntProperty("ACKNOWLEDGE_MODE"); + String clientName = assignRoleMessage.getStringProperty("CLIENT_NAME"); + + if (log.isDebugEnabled()) + { + log.debug("numReceivers = " + numReceivers); + log.debug("_batchSize = " + _batchSize); + log.debug("ackMode = " + ackMode); + log.debug("sendKey = " + sendKey); + log.debug("sendUpdateKey = " + sendUpdateKey); + log.debug("role = " + role); + } + + switch (role) + { + // Check if the sender role is being assigned, and set up a single message producer if so. + case SENDER: + console.info("Creating Sender"); + // Create a new connection to pass the test messages on. + connection = new Connection[1]; + session = new Session[1]; + + connection[0] = TestUtils.createConnection(TestClient.testContextProperties); + session[0] = connection[0].createSession(false, ackMode); + + // Extract and retain the test parameters. + sendDestination = session[0].createTopic(sendKey); + + connection[0].setExceptionListener(this); + + producer = session[0].createProducer(sendDestination); + + sendUpdateDestination = session[0].createTopic(sendUpdateKey); + MessageConsumer updateConsumer = session[0].createConsumer(sendUpdateDestination); + + _rateAdapter = new SustainedRateAdapter(this); + updateConsumer.setMessageListener(_rateAdapter); + + break; + + // Otherwise the receivers role is being assigned, so set this up to listen for messages on the required number + // of receivers connections. + case RECEIVER: + console.info("Creating Receiver"); + // Create the required number of receivers connections. + connection = new Connection[numReceivers]; + session = new Session[numReceivers]; + + for (int i = 0; i < numReceivers; i++) + { + connection[i] = TestUtils.createConnection(TestClient.testContextProperties); + session[i] = connection[i].createSession(false, ackMode); + + sendDestination = session[i].createTopic(sendKey); + + sendUpdateDestination = session[i].createTopic(sendUpdateKey); + + MessageConsumer consumer = session[i].createConsumer(sendDestination); + + consumer.setMessageListener(new SustainedListener(clientName + "-" + i, _batchSize, session[i], + sendUpdateDestination)); + } + + break; + } + + // Start all the connection dispatcher threads running. + for (int i = 0; i < connection.length; i++) + { + connection[i].start(); + } + } + + /** Performs the test case actions. */ + public void start() throws JMSException + { + log.debug("public void start(): called"); + + // Check that the sender role is being performed. + switch (role) + { + // Check if the sender role is being assigned, and set up a single message producer if so. + case SENDER: + _rateAdapter.run(); + break; + case RECEIVER: + + } + + // return from here when you have finished the test.. this will signal the controller and + } + + public void terminate() throws JMSException, InterruptedException + { + if (_rateAdapter != null) + { + _rateAdapter.stop(); + } + } + + /** + * Gets a report on the actions performed by the test case in its assigned role. + * + * @param session The session to create the report message in. + * + * @return The report message. + * + * @throws JMSException Any JMSExceptions resulting from creating the report are allowed to fall through. + */ + public Message getReport(Session session) throws JMSException + { + log.debug("public Message getReport(Session session): called"); + + // Close the test connections. + for (int i = 0; i < connection.length; i++) + { + connection[i].close(); + } + + Message report = session.createMessage(); + report.setStringProperty("CONTROL_TYPE", "REPORT"); + + return report; + } + + public void onException(JMSException jmsException) + { + Exception linked = jmsException.getLinkedException(); + + if (linked != null) + { + if (log.isDebugEnabled()) + { + log.debug("Linked Exception:" + linked); + } + + if ((linked instanceof AMQNoRouteException) || (linked instanceof AMQNoConsumersException)) + { + if (log.isDebugEnabled()) + { + if (linked instanceof AMQNoConsumersException) + { + log.warn("No clients currently available for message:" + + ((AMQNoConsumersException) linked).getUndeliveredMessage()); + } + else + { + log.warn("No route for message"); + } + } + + // Tell the rate adapter that there are no clients ready yet + _rateAdapter.NO_CLIENTS = true; + } + } + else + { + log.warn("Exception:" + linked); + } + } + + /** + * Inner class that listens for messages and sends a report for the time taken between receiving the 'start' and + * 'end' messages. + */ + class SustainedListener implements MessageListener + { + /** Number of messages received */ + private long _received = 0; + /** The number of messages in the batch */ + private int _batchSize = 0; + /** Record of the when the 'start' messagse was sen */ + private Long _startTime; + /** Message producer to use to send reports */ + MessageProducer _updater; + /** Session to create the report message on */ + Session _session; + /** Record of the client ID used for this SustainedListnener */ + String _client; + + /** + * Main Constructor + * + * @param clientname The _client id used to identify this connection. + * @param batchSize The number of messages that are to be sent per batch. Note: This is not used to + * control the interval between sending reports. + * @param session The session used for communication. + * @param sendDestination The destination that update reports should be sent to. + * + * @throws JMSException My occur if creatingthe Producer fails + */ + public SustainedListener(String clientname, int batchSize, Session session, Destination sendDestination) + throws JMSException + { + _batchSize = batchSize; + _client = clientname; + _session = session; + _updater = session.createProducer(sendDestination); + } + + public void onMessage(Message message) + { + if (log.isTraceEnabled()) + { + log.trace("Message " + _received + "received in listener"); + } + + if (message instanceof TextMessage) + { + try + { + _received++; + if (((TextMessage) message).getText().equals("start")) + { + log.debug("Starting Batch"); + _startTime = System.nanoTime(); + } + else if (((TextMessage) message).getText().equals("end")) + { + if (_startTime != null) + { + long currentTime = System.nanoTime(); + sendStatus(currentTime - _startTime, _received, message.getIntProperty("BATCH")); + log.debug("End Batch"); + } + } + } + catch (JMSException e) + { + // ignore error + } + } + + } + + /** + * sendStatus creates and sends the report back to the publisher + * + * @param time taken for the the last batch + * @param received Total number of messages received. + * @param batchNumber the batch number + * @throws JMSException if an error occurs during the send + */ + private void sendStatus(long time, long received, int batchNumber) throws JMSException + { + Message updateMessage = _session.createTextMessage("update"); + updateMessage.setStringProperty("CLIENT_ID", ":" + _client); + updateMessage.setStringProperty("CONTROL_TYPE", "UPDATE"); + updateMessage.setLongProperty("RECEIVED", received); + updateMessage.setIntProperty("BATCH", batchNumber); + updateMessage.setLongProperty("DURATION", time); + + if (log.isInfoEnabled()) + { + log.info("**** SENDING [" + batchNumber + "]**** " + "CLIENT_ID:" + _client + " RECEIVED:" + received + + " BATCH:" + batchNumber + " DURATION:" + time); + } + + // Output on the main console.info the details of this batch + if ((batchNumber % 10) == 0) + { + console.info("Sending Report [" + batchNumber + "] " + "CLIENT_ID:" + _client + " RECEIVED:" + received + + " BATCH:" + batchNumber + " DURATION:" + time); + } + + _updater.send(updateMessage); + } + } + + /** + * This class is used here to adjust the _delay value which in turn is used to control the number of messages/second + * that are sent through the test system. + * + * By keeping a record of the messages recevied and the average time taken to process the batch size can be + * calculated and so the delay can be adjusted to maintain that rate. + * + * Given that delays of < 10ms can be rounded up the delay is only used between messages if the _delay > 10ms * no + * messages in the batch. Otherwise the delay is used at the end of the batch. + */ + class SustainedRateAdapter implements MessageListener, Runnable + { + private SustainedClientTestCase _client; + private long _batchVariance = Integer.getInteger("batchVariance", 3); // no. batches to allow drifting + private long _timeVariance = TEN_MILLI_SEC * 5; // no. nanos between send and report delay (10ms) + private volatile long _delay; // in nanos + private long _sent; + private Map _slowClients = new HashMap(); + private static final long PAUSE_SLEEP = TEN_MILLI_SEC / 1000; // 10 ms + private static final long NO_CLIENT_SLEEP = 1000; // 1s + private volatile boolean NO_CLIENTS = true; + private int _delayShifting; + private final int REPORTS_WITHOUT_CHANGE = Integer.getInteger("stableReportCount", 5); + private boolean _warmedup = false; + private static final long EXPECTED_TIME_PER_BATCH = 100000L; + private int _warmUpBatches = Integer.getInteger("warmUpBatches", 10); + + SustainedRateAdapter(SustainedClientTestCase client) + { + _client = client; + } + + public void onMessage(Message message) + { + if (log.isDebugEnabled()) + { + log.debug("SustainedRateAdapter onMessage(Message message = " + message + "): called"); + } + + try + { + String controlType = message.getStringProperty("CONTROL_TYPE"); + + // Check if the message is a test invite. + if ("UPDATE".equals(controlType)) + { + NO_CLIENTS = false; + long duration = message.getLongProperty("DURATION"); + long totalReceived = message.getLongProperty("RECEIVED"); + String client = message.getStringProperty("CLIENT_ID"); + int batchNumber = message.getIntProperty("BATCH"); + + if (log.isInfoEnabled() && ((batchNumber % DEBUG_LOG_UPATE_INTERVAL) == 0)) + { + log.info("Update Report: CLIENT_ID:" + client + " RECEIVED:" + totalReceived + " Recevied BATCH:" + + batchNumber + " DURATION:" + duration); + } + + recordSlow(client, totalReceived, batchNumber); + + adjustDelay(client, batchNumber, duration); + + // Warm up completes when: + // we haven't warmed up + // and the number of batches sent to each client is at least half of the required warmup batches + if (!_warmedup && (batchNumber >= _warmUpBatches)) + { + _warmedup = true; + _warmup.countDown(); + + } + } + } + catch (JMSException e) + { + // + } + } + + CountDownLatch _warmup = new CountDownLatch(1); + + int _numBatches = 10000; + + // long[] _timings = new long[_numBatches]; + private boolean _running = true; + + public void run() + { + console.info("Warming up"); + + doBatch(_warmUpBatches); + + try + { + // wait for warmup to complete. + _warmup.await(); + + // set delay to the average length of the batches + _delay = _totalDuration / _warmUpBatches / delays.size(); + + console.info("Warmup complete delay set : " + _delay + " based on _totalDuration: " + _totalDuration + + " over no. batches: " + _warmUpBatches + " with client count: " + delays.size()); + + _totalDuration = 0L; + _totalReceived = 0L; + _sent = 0L; + } + catch (InterruptedException e) + { + // + } + + doBatch(_numBatches); + + } + + private void doBatch(int batchSize) // long[] timings, + { + TextMessage testMessage = null; + try + { + testMessage = _client.session[0].createTextMessage("start"); + + for (int batch = 0; batch <= batchSize; batch++) + // while (_running) + { + long start = System.nanoTime(); + + testMessage.setText("start"); + testMessage.setIntProperty("BATCH", batch); + + _client.producer.send(testMessage); + _rateAdapter.sentMessage(); + + testMessage.setText("test"); + // start at 2 so start and end count as part of batch + for (int m = 2; m < _batchSize; m++) + { + _client.producer.send(testMessage); + _rateAdapter.sentMessage(); + } + + testMessage.setText("end"); + _client.producer.send(testMessage); + _rateAdapter.sentMessage(); + + long end = System.nanoTime(); + + long sendtime = end - start; + + if (log.isDebugEnabled()) + { + log.info("Sent batch[" + batch + "](" + _batchSize + ") in " + sendtime); // timings[batch]); + } + + if ((batch % LOG_UPATE_INTERVAL) == 0) + { + console.info("Sent Batch[" + batch + "](" + _batchSize + ")" + status()); + } + + _rateAdapter.sleepBatch(); + + } + } + catch (JMSException e) + { + console.error("Runner ended"); + } + } + + private String status() + { + return " TotalDuration: " + _totalDuration + " for " + delays.size() + " consumers" + " Delay is " + _delay + + " resulting in " + + ((_delay > (TEN_MILLI_SEC * _batchSize)) ? ((_delay / _batchSize) + "/msg") : (_delay + "/batch")); + } + + private void sleepBatch() + { + if (checkForSlowClients()) + { // if there werwe slow clients we have already slept so don't sleep anymore again. + return; + } + + if (!SLEEP_PER_MESSAGE) + { + // per batch sleep.. if sleep is to small to spread over the batch. + if (_delay <= (TEN_MILLI_SEC * _batchSize)) + { + sleepLong(_delay); + } + else + { + log.info("Not sleeping _delay > ten*batch is:" + _delay); + } + } + } + + public void stop() + { + _running = false; + } + + Map delays = new HashMap(); + Long _totalReceived = 0L; + Long _totalDuration = 0L; + int _skipUpdate = 0; + + /** + * Adjust the delay for sending messages based on this update from the client + * + * @param client The client that send this update + * @param duration The time taken for the last batch of messagse + * @param batchNumber The reported batchnumber from the client + */ + private void adjustDelay(String client, int batchNumber, long duration) + { + // Retrieve the current total time taken for this client. + Long currentTime = delays.get(client); + + // Add the new duration time to this client + if (currentTime == null) + { + currentTime = duration; + } + else + { + currentTime += duration; + } + + delays.put(client, currentTime); + + long batchesSent = _sent / _batchSize; + + // ensure we don't divide by zero + if (batchesSent == 0) + { + batchesSent = 1L; + } + + _totalReceived += _batchSize; + _totalDuration += duration; + + // calculate average duration accross clients per batch + long averageDuration = _totalDuration / delays.size() / batchesSent; + + // calculate the difference between current send delay and average report delay + long diff = (duration) - averageDuration; + + if (log.isInfoEnabled() && ((batchNumber % DEBUG_LOG_UPATE_INTERVAL) == 0)) + { + log.info("TotalDuration:" + _totalDuration + " for " + delays.size() + " consumers." + " on batch: " + + batchesSent + " received batch: " + batchNumber + " Batch Duration: " + duration + " Average: " + + averageDuration + " so diff: " + diff + " for : " + client + " Delay is " + _delay + " resulting in " + + ((_delay > (TEN_MILLI_SEC * _batchSize)) ? ((_delay / _batchSize) + "/msg") : (_delay + "/batch"))); + } + + // if the averageDuration differs from the current by more than the specified variane then adjust delay. + if (Math.abs(diff) > _timeVariance) + { + + // if the the _delay is larger than the required duration to send report + // speed up + if (diff > TEN_MILLI_SEC) + { + _delay -= TEN_MILLI_SEC; + + if (_delay < 0) + { + _delay = 0; + log.info("Reset _delay to 0"); + delayStable(); + } + else + { + delayChanged(); + } + + } + else if (diff < 0) // diff < 0 diff cannot be 0 as it is > _timeVariance + { + // the report took longer + _delay += TEN_MILLI_SEC; + delayChanged(); + } + } + else + { + delayStable(); + } + + // If we have a consumer that is behind with the batches. + if ((batchesSent - batchNumber) > _batchVariance) + { + log.debug("Increasing _delay as sending more than receiving"); + + _delay += 2 * TEN_MILLI_SEC; + delayChanged(); + } + + } + + /** Reset the number of iterations before we say the delay has stabilised. */ + private void delayChanged() + { + _delayShifting = REPORTS_WITHOUT_CHANGE; + } + + /** + * Record the fact that delay has stabilised If delay has stablised for REPORTS_WITHOUT_CHANGE then it will + * output Delay stabilised + */ + private void delayStable() + { + _delayShifting--; + + if (_delayShifting < 0) + { + _delayShifting = 0; + console.debug("Delay stabilised:" + _delay); + } + } + + /** + * Checks that the client has received enough messages. If the client has fallen behind then they are put in the + * _slowClients lists which will increase the delay. + * + * @param client The client identifier to check + * @param received the number of messages received by that client + * @param batchNumber + */ + private void recordSlow(String client, long received, int batchNumber) + { + if (Math.abs(batchNumber - (_sent / _batchSize)) > _batchVariance) + { + _slowClients.put(client, received); + } + else + { + _slowClients.remove(client); + } + } + + /** Incrment the number of sent messages and then sleep, if required. */ + public void sentMessage() + { + + _sent++; + + if (_delay > (TEN_MILLI_SEC * _batchSize)) + { + long batchDelay = _delay / _batchSize; + // less than 10ms sleep doesn't always work. + // _delay is in nano seconds + // if (batchDelay < (TEN_MILLI_SEC)) + // { + // sleep(0, (int) batchDelay); + // } + // else + { + // if (batchDelay < 30000000000L) + { + sleepLong(batchDelay); + } + } + } + else + { + if (SLEEP_PER_MESSAGE && (_delay > 0)) + { + sleepLong(_delay / _batchSize); + } + } + } + + /** + * Check at the end of each batch and pause sending messages to allow slow clients to catch up. + * + * @return true if there were slow clients that caught up. + */ + private boolean checkForSlowClients() + { + // This will allways be true as we are running this at the end of each batchSize + // if (_sent % _batchSize == 0) + { + // Cause test to pause when we have slow + if (!_slowClients.isEmpty() || NO_CLIENTS) + { + + while (!_slowClients.isEmpty()) + { + if (log.isInfoEnabled() && ((_sent / _batchSize % DEBUG_LOG_UPATE_INTERVAL) == 0)) + { + String clients = ""; + Iterator it = _slowClients.keySet().iterator(); + while (it.hasNext()) + { + clients += it.next(); + if (it.hasNext()) + { + clients += ", "; + } + } + + log.info("Pausing for slow clients:" + clients); + } + + if (console.isDebugEnabled() && ((_sent / _batchSize % LOG_UPATE_INTERVAL) == 0)) + { + console.debug(_slowClients.size() + " slow clients."); + } + + sleep(PAUSE_SLEEP); + } + + if (NO_CLIENTS) + { + sleep(NO_CLIENT_SLEEP); + } + + log.debug("Continuing"); + + return true; + } + else + { + if ((_sent / _batchSize % LOG_UPATE_INTERVAL) == 0) + { + console.info("Total Delay :" + _delay + " " + + ((_delayShifting == 0) ? "Stablised" : ("Not Stablised(" + _delayShifting + ")"))); + } + } + + } + + return false; + } + + /** + * Sleep normally takes micro-seconds this allows the use of a nano-second value. + * + * @param delay nanoseconds to sleep for. + */ + private void sleepLong(long delay) + { + sleep(delay / 1000000, (int) (delay % 1000000)); + } + + /** + * Sleep for the specified micro-seconds. + * @param sleep microseconds to sleep for. + */ + private void sleep(long sleep) + { + sleep(sleep, 0); + } + + /** + * Perform the sleep , swallowing any InteruptException. + * + * NOTE: If a sleep request is > 10s then reset only sleep for 5s + * + * @param milli to sleep for + * @param nano sub miliseconds to sleep for + */ + private void sleep(long milli, int nano) + { + try + { + log.debug("Sleep:" + milli + ":" + nano); + if (milli > 10000) + { + + if (_delay == milli) + { + _totalDuration = _totalReceived / _batchSize * EXPECTED_TIME_PER_BATCH; + log.error("Sleeping for more than 10 seconds adjusted to 5s!:" + (milli / 1000) + + "s. Reset _totalDuration:" + _totalDuration); + } + else + { + log.error("Sleeping for more than 10 seconds adjusted to 5s!:" + (milli / 1000) + "s"); + } + + milli = 5000; + } + + Thread.sleep(milli, nano); + } + catch (InterruptedException e) + { + // + } + } + + public void setClient(SustainedClientTestCase client) + { + _client = client; + } + } + +} diff --git a/java/integrationtests/src/main/java/org/apache/qpid/sustained/SustainedTestCase.java b/java/integrationtests/src/main/java/org/apache/qpid/sustained/SustainedTestCase.java new file mode 100644 index 0000000000..36f9b4eaf1 --- /dev/null +++ b/java/integrationtests/src/main/java/org/apache/qpid/sustained/SustainedTestCase.java @@ -0,0 +1,126 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +package org.apache.qpid.sustained; + +import org.apache.log4j.Logger; + +import org.apache.qpid.client.AMQSession; +import org.apache.qpid.test.framework.distributedtesting.DistributedTestCase; +import org.apache.qpid.test.framework.DropInTest; + +import javax.jms.JMSException; +import javax.jms.Message; + +import java.util.Properties; + +/** + * SustainedTestCase is a {@link org.apache.qpid.test.framework.distributedtesting.DistributedTestCase} that runs the "Perf_SustainedPubSub" test case. This consists of one + * test client sending, and several receiving, and attempts to find the highest rate at which messages can be broadcast + * to the receivers. It is also a {@link DropInTest} to which more test clients may be added during a test run. + * + *

+ *
CRC Card
Responsibilities Collaborations + *
+ *
+ */ +public class SustainedTestCase extends DistributedTestCase implements DropInTest +{ + /** Used for debugging. */ + Logger log = Logger.getLogger(SustainedTestCase.class); + + /** Holds the root name of the topic on which to send the test messages. */ + private static final String SUSTAINED_KEY = "Perf_SustainedPubSub"; + + /** + * Creates a new coordinating test case with the specified name. + * + * @param name The test case name. + */ + public SustainedTestCase(String name) + { + super(name); + } + + /** + * Performs a single test run of the sustained test. + * + * @throws Exception Any exceptions are allowed to fall through and fail the test. + */ + public void testBasicPubSub() throws Exception + { + log.debug("public void testSinglePubSubCycle(): called"); + + Properties testConfig = new Properties(); + testConfig.put("TEST_NAME", "Perf_SustainedPubSub"); + testConfig.put("SUSTAINED_KEY", SUSTAINED_KEY); + testConfig.put("SUSTAINED_NUM_RECEIVERS", Integer.getInteger("numReceives", 2)); + testConfig.put("SUSTAINED_UPDATE_INTERVAL", Integer.getInteger("batchSize", 1000)); + testConfig.put("SUSTAINED_UPDATE_KEY", SUSTAINED_KEY + ".UPDATE"); + testConfig.put("ACKNOWLEDGE_MODE", Integer.getInteger("ackMode", AMQSession.AUTO_ACKNOWLEDGE)); + + log.info("Created Config: " + testConfig.entrySet().toArray()); + + getTestSequencer().sequenceTest(null, null, testConfig); + } + + /** + * Accepts a late joining client into this test case. The client will be enlisted with a control message + * with the 'CONTROL_TYPE' field set to the value 'LATEJOIN'. It should also provide values for the fields: + * + *

+ *
CLIENT_NAME A unique name for the new client. + *
CLIENT_PRIVATE_CONTROL_KEY The key for the route on which the client receives its control messages. + *
+ * + * @param message The late joiners join message. + * + * @throws JMSException Any JMS Exception are allowed to fall through, indicating that the join failed. + */ + public void lateJoin(Message message) throws JMSException + { + throw new RuntimeException("Not implemented."); + /* + // Extract the joining clients details from its join request message. + TestClientDetails clientDetails = new TestClientDetails(); + clientDetails.clientName = message.getStringProperty("CLIENT_NAME"); + clientDetails.privateControlKey = message.getStringProperty("CLIENT_PRIVATE_CONTROL_KEY"); + + // Register the joining client, but do block for confirmation as cannot do a synchronous receivers during this + // method call, as it may have been called from an 'onMessage' method. + assignReceiverRole(clientDetails, new Properties(), false); + */ + } + + /** + * Should provide a translation from the junit method name of a test to its test case name as known to the test + * clients that will run the test. The purpose of this is to convert the JUnit method name into the correct test + * case name to place into the test invite. For example the method "testP2P" might map onto the interop test case + * name "TC2_BasicP2P". + * + * @param methodName The name of the JUnit test method. + * + * @return The name of the corresponding interop test case. + */ + public String getTestCaseNameForTestMethod(String methodName) + { + return "Perf_SustainedPubSub"; + } +} diff --git a/java/integrationtests/src/main/java/org/apache/qpid/sustained/SustainedTestClient.java b/java/integrationtests/src/main/java/org/apache/qpid/sustained/SustainedTestClient.java index 6f2089290a..79707bafa5 100644 --- a/java/integrationtests/src/main/java/org/apache/qpid/sustained/SustainedTestClient.java +++ b/java/integrationtests/src/main/java/org/apache/qpid/sustained/SustainedTestClient.java @@ -425,7 +425,7 @@ public class SustainedTestClient extends TestCase3BasicPubSub implements Excepti class SustainedRateAdapter implements MessageListener, Runnable { private SustainedTestClient _client; - private long _batchVariance = 3; //no. batches to allow drifting + private long _batchVariance = Integer.getInteger("batchVariance", 3); //no. batches to allow drifting private long _timeVariance = TEN_MILLI_SEC * 5; // no. nanos between send and report delay (10ms) private volatile long _delay; //in nanos private long _sent; @@ -434,9 +434,11 @@ public class SustainedTestClient extends TestCase3BasicPubSub implements Excepti private static final long NO_CLIENT_SLEEP = 1000; // 1s private volatile boolean NO_CLIENTS = true; private int _delayShifting; - private static final int REPORTS_WITHOUT_CHANGE = 5; + private final int REPORTS_WITHOUT_CHANGE = Integer.getInteger("stableReportCount", 5); private boolean _warmedup = false; private static final long EXPECTED_TIME_PER_BATCH = 100000L; + private int _warmUpBatches = Integer.getInteger("warmUpBatches", 10); + SustainedRateAdapter(SustainedTestClient client) { @@ -493,8 +495,6 @@ public class SustainedTestClient extends TestCase3BasicPubSub implements Excepti CountDownLatch _warmup = new CountDownLatch(1); - int _warmUpBatches = Integer.getInteger("warmUpBatches", 10); - int _numBatches = 10000; // long[] _timings = new long[_numBatches]; diff --git a/java/integrationtests/src/main/java/org/apache/qpid/sustained/SustainedTestCoordinator.java b/java/integrationtests/src/main/java/org/apache/qpid/sustained/SustainedTestCoordinator.java deleted file mode 100644 index 0075e45a8c..0000000000 --- a/java/integrationtests/src/main/java/org/apache/qpid/sustained/SustainedTestCoordinator.java +++ /dev/null @@ -1,222 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - * - * - */ -package org.apache.qpid.sustained; - -import org.apache.log4j.Logger; -import org.apache.qpid.client.AMQSession; -import org.apache.qpid.interop.coordinator.ListeningCoordinatorTest; -import org.apache.qpid.interop.coordinator.TestClientDetails; -import org.apache.qpid.interop.coordinator.testcases.CoordinatingTestCase3BasicPubSub; -import org.apache.qpid.util.ConversationFactory; - -import javax.jms.Destination; -import javax.jms.JMSException; -import javax.jms.Message; -import javax.jms.Session; -import java.util.HashMap; -import java.util.LinkedList; -import java.util.List; -import java.util.Map; - -public class SustainedTestCoordinator extends CoordinatingTestCase3BasicPubSub implements ListeningCoordinatorTest -{ - /** Used for debugging. */ - private static final Logger log = Logger.getLogger(SustainedTestCoordinator.class); - private List _receivers; - private static final String SUSTAINED_KEY = "Perf_SustainedPubSub"; - Map _testProperties; - - /** - * Creates a new coordinating test case with the specified name. - * - * @param name The test case name. - */ - public SustainedTestCoordinator(String name) - { - super(name); - _receivers = new LinkedList(); - } - - /** - * Adds a receiver to this test. - * - * @param receiver The contact details of the sending client in the test. - */ - public void setReceiver(TestClientDetails receiver) - { - _receivers.add(receiver); - } - - - /** - * Performs the a single test run - * - * @throws Exception if there was a problem running the test. - */ - public void testBasicPubSub() throws Exception - { - log.debug("public void testSinglePubSubCycle(): called"); - - Map testConfig = new HashMap(); - testConfig.put("TEST_NAME", "Perf_SustainedPubSub"); - testConfig.put("SUSTAINED_KEY", SUSTAINED_KEY); - testConfig.put("SUSTAINED_NUM_RECEIVERS", Integer.getInteger("numReceives", 2)); - testConfig.put("SUSTAINED_UPDATE_INTERVAL", Integer.getInteger("batchSize", 1000)); - testConfig.put("SUSTAINED_UPDATE_KEY", SUSTAINED_KEY + ".UPDATE"); - testConfig.put("ACKNOWLEDGE_MODE", Integer.getInteger("ackMode", AMQSession.AUTO_ACKNOWLEDGE)); - - log.info("Created Config: " + testConfig.entrySet().toArray()); - - sequenceTest(testConfig); - } - - /** - * Holds a test coordinating conversation with the test clients. This is the basic implementation of the inner loop - * of Use Case 5. It consists of assigning the test roles, begining the test and gathering the test reports from the - * participants. - * - * @param testProperties The test case definition. - * - * @return The test results from the senders and receivers. - * - * @throws javax.jms.JMSException All underlying JMSExceptions are allowed to fall through. - */ - protected Message[] sequenceTest(Map testProperties) throws JMSException - { - log.debug("protected Message[] sequenceTest(Object... testProperties = " + testProperties + "): called"); - - Session session = conversationFactory.getSession(); - Destination senderControlTopic = session.createTopic(sender.privateControlKey); - - ConversationFactory.Conversation senderConversation = conversationFactory.startConversation(); - - // Assign the sender role to the sending test client. - Message assignSender = conversationFactory.getSession().createMessage(); - setPropertiesOnMessage(assignSender, testProperties); - assignSender.setStringProperty("CONTROL_TYPE", "ASSIGN_ROLE"); - assignSender.setStringProperty("ROLE", "SENDER"); - assignSender.setStringProperty("CLIENT_NAME", "Sustained_SENDER"); - - senderConversation.send(senderControlTopic, assignSender); - - //Assign and wait for the receiver ckuebts to be ready. - _testProperties = testProperties; - - // Wait for the senders to confirm their roles. - senderConversation.receive(); - - assignReceivers(); - - // Start the test. - Message start = session.createMessage(); - start.setStringProperty("CONTROL_TYPE", "START"); - - senderConversation.send(senderControlTopic, start); - - // Wait for the test sender to return its report. - Message senderReport = senderConversation.receive(); - - try - { - Thread.sleep(500); - } - catch (InterruptedException e) - { - } - - // Ask the receiver for its report. - Message statusRequest = session.createMessage(); - statusRequest.setStringProperty("CONTROL_TYPE", "STATUS_REQUEST"); - - - return new Message[]{senderReport}; - } - - private void assignReceivers() - { - for (TestClientDetails receiver : _receivers) - { - registerReceiver(receiver); - } - } - - private void registerReceiver(TestClientDetails receiver) - { - log.info("registerReceiver called for receiver:" + receiver); - try - { - Session session = conversationFactory.getSession(); - Destination receiverControlTopic = session.createTopic(receiver.privateControlKey); - ConversationFactory.Conversation receiverConversation = conversationFactory.startConversation(); - // Assign the receiver role the receiving client. - Message assignReceiver = session.createMessage(); - setPropertiesOnMessage(assignReceiver, _testProperties); - assignReceiver.setStringProperty("CONTROL_TYPE", "ASSIGN_ROLE"); - assignReceiver.setStringProperty("ROLE", "RECEIVER"); - assignReceiver.setStringProperty("CLIENT_NAME", "Sustained_RECEIVER_" + receiver.clientName); - - receiverConversation.send(receiverControlTopic, assignReceiver); - - //Don't wait for receiver to be ready.... we can't this is being done in - // the dispatcher thread, and most likely the acceptance message we - // want is sitting in the Dispatcher._queue waiting its turn for being - // dispatched so if we block here we won't can't get the message. - // So assume consumer is ready for action. - //receiverConversation.receive(); - } - catch (JMSException e) - { - log.warn("Unable to assign receiver:" + receiver + ". Due to:" + e.getMessage()); - } - } - - public void latejoin(Message message) - { - try - { - - TestClientDetails clientDetails = new TestClientDetails(); - clientDetails.clientName = message.getStringProperty("CLIENT_NAME"); - clientDetails.privateControlKey = message.getStringProperty("CLIENT_PRIVATE_CONTROL_KEY"); - - - registerReceiver(clientDetails); - } - catch (JMSException e) - { - //swallow - } - } - - /** - * Should provide a translation from the junit method name of a test to its test case name as defined in the interop - * testing specification. For example the method "testP2P" might map onto the interop test case name - * "TC2_BasicP2P". - * - * @param methodName The name of the JUnit test method. - * - * @return The name of the corresponding interop test case. - */ - public String getTestCaseNameForTestMethod(String methodName) - { - return "Perf_SustainedPubSub"; - } -} diff --git a/java/integrationtests/src/main/java/org/apache/qpid/sustained/TestClient.java b/java/integrationtests/src/main/java/org/apache/qpid/sustained/TestClient.java deleted file mode 100644 index 44fc090410..0000000000 --- a/java/integrationtests/src/main/java/org/apache/qpid/sustained/TestClient.java +++ /dev/null @@ -1,157 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - * - * - */ -package org.apache.qpid.sustained; - -import org.apache.log4j.Logger; -import org.apache.qpid.interop.testclient.InteropClientTestCase; -import org.apache.qpid.util.CommandLineParser; - -import javax.jms.JMSException; -import javax.jms.Message; -import java.util.ArrayList; -import java.util.Collection; -import java.util.Collections; -import java.util.Properties; - -public class TestClient extends org.apache.qpid.interop.testclient.TestClient -{ - private static Logger log = Logger.getLogger(TestClient.class); - - /** - * Creates a new interop test client, listenting to the specified broker and virtual host, with the specified client - * identifying name. - * - * @param brokerUrl The url of the broker to connect to. - * @param virtualHost The virtual host to conect to. - * @param clientName The client name to use. - */ - public TestClient(String brokerUrl, String virtualHost, String clientName) - { - super(brokerUrl, virtualHost, clientName); - } - - /** - * The entry point for the interop test coordinator. This client accepts the following command line arguments: - * - *

-b The broker URL. Optional.
-h The virtual - * host. Optional.
-n The test client name. Optional.
name=value - * Trailing argument define name/value pairs. Added to system properties. Optional.
- * - * @param args The command line arguments. - */ - public static void main(String[] args) - { - // Use the command line parser to evaluate the command line. - CommandLineParser commandLine = - new CommandLineParser( - new String[][] - { - {"b", "The broker URL.", "broker", "false"}, - {"h", "The virtual host to use.", "virtual host", "false"}, - {"n", "The test client name.", "name", "false"}, - {"j", "Join this test client to running test.", "join", ""} - }); - - // Capture the command line arguments or display errors and correct usage and then exit. - Properties options = null; - - try - { - options = commandLine.parseCommandLine(args); - } - catch (IllegalArgumentException e) - { - System.out.println(commandLine.getErrors()); - System.out.println(commandLine.getUsage()); - System.exit(1); - } - - // Extract the command line options. - String brokerUrl = options.getProperty("b"); - String virtualHost = options.getProperty("h"); - String clientName = options.getProperty("n"); - String join = options.getProperty("j"); - - // Add all the trailing command line options (name=value pairs) to system properties. Tests may pick up - // overridden values from there. - commandLine.addCommandLineToSysProperties(); - - // Create a test client and start it running. - TestClient client = new TestClient(brokerUrl, virtualHost, (clientName == null) ? CLIENT_NAME : clientName); - - // Use a class path scanner to find all the interop test case implementations. - Collection> testCaseClasses = - new ArrayList>(); - // ClasspathScanner.getMatches(InteropClientTestCase.class, "^TestCase.*", true); - // Hard code the test classes till the classpath scanner is fixed. - Collections.addAll(testCaseClasses, - SustainedTestClient.class); - - - try - { - client.start(testCaseClasses, join); - } - catch (Exception e) - { - log.error("The test client was unable to start.", e); - System.exit(1); - } - } - - protected void start(Collection> testCaseClasses, String join) throws JMSException, ClassNotFoundException - { - super.start(testCaseClasses); - log.debug("private void start(): called"); - - if (join != null && !join.equals("")) - { - Message latejoin = session.createMessage(); - - try - { - Object test = Class.forName(join).newInstance(); - if (test instanceof InteropClientTestCase) - { - currentTestCase = (InteropClientTestCase) test; - } - else - { - throw new RuntimeException("Requested to join class '" + join + "' but this is not a InteropClientTestCase."); - } - - latejoin.setStringProperty("CONTROL_TYPE", "LATEJOIN"); - latejoin.setStringProperty("CLIENT_NAME", clientName); - latejoin.setStringProperty("CLIENT_PRIVATE_CONTROL_KEY", "iop.control." + clientName); - producer.send(session.createTopic("iop.control.test." + currentTestCase.getName()), latejoin); - } - catch (InstantiationException e) - { - log.warn("Unable to request latejoining of test:" + currentTestCase); - } - catch (IllegalAccessException e) - { - log.warn("Unable to request latejoining of test:" + currentTestCase); - } - } - } - -} diff --git a/java/integrationtests/src/main/java/org/apache/qpid/sustained/TestCoordinator.java b/java/integrationtests/src/main/java/org/apache/qpid/sustained/TestCoordinator.java deleted file mode 100644 index 7e12fe39fb..0000000000 --- a/java/integrationtests/src/main/java/org/apache/qpid/sustained/TestCoordinator.java +++ /dev/null @@ -1,117 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - * - * - */ -package org.apache.qpid.sustained; - -import org.apache.qpid.interop.coordinator.Coordinator; -import org.apache.qpid.interop.coordinator.ListeningTestDecorator; -import org.apache.qpid.interop.coordinator.TestClientDetails; -import org.apache.qpid.util.CommandLineParser; -import org.apache.qpid.util.ConversationFactory; -import org.apache.log4j.Logger; - -import java.util.Properties; -import java.util.Set; - -import junit.framework.TestResult; -import uk.co.thebadgerset.junit.extensions.WrappedSuiteTestDecorator; - -import javax.jms.Connection; - -public class TestCoordinator extends Coordinator -{ - - private static final Logger log = Logger.getLogger(TestCoordinator.class); - - /** - * Creates an interop test coordinator on the specified broker and virtual host. - * - * @param brokerUrl The URL of the broker to connect to. - * @param virtualHost The virtual host to run all tests on. Optional, may be null. - */ - TestCoordinator(String brokerUrl, String virtualHost) - { - super(brokerUrl, virtualHost); - } - - protected WrappedSuiteTestDecorator newTestDecorator(WrappedSuiteTestDecorator targetTest, Set enlistedClients, ConversationFactory conversationFactory, Connection connection) - { - return new ListeningTestDecorator(targetTest, enlistedClients, conversationFactory, connection); - } - - - /** - * The entry point for the interop test coordinator. This client accepts the following command line arguments: - * - *

-b The broker URL. Mandatory.
-h The virtual host. - * Optional.
name=value Trailing argument define name/value pairs. Added to system properties. - * Optional.
- * - * @param args The command line arguments. - */ - public static void main(String[] args) - { - try - { - // Use the command line parser to evaluate the command line with standard handling behaviour (print errors - // and usage then exist if there are errors). - Properties options = - CommandLineParser.processCommandLine(args, - new CommandLineParser( - new String[][] - { - {"b", "The broker URL.", "broker", "false"}, - {"h", "The virtual host to use.", "virtual host", "false"}, - {"o", "The name of the directory to output test timings to.", "dir", "false"} - })); - - // Extract the command line options. - String brokerUrl = options.getProperty("b"); - String virtualHost = options.getProperty("h"); - String reportDir = options.getProperty("o"); - reportDir = (reportDir == null) ? "." : reportDir; - - - String[] testClassNames = {SustainedTestCoordinator.class.getName()}; - - // Create a coordinator and begin its test procedure. - Coordinator coordinator = new TestCoordinator(brokerUrl, virtualHost); - - coordinator.setReportDir(reportDir); - - TestResult testResult = coordinator.start(testClassNames); - - if (testResult.failureCount() > 0) - { - System.exit(FAILURE_EXIT); - } - else - { - System.exit(SUCCESS_EXIT); - } - } - catch (Exception e) - { - System.err.println(e.getMessage()); - log.error("Top level handler caught execption.", e); - System.exit(EXCEPTION_EXIT); - } - } -} diff --git a/java/integrationtests/src/main/java/org/apache/qpid/test/framework/distributedtesting/InteropClientTestCase.java b/java/integrationtests/src/main/java/org/apache/qpid/test/framework/distributedtesting/InteropClientTestCase.java new file mode 100644 index 0000000000..5e6d61a9e0 --- /dev/null +++ b/java/integrationtests/src/main/java/org/apache/qpid/test/framework/distributedtesting/InteropClientTestCase.java @@ -0,0 +1,101 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +package org.apache.qpid.test.framework.distributedtesting; + +import javax.jms.JMSException; +import javax.jms.Message; +import javax.jms.MessageListener; +import javax.jms.Session; + +/** + * InteropClientTestCase provides an interface that classes implementing test cases from the interop testing spec + * (http://cwiki.apache.org/confluence/display/qpid/Interop+Testing+Specification) should implement. Implementations + * must be Java beans, that is, to provide a default constructor and to implement the {@link #getName} method. + * + *

+ *
CRC Card
Responsibilities + *
Supply the name of the test case that this implements. + *
Accept/Reject invites based on test parameters. + *
Adapt to assigned roles. + *
Perform test case actions. + *
Generate test reports. + *
+ */ +public interface InteropClientTestCase extends MessageListener +{ + /** Defines the possible test case roles that an interop test case can take on. */ + public enum Roles + { + /** Specifies the sender role. */ + SENDER, + + /** Specifies the receivers role. */ + RECEIVER + } + + /** + * Should provide the name of the test case that this class implements. The exact names are defined in the + * interop testing spec. + * + * @return The name of the test case that this implements. + */ + public String getName(); + + /** + * Determines whether the test invite that matched this test case is acceptable. + * + * @param inviteMessage The invitation to accept or reject. + * + * @return true to accept the invitation, false to reject it. + * + * @throws JMSException Any JMSException resulting from reading the message are allowed to fall through. + */ + public boolean acceptInvite(Message inviteMessage) throws JMSException; + + /** + * Assigns the role to be played by this test case. The test parameters are fully specified in the + * assignment message. When this method return the test case will be ready to execute. + * + * @param role The role to be played; sender or receivers. + * @param assignRoleMessage The role assingment message, contains the full test parameters. + * + * @throws JMSException Any JMSException resulting from reading the message are allowed to fall through. + */ + public void assignRole(Roles role, Message assignRoleMessage) throws JMSException; + + /** + * Performs the test case actions. Returning from here, indicates that the sending role has completed its test. + * + * @throws JMSException Any JMSException resulting from reading the message are allowed to fall through. + */ + public void start() throws JMSException; + + /** + * Gets a report on the actions performed by the test case in its assigned role. + * + * @param session The session to create the report message in. + * + * @return The report message. + * + * @throws JMSException Any JMSExceptions resulting from creating the report are allowed to fall through. + */ + public Message getReport(Session session) throws JMSException; +} diff --git a/java/integrationtests/src/main/java/org/apache/qpid/test/framework/distributedtesting/TestClient.java b/java/integrationtests/src/main/java/org/apache/qpid/test/framework/distributedtesting/TestClient.java new file mode 100644 index 0000000000..12c0d0aa69 --- /dev/null +++ b/java/integrationtests/src/main/java/org/apache/qpid/test/framework/distributedtesting/TestClient.java @@ -0,0 +1,377 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +package org.apache.qpid.test.framework.distributedtesting; + +import org.apache.log4j.Logger; + +import org.apache.qpid.interop.clienttestcases.TestCase1DummyRun; +import org.apache.qpid.interop.clienttestcases.TestCase2BasicP2P; +import org.apache.qpid.interop.clienttestcases.TestCase3BasicPubSub; +import org.apache.qpid.sustained.SustainedClientTestCase; +import org.apache.qpid.test.framework.MessagingTestConfigProperties; +import org.apache.qpid.test.framework.TestUtils; + +import uk.co.thebadgerset.junit.extensions.util.ParsedProperties; +import uk.co.thebadgerset.junit.extensions.util.TestContextProperties; + +import javax.jms.*; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; + +/** + * Implements a test client as described in the interop testing spec + * (http://cwiki.apache.org/confluence/display/qpid/Interop+Testing+Specification). A test client is an agent that + * reacts to control message sequences send by the test {@link org.apache.qpid.test.framework.distributedtesting.Coordinator}. + * + *

+ *
Messages Handled by SustainedTestClient
Message Action + *
Invite(compulsory) Reply with Enlist. + *
Invite(test case) Reply with Enlist if test case available. + *
AssignRole(test case) Reply with Accept Role if matches an enlisted test. Keep test parameters. + *
Start Send test messages defined by test parameters. Send report on messages sent. + *
Status Request Send report on messages received. + *
Terminate Terminate the test client. + *
+ * + *

+ *
CRC Card
Responsibilities Collaborations + *
Handle all incoming control messages. {@link InteropClientTestCase} + *
Configure and look up test cases by name. {@link InteropClientTestCase} + *
+ */ +public class TestClient implements MessageListener +{ + /** Used for debugging. */ + private static final Logger log = Logger.getLogger(TestClient.class); + + /** Used for reporting to the console. */ + private static final Logger console = Logger.getLogger("CONSOLE"); + + /** Holds the default identifying name of the test client. */ + public static final String CLIENT_NAME = "java"; + + /** Holds the URL of the broker to run the tests on. */ + public static String brokerUrl; + + /** Holds the virtual host to run the tests on. If null, then the default virtual host is used. */ + public static String virtualHost; + + /** + * Holds the test context properties that provides the default test parameters, plus command line overrides. + * This is initialized with the default test parameters, to which command line overrides may be applied. + */ + public static ParsedProperties testContextProperties = + TestContextProperties.getInstance(MessagingTestConfigProperties.defaults); + + /** Holds all the test cases loaded from the classpath. */ + Map testCases = new HashMap(); + + /** Holds the test case currently being run by this client. */ + protected InteropClientTestCase currentTestCase; + + /** Holds the connection to the broker that the test is being coordinated on. */ + protected Connection connection; + + /** Holds the message producer to hold the test coordination over. */ + protected MessageProducer producer; + + /** Holds the JMS session for the test coordination. */ + protected Session session; + + /** Holds the name of this client, with a default value. */ + protected String clientName = CLIENT_NAME; + + /** This flag indicates that the test client should attempt to join the currently running test case on start up. */ + protected boolean join; + + /** + * Creates a new interop test client, listenting to the specified broker and virtual host, with the specified client + * identifying name. + * + * @param brokerUrl The url of the broker to connect to. + * @param virtualHost The virtual host to conect to. + * @param clientName The client name to use. + */ + public TestClient(String brokerUrl, String virtualHost, String clientName, boolean join) + { + log.debug("public SustainedTestClient(String brokerUrl = " + brokerUrl + ", String virtualHost = " + virtualHost + + ", String clientName = " + clientName + "): called"); + + // Retain the connection parameters. + this.brokerUrl = brokerUrl; + this.virtualHost = virtualHost; + this.clientName = clientName; + this.join = join; + } + + /** + * The entry point for the interop test coordinator. This client accepts the following command line arguments: + * + *

+ *
-b The broker URL. Optional. + *
-h The virtual host. Optional. + *
-n The test client name. Optional. + *
name=value Trailing argument define name/value pairs. Added to system properties. Optional. + *
+ * + * @param args The command line arguments. + */ + public static void main(String[] args) + { + // Override the default broker url to be localhost:5672. + testContextProperties.setProperty(MessagingTestConfigProperties.BROKER_PROPNAME, "tcp://localhost:5672"); + + // Use the command line parser to evaluate the command line with standard handling behaviour (print errors + // and usage then exist if there are errors). + // Any options and trailing name=value pairs are also injected into the test context properties object, + // to override any defaults that may have been set up. + ParsedProperties options = + new ParsedProperties(uk.co.thebadgerset.junit.extensions.util.CommandLineParser.processCommandLine(args, + new uk.co.thebadgerset.junit.extensions.util.CommandLineParser( + new String[][] + { + { "b", "The broker URL.", "broker", "false" }, + { "h", "The virtual host to use.", "virtual host", "false" }, + { "o", "The name of the directory to output test timings to.", "dir", "false" }, + { "n", "The name of the test client.", "name", "false" }, + { "j", "Join this test client to running test.", "false" } + }), testContextProperties)); + + // Extract the command line options. + String brokerUrl = options.getProperty("b"); + String virtualHost = options.getProperty("h"); + String clientName = options.getProperty("n"); + boolean join = options.getPropertyAsBoolean("j"); + + // Create a test client and start it running. + TestClient client = new TestClient(brokerUrl, virtualHost, (clientName == null) ? CLIENT_NAME : clientName, join); + + // Use a class path scanner to find all the interop test case implementations. + // Hard code the test classes till the classpath scanner is fixed. + Collection> testCaseClasses = + new ArrayList>(); + // ClasspathScanner.getMatches(InteropClientTestCase.class, "^TestCase.*", true); + Collections.addAll(testCaseClasses, TestCase1DummyRun.class, TestCase2BasicP2P.class, TestCase3BasicPubSub.class, + SustainedClientTestCase.class); + + try + { + client.start(testCaseClasses); + } + catch (Exception e) + { + log.error("The test client was unable to start.", e); + System.exit(1); + } + } + + /** + * Starts the interop test client running. This causes it to start listening for incoming test invites. + * + * @param testCaseClasses The classes of the available test cases. The test case names from these are used to + * matchin incoming test invites against. + * + * @throws JMSException Any underlying JMSExceptions are allowed to fall through. + */ + protected void start(Collection> testCaseClasses) throws JMSException + { + log.debug("private void start(): called"); + + // Create all the test case implementations and index them by the test names. + for (Class nextClass : testCaseClasses) + { + try + { + InteropClientTestCase testCase = nextClass.newInstance(); + testCases.put(testCase.getName(), testCase); + } + catch (InstantiationException e) + { + log.warn("Could not instantiate test case class: " + nextClass.getName(), e); + // Ignored. + } + catch (IllegalAccessException e) + { + log.warn("Could not instantiate test case class due to illegal access: " + nextClass.getName(), e); + // Ignored. + } + } + + // Open a connection to communicate with the coordinator on. + connection = TestUtils.createConnection(testContextProperties); + session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE); + + // Set this up to listen for control messages. + Topic privateControlTopic = session.createTopic("iop.control." + clientName); + MessageConsumer consumer = session.createConsumer(privateControlTopic); + consumer.setMessageListener(this); + + Topic controlTopic = session.createTopic("iop.control"); + MessageConsumer consumer2 = session.createConsumer(controlTopic); + consumer2.setMessageListener(this); + + // Create a producer to send replies with. + producer = session.createProducer(null); + + // If the join flag was set, then broadcast a join message to notify the coordinator that a new test client + // is available to join the current test case, if it supports it. This message may be ignored, or it may result + // in this test client receiving a test invite. + if (join) + { + Message joinMessage = session.createMessage(); + + joinMessage.setStringProperty("CONTROL_TYPE", "JOIN"); + joinMessage.setStringProperty("CLIENT_NAME", clientName); + joinMessage.setStringProperty("CLIENT_PRIVATE_CONTROL_KEY", "iop.control." + clientName); + producer.send(controlTopic, joinMessage); + } + + // Start listening for incoming control messages. + connection.start(); + } + + /** + * Handles all incoming control messages. + * + * @param message The incoming message. + */ + public void onMessage(Message message) + { + log.debug("public void onMessage(Message message = " + message + "): called"); + + try + { + String controlType = message.getStringProperty("CONTROL_TYPE"); + String testName = message.getStringProperty("TEST_NAME"); + + log.info("onMessage(Message message = " + message + "): for '" + controlType + "' to '" + testName + "'"); + + // Check if the message is a test invite. + if ("INVITE".equals(controlType)) + { + // Flag used to indicate that an enlist should be sent. Only enlist to compulsory invites or invites + // for which test cases exist. + boolean enlist = false; + + if (testName != null) + { + log.debug("Got an invite to test: " + testName); + + // Check if the requested test case is available. + InteropClientTestCase testCase = testCases.get(testName); + + if (testCase != null) + { + // Make the requested test case the current test case. + currentTestCase = testCase; + enlist = true; + } + else + { + log.debug("Received an invite to the test '" + testName + "' but this test is not known."); + } + } + else + { + log.debug("Got a compulsory invite."); + + enlist = true; + } + + if (enlist) + { + // Reply with the client name in an Enlist message. + Message enlistMessage = session.createMessage(); + enlistMessage.setStringProperty("CONTROL_TYPE", "ENLIST"); + enlistMessage.setStringProperty("CLIENT_NAME", clientName); + enlistMessage.setStringProperty("CLIENT_PRIVATE_CONTROL_KEY", "iop.control." + clientName); + enlistMessage.setJMSCorrelationID(message.getJMSCorrelationID()); + + log.info("Sending Message '" + enlistMessage + "'. to " + message.getJMSReplyTo()); + + producer.send(message.getJMSReplyTo(), enlistMessage); + } + } + else if ("ASSIGN_ROLE".equals(controlType)) + { + // Assign the role to the current test case. + String roleName = message.getStringProperty("ROLE"); + + log.debug("Got a role assignment to role: " + roleName); + + InteropClientTestCase.Roles role = Enum.valueOf(InteropClientTestCase.Roles.class, roleName); + + currentTestCase.assignRole(role, message); + + // Reply by accepting the role in an Accept Role message. + Message acceptRoleMessage = session.createMessage(); + acceptRoleMessage.setStringProperty("CONTROL_TYPE", "ACCEPT_ROLE"); + acceptRoleMessage.setJMSCorrelationID(message.getJMSCorrelationID()); + + producer.send(message.getJMSReplyTo(), acceptRoleMessage); + } + else if ("START".equals(controlType) || "STATUS_REQUEST".equals(controlType)) + { + if ("START".equals(controlType)) + { + log.debug("Got a start notification."); + + // Start the current test case. + currentTestCase.start(); + } + else + { + log.debug("Got a status request."); + } + + // Generate the report from the test case and reply with it as a Report message. + Message reportMessage = currentTestCase.getReport(session); + reportMessage.setStringProperty("CONTROL_TYPE", "REPORT"); + reportMessage.setJMSCorrelationID(message.getJMSCorrelationID()); + + producer.send(message.getJMSReplyTo(), reportMessage); + } + else if ("TERMINATE".equals(controlType)) + { + log.info("Received termination instruction from coordinator."); + + // Is a cleaner shutdown needed? + connection.close(); + System.exit(0); + } + else + { + // Log a warning about this but otherwise ignore it. + log.warn("Got an unknown control message, controlType = " + controlType + ", message = " + message); + } + } + catch (JMSException e) + { + // Log a warning about this, but otherwise ignore it. + log.warn("A JMSException occurred whilst handling a message."); + log.debug("Got JMSException whilst handling message: " + message, e); + } + } +} diff --git a/java/integrationtests/src/main/java/org/apache/qpid/util/ClasspathScanner.java b/java/integrationtests/src/main/java/org/apache/qpid/util/ClasspathScanner.java deleted file mode 100644 index bad49060ca..0000000000 --- a/java/integrationtests/src/main/java/org/apache/qpid/util/ClasspathScanner.java +++ /dev/null @@ -1,234 +0,0 @@ -/* - * - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - * - */ -package org.apache.qpid.util; - -import java.io.File; -import java.util.*; -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -import org.apache.log4j.Logger; - -/** - * An ClasspathScanner scans the classpath for classes that implement an interface or extend a base class and have names - * that match a regular expression. - * - *

In order to test whether a class implements an interface or extends a class, the class must be loaded (unless - * the class files were to be scanned directly). Using this collector can cause problems when it scans the classpath, - * because loading classes will initialize their statics, which in turn may cause undesired side effects. For this - * reason, the collector should always be used with a regular expression, through which the class file names are - * filtered, and only those that pass this filter will be tested. For example, if you define tests in classes that - * end with the keyword "Test" then use the regular expression "Test$" to match this. - * - *

- *
CRC Card
Responsibilities Collaborations - *
Find all classes matching type and name pattern on the classpath. - *
- * - * @todo Add logic to scan jars as well as directories. - */ -public class ClasspathScanner -{ - private static final Logger log = Logger.getLogger(ClasspathScanner.class); - - /** - * Scans the classpath and returns all classes that extend a specified class and match a specified name. - * There is an flag that can be used to indicate that only Java Beans will be matched (that is, only those classes - * that have a default constructor). - * - * @param matchingClass The class or interface to match. - * @param matchingRegexp The regular expression to match against the class name. - * @param beanOnly Flag to indicate that onyl classes with default constructors should be matched. - * - * @return All the classes that match this collector. - */ - public static Collection> getMatches(Class matchingClass, String matchingRegexp, - boolean beanOnly) - { - log.debug("public static Collection> getMatches(Class matchingClass = " + matchingClass - + ", String matchingRegexp = " + matchingRegexp + ", boolean beanOnly = " + beanOnly + "): called"); - - // Build a compiled regular expression from the pattern to match. - Pattern matchPattern = Pattern.compile(matchingRegexp); - - String classPath = System.getProperty("java.class.path"); - Map> result = new HashMap>(); - - log.debug("classPath = " + classPath); - - // Find matching classes starting from all roots in the classpath. - for (String path : splitClassPath(classPath)) - { - gatherFiles(new File(path), "", result, matchPattern, matchingClass); - } - - return result.values(); - } - - /** - * Finds all matching classes rooted at a given location in the file system. If location is a directory it - * is recursively examined. - * - * @param classRoot The root of the current point in the file system being examined. - * @param classFileName The name of the current file or directory to examine. - * @param result The accumulated mapping from class names to classes that match the scan. - * - * @todo Recursion ok as file system depth is not likely to exhaust the stack. Might be better to replace with - * iteration. - */ - private static void gatherFiles(File classRoot, String classFileName, Map> result, - Pattern matchPattern, Class matchClass) - { - log.debug("private static void gatherFiles(File classRoot = " + classRoot + ", String classFileName = " - + classFileName + ", Map> result, Pattern matchPattern = " + matchPattern - + ", Class matchClass = " + matchClass + "): called"); - - File thisRoot = new File(classRoot, classFileName); - - // If the current location is a file, check if it is a matching class. - if (thisRoot.isFile()) - { - // Check that the file has a matching name. - if (matchesName(thisRoot.getName(), matchPattern)) - { - String className = classNameFromFile(thisRoot.getName()); - - // Check that the class has matching type. - try - { - Class candidateClass = Class.forName(className); - - Class matchedClass = matchesClass(candidateClass, matchClass); - - if (matchedClass != null) - { - result.put(className, matchedClass); - } - } - catch (ClassNotFoundException e) - { - // Ignore this. The matching class could not be loaded. - log.debug("Got ClassNotFoundException, ignoring.", e); - } - } - - return; - } - // Otherwise the current location is a directory, so examine all of its contents. - else - { - String[] contents = thisRoot.list(); - - if (contents != null) - { - for (String content : contents) - { - gatherFiles(classRoot, classFileName + File.separatorChar + content, result, matchPattern, matchClass); - } - } - } - } - - /** - * Checks if the specified class file name corresponds to a class with name matching the specified regular expression. - * - * @param classFileName The class file name. - * @param matchPattern The regular expression pattern to match. - * - * @return true if the class name matches, false otherwise. - */ - private static boolean matchesName(String classFileName, Pattern matchPattern) - { - String className = classNameFromFile(classFileName); - Matcher matcher = matchPattern.matcher(className); - - return matcher.matches(); - } - - /** - * Checks if the specified class to compare extends the base class being scanned for. - * - * @param matchingClass The base class to match against. - * @param toMatch The class to match against the base class. - * - * @return The class to check, cast as an instance of the class to match if the class extends the base class, or - * null otherwise. - */ - private static Class matchesClass(Class matchingClass, Class toMatch) - { - try - { - return matchingClass.asSubclass(toMatch); - } - catch (ClassCastException e) - { - return null; - } - } - - /** - * Takes a classpath (which is a series of paths) and splits it into its component paths. - * - * @param classPath The classpath to split. - * - * @return A list of the component paths that make up the class path. - */ - private static List splitClassPath(String classPath) - { - List result = new LinkedList(); - String separator = System.getProperty("path.separator"); - StringTokenizer tokenizer = new StringTokenizer(classPath, separator); - - while (tokenizer.hasMoreTokens()) - { - result.add(tokenizer.nextToken()); - } - - return result; - } - - /** - * Translates from the filename of a class to its fully qualified classname. Files are named using forward slash - * seperators and end in ".class", whereas fully qualified class names use "." sperators and no ".class" ending. - * - * @param classFileName The filename of the class to translate to a class name. - * - * @return The fully qualified class name. - */ - private static String classNameFromFile(String classFileName) - { - log.debug("private static String classNameFromFile(String classFileName = " + classFileName + "): called"); - - // Remove the .class ending. - String s = classFileName.substring(0, classFileName.length() - ".class".length()); - - // Turn / seperators in . seperators. - String s2 = s.replace(File.separatorChar, '.'); - - // Knock off any leading . caused by a leading /. - if (s2.startsWith(".")) - { - return s2.substring(1); - } - - return s2; - } -} diff --git a/java/integrationtests/src/main/java/org/apache/qpid/util/ConversationFactory.java b/java/integrationtests/src/main/java/org/apache/qpid/util/ConversationFactory.java deleted file mode 100644 index 0090bec3d0..0000000000 --- a/java/integrationtests/src/main/java/org/apache/qpid/util/ConversationFactory.java +++ /dev/null @@ -1,479 +0,0 @@ -/* - * - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - * - */ -package org.apache.qpid.util; - -import org.apache.log4j.Logger; - -import javax.jms.*; - -import java.util.*; -import java.util.concurrent.BlockingQueue; -import java.util.concurrent.LinkedBlockingQueue; -import java.util.concurrent.TimeUnit; -import java.util.concurrent.atomic.AtomicLong; - -/** - * A conversation helper, uses a message correlation id pattern to match up sent and received messages as a conversation - * over JMS messaging. Incoming message traffic is divided up by correlation id. Each id has a queue (behaviour dependant - * on the queue implementation). Clients of this de-multiplexer can wait on messages, defined by message correlation ids. - * - *

One use of this is as a conversation synchronizer where multiple threads are carrying out conversations over a - * multiplexed messaging route. This can be usefull, as JMS sessions are not multi-threaded. Setting up the conversation - * with synchronous queues will allow these threads to be written in a synchronous style, but with their execution order - * governed by the asynchronous message flow. For example, something like the following code could run a multi-threaded - * conversation (the conversation methods can be called many times in parallel): - * - *

- * class Initiator
- * {
- * ConversationHelper conversation = new ConversationHelper(connection, null,
- *                                                          java.util.concurrent.LinkedBlockingQueue.class);
- *
- * initiateConversation()
- * {
- *  try {
- *   // Exchange greetings.
- *   conversation.send(sendDestination, conversation.getSession().createTextMessage("Hello."));
- *   Message greeting = conversation.receive();
- *
- *   // Exchange goodbyes.
- *   conversation.send(conversation.getSession().createTextMessage("Goodbye."));
- *   Message goodbye = conversation.receive();
- *  } finally {
- *   conversation.end();
- *  }
- * }
- * }
- *
- * class Responder
- * {
- * ConversationHelper conversation = new ConversationHelper(connection, receiveDestination,
- *                                                          java.util.concurrent.LinkedBlockingQueue.class);
- *
- * respondToConversation()
- * {
- *   try {
- *   // Exchange greetings.
- *   Message greeting = conversation.receive();
- *   conversation.send(conversation.getSession().createTextMessage("Hello."));
- *
- *   // Exchange goodbyes.
- *   Message goodbye = conversation.receive();
- *   conversation.send(conversation.getSession().createTextMessage("Goodbye."));
- *  } finally {
- *   conversation.end();
- *  }
- * }
- * }
- * 
- * - *

Conversation correlation id's are generated on a per thread basis. - * - *

The same session is shared amongst all conversations. Calls to send are therefore synchronized because JMS - * sessions are not multi-threaded. - * - *

- *
CRC Card
Responsibilities Collaborations - *
Associate messages to an ongoing conversation using correlation ids. - *
Auto manage sessions for conversations. - *
Store messages not in a conversation in dead letter box. - *
- */ -public class ConversationFactory -{ - /** Used for debugging. */ - private static final Logger log = Logger.getLogger(ConversationFactory.class); - - /** Holds a map from correlation id's to queues. */ - private Map> idsToQueues = new HashMap>(); - - /** Holds the connection over which the conversation is conducted. */ - private Connection connection; - - /** Holds the session over which the conversation is conduxted. */ - private Session session; - - /** The message consumer for incoming messages. */ - MessageConsumer consumer; - - /** The message producer for outgoing messages. */ - MessageProducer producer; - - /** The well-known or temporary destination to receive replies on. */ - Destination receiveDestination; - - /** Holds the queue implementation class for the reply queue. */ - Class queueClass; - - /** Used to hold any replies that are received outside of the context of a conversation. */ - BlockingQueue deadLetterBox = new LinkedBlockingQueue(); - - /* Used to hold conversation state on a per thread basis. */ - /* - ThreadLocal threadLocals = - new ThreadLocal() - { - protected Conversation initialValue() - { - Conversation settings = new Conversation(); - settings.conversationId = conversationIdGenerator.getAndIncrement(); - - return settings; - } - }; - */ - - /** Generates new coversation id's as needed. */ - AtomicLong conversationIdGenerator = new AtomicLong(); - - /** - * Creates a conversation helper on the specified connection with the default sending destination, and listening - * to the specified receiving destination. - * - * @param connection The connection to build the conversation helper on. - * @param receiveDestination The destination to listen to for incoming messages. This may be null to use a temporary - * queue. - * @param queueClass The queue implementation class. - * - * @throws JMSException All underlying JMSExceptions are allowed to fall through. - */ - public ConversationFactory(Connection connection, Destination receiveDestination, - Class queueClass) throws JMSException - { - log.debug("public ConversationFactory(Connection connection, Destination receiveDestination = " + receiveDestination - + ", Class queueClass = " + queueClass + "): called"); - - this.connection = connection; - this.queueClass = queueClass; - - session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE); - - // Check if a well-known receive destination has been provided, or use a temporary queue if not. - this.receiveDestination = (receiveDestination != null) ? receiveDestination : session.createTemporaryQueue(); - - consumer = session.createConsumer(receiveDestination); - producer = session.createProducer(null); - - consumer.setMessageListener(new Receiver()); - } - - /** - * Creates a new conversation context. - * - * @return A new conversation context. - */ - public Conversation startConversation() - { - log.debug("public Conversation startConversation(): called"); - - Conversation conversation = new Conversation(); - conversation.conversationId = conversationIdGenerator.getAndIncrement(); - - return conversation; - } - - /** - * Ensures that the reply queue for a conversation exists. - * - * @param conversationId The conversation correlation id. - */ - private void initQueueForId(long conversationId) - { - if (!idsToQueues.containsKey(conversationId)) - { - idsToQueues.put(conversationId, ReflectionUtils.newInstance(queueClass)); - } - } - - /** - * Clears the dead letter box, returning all messages that were in it. - * - * @return All messages in the dead letter box. - */ - public Collection emptyDeadLetterBox() - { - log.debug("public Collection emptyDeadLetterBox(): called"); - - Collection result = new ArrayList(); - deadLetterBox.drainTo(result); - - return result; - } - - /** - * Gets the session over which the conversation is conducted. - * - * @return The session over which the conversation is conducted. - */ - public Session getSession() - { - // Conversation settings = threadLocals.get(); - - return session; - } - - /** - * Used to hold a conversation context. This consists of a correlating id for the conversation, and a reply - * destination automatically updated to the last received reply-to destination. - */ - public class Conversation - { - /** Holds the correlation id for the context. */ - long conversationId; - - /** - * Holds the send destination for the context. This will automatically be updated to the most recently received - * reply-to destination. - */ - Destination sendDestination; - - /** - * Sends a message to the default sending location. The correlation id of the message will be assigned by this - * method, overriding any previously set value. - * - * @param sendDestination The destination to send to. This may be null to use the last received reply-to - * destination. - * @param message The message to send. - * - * @throws JMSException All undelying JMSExceptions are allowed to fall through. This will also be thrown if no - * send destination is specified and there is no most recent reply-to destination available - * to use. - */ - public void send(Destination sendDestination, Message message) throws JMSException - { - log.debug("public void send(Destination sendDestination = " + sendDestination + ", Message message = " + message - + "): called"); - - // Conversation settings = threadLocals.get(); - // long conversationId = conversationId; - message.setJMSCorrelationID(Long.toString(conversationId)); - message.setJMSReplyTo(receiveDestination); - - // Ensure that the reply queue for this conversation exists. - initQueueForId(conversationId); - - // Check if an overriding send to destination has been set or use the last reply-to if not. - Destination sendTo = null; - - if (sendDestination != null) - { - sendTo = sendDestination; - } - else if (sendDestination != null) - { - sendTo = sendDestination; - } - else - { - throw new JMSException("The send destination was specified, and no most recent reply-to available to use."); - } - - // Send the message. - synchronized (this) - { - producer.send(sendTo, message); - } - } - - /** - * Gets the next message in an ongoing conversation. This method may block until such a message is received. - * - * @return The next incoming message in the conversation. - * - * @throws JMSException All undelying JMSExceptions are allowed to fall through. Thrown if the received message - * did not have its reply-to destination set up. - */ - public Message receive() throws JMSException - { - log.debug("public Message receive(): called"); - - // Conversation settings = threadLocals.get(); - // long conversationId = settings.conversationId; - - // Ensure that the reply queue for this conversation exists. - initQueueForId(conversationId); - - BlockingQueue queue = idsToQueues.get(conversationId); - - try - { - Message result = queue.take(); - - // Keep the reply-to destination to send replies to. - sendDestination = result.getJMSReplyTo(); - - return result; - } - catch (InterruptedException e) - { - return null; - } - } - - /** - * Gets many messages in an ongoing conversation. If a limit is specified, then once that many messages are - * received they will be returned. If a timeout is specified, then all messages up to the limit, received within - * that timespan will be returned. At least one of the message count or timeout should be set to a value of - * 1 or greater. - * - * @param num The number of messages to receive, or all if this is less than 1. - * @param timeout The timeout in milliseconds to receive the messages in, or forever if this is less than 1. - * - * @return All messages received within the count limit and the timeout. - * - * @throws JMSException All undelying JMSExceptions are allowed to fall through. - */ - public Collection receiveAll(int num, long timeout) throws JMSException - { - log.debug("public Collection receiveAll(int num = " + num + ", long timeout = " + timeout - + "): called"); - - // Check that a timeout or message count was set. - if ((num < 1) && (timeout < 1)) - { - throw new IllegalArgumentException("At least one of message count (num) or timeout must be set."); - } - - // Ensure that the reply queue for this conversation exists. - initQueueForId(conversationId); - BlockingQueue queue = idsToQueues.get(conversationId); - - // Used to collect the received messages in. - Collection result = new ArrayList(); - - // Used to indicate when the timeout or message count has expired. - boolean receiveMore = true; - - int messageCount = 0; - - // Receive messages until the timeout or message count expires. - do - { - try - { - Message next = null; - - // Try to receive the message with a timeout if one has been set. - if (timeout > 0) - { - next = queue.poll(timeout, TimeUnit.MILLISECONDS); - - // Check if the timeout expired, and stop receiving if so. - if (next == null) - { - receiveMore = false; - } - } - // Receive the message without a timeout. - else - { - next = queue.take(); - } - - // Increment the message count if a message was received. - messageCount += (next != null) ? 1 : 0; - - // Check if all the requested messages were received, and stop receiving if so. - if ((num > 0) && (messageCount >= num)) - { - receiveMore = false; - } - - // Keep the reply-to destination to send replies to. - sendDestination = (next != null) ? next.getJMSReplyTo() : sendDestination; - - if (next != null) - { - result.add(next); - } - } - catch (InterruptedException e) - { - // Restore the threads interrupted status. - Thread.currentThread().interrupt(); - - // Stop receiving but return the messages received so far. - receiveMore = false; - } - } - while (receiveMore); - - return result; - } - - /** - * Completes the conversation. Any correlation id's pertaining to the conversation are no longer valid, and any - * incoming messages using them will go to the dead letter box. - */ - public void end() - { - log.debug("public void end(): called"); - - // Ensure that the thread local for the current thread is cleaned up. - // Conversation settings = threadLocals.get(); - // long conversationId = settings.conversationId; - // threadLocals.remove(); - - // Ensure that its queue is removed from the queue map. - BlockingQueue queue = idsToQueues.remove(conversationId); - - // Move any outstanding messages on the threads conversation id into the dead letter box. - queue.drainTo(deadLetterBox); - } - } - - /** - * Implements the message listener for this conversation handler. - */ - protected class Receiver implements MessageListener - { - /** - * Handles all incoming messages in the ongoing conversations. These messages are split up by correaltion id - * and placed into queues. - * - * @param message The incoming message. - */ - public void onMessage(Message message) - { - log.debug("public void onMessage(Message message = " + message + "): called"); - - try - { - Long conversationId = Long.parseLong(message.getJMSCorrelationID()); - - // Find the converstaion queue to place the message on. If there is no conversation for the message id, - // the the dead letter box queue is used. - BlockingQueue queue = idsToQueues.get(conversationId); - queue = (queue == null) ? deadLetterBox : queue; - - queue.put(message); - } - catch (JMSException e) - { - throw new RuntimeException(e); - } - catch (InterruptedException e) - { - throw new RuntimeException(e); - } - } - } -} diff --git a/java/integrationtests/src/resources/org/apache/qpid/interop/connection.properties b/java/integrationtests/src/resources/org/apache/qpid/interop/connection.properties deleted file mode 100644 index a5fb611dfa..0000000000 --- a/java/integrationtests/src/resources/org/apache/qpid/interop/connection.properties +++ /dev/null @@ -1,20 +0,0 @@ -# -# Licensed to the Apache Software Foundation (ASF) under one -# or more contributor license agreements. See the NOTICE file -# distributed with this work for additional information -# regarding copyright ownership. The ASF licenses this file -# to you under the Apache License, Version 2.0 (the -# "License"); you may not use this file except in compliance -# with the License. You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, -# software distributed under the License is distributed on an -# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -# KIND, either express or implied. See the License for the -# specific language governing permissions and limitations -# under the License. -# -java.naming.factory.initial = org.apache.qpid.jndi.PropertiesFileInitialContextFactory -connectionfactory.broker = amqp://guest:guest@clientid/?brokerlist='tcp://localhost:5672' diff --git a/java/management/eclipse-plugin/pom.xml b/java/management/eclipse-plugin/pom.xml index 6637460822..2ec30d212a 100644 --- a/java/management/eclipse-plugin/pom.xml +++ b/java/management/eclipse-plugin/pom.xml @@ -15,7 +15,7 @@ KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. ---> + --> @@ -38,17 +38,17 @@ - + repo1.maven.org Maven eclipse Repository http://repo1.maven.org/eclipse - - + + apache.snapshots Apache SNAPSHOT Repository http://people.apache.org/repo/m2-snapshot-repository - true + true @@ -197,43 +197,46 @@ icons/ icons/ - ** + ** icons/ / - splash.bmp + splash.bmp - ${basedir} - / - - plugin.xml - plugin.properties - + ${basedir} + / + + plugin.xml + plugin.properties + - + + org.apache.maven.plugins maven-jar-plugin - - META-INF/MANIFEST.MF - - ${artifactId}_${version} + + META-INF/MANIFEST.MF + + ${artifactId}_${version} - + + - -n TQR-Qpid-01 -d10M -s[1000] -c[8] -o $QPID_WORK/results -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=false pubsub=false transacted=true commitBatchSize=100 batchSize=1000 messageSize=256 destinationsCount=1 rate=0 maxPending=1000000 - -n TQR-Qpid-02 -d10M -s[1000] -c[8] -o $QPID_WORK/results -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=false pubsub=false transacted=false commitBatchSize=100 batchSize=1000 messageSize=256 destinationsCount=1 rate=0 maxPending=1000000 - -n TQR-Qpid-03 -d24H -s[100000] -c[8] -o $QPID_WORK/results -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=false pubsub=false transacted=true commitBatchSize=100 batchSize=100000 messageSize=256 destinationsCount=1 rate=0 maxPending=1000000 - -n TQR-Qpid-04 -d24H -s[100000] -c[8] -o $QPID_WORK/results -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=false pubsub=false transacted=false commitBatchSize=100 batchSize=100000 messageSize=256 destinationsCount=1 rate=0 maxPending=1000000 - - -n TQC-Qpid-01 -d1M -s[1000] -c[1,30],samples=30 -o $QPID_WORK/results -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=false pubsub=false transacted=true commitBatchSize=100 batchSize=1000 messageSize=256 destinationsCount=1 rate=1000 maxPending=1000000 - -n TQC-Qpid-02 -d1M -s[1000] -c[1,30],samples=30 -o $QPID_WORK/results -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=false pubsub=false transacted=false commitBatchSize=100 batchSize=1000 messageSize=256 destinationsCount=1 rate=1000 maxPending=1000000 - -n TQC-Qpid-03 -d10M -s[1000] -c[10] -o $QPID_WORK/results -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=false pubsub=false transacted=true commitBatchSize=100 batchSize=1000 messageSize=256 destinationsCount=10 rate=0 maxPending=1000000 - -n TQC-Qpid-04 -d10M -s[1000] -c[10] -o $QPID_WORK/results -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=false pubsub=false transacted=false commitBatchSize=100 batchSize=1000 messageSize=256 destinationsCount=10 rate=0 maxPending=1000000 - -n TQC-Qpid-05 -d10M -s[1000] -c[100] -o $QPID_WORK/results -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=false pubsub=false transacted=true commitBatchSize=100 batchSize=1000 messageSize=256 destinationsCount=10 rate=0 maxPending=100000 - -n TQC-Qpid-06 -d10M -s[1000] -c[100] -o $QPID_WORK/results -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=false pubsub=false transacted=false commitBatchSize=100 batchSize=1000 messageSize=256 destinationsCount=10 rate=0 maxPending=100000 - - -n TQM-Qpid-01-512b -d10M -s[1000] -c[1] -o $QPID_WORK/results -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=false pubsub=false transacted=true commitBatchSize=10 batchSize=1000 messageSize=512 destinationsCount=1 rate=0 maxPending=20000000 - -n TQM-Qpid-02-512b -d10M -s[1000] -c[1] -o $QPID_WORK/results -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=false pubsub=false transacted=false commitBatchSize=10 batchSize=1000 messageSize=512 destinationsCount=1 rate=0 maxPending=20000000 - -n TQM-Qpid-01-1K -d10M -s[1000] -c[1] -o $QPID_WORK/results -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=false pubsub=false transacted=true commitBatchSize=10 batchSize=1000 messageSize=1024 destinationsCount=1 rate=0 maxPending=20000000 - -n TQM-Qpid-02-1K -d10M -s[1000] -c[1] -o $QPID_WORK/results -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=false pubsub=false transacted=false commitBatchSize=10 batchSize=1000 messageSize=1024 destinationsCount=1 rate=0 maxPending=20000000 - -n TQM-Qpid-01-5K -d10M -s[1000] -c[1] -o $QPID_WORK/results -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=false pubsub=false transacted=true commitBatchSize=10 batchSize=1000 messageSize=5120 destinationsCount=1 rate=0 maxPending=20000000 - -n TQM-Qpid-02-5K -d10M -s[1000] -c[1] -o $QPID_WORK/results -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=false pubsub=false transacted=false commitBatchSize=10 batchSize=1000 messageSize=5120 destinationsCount=1 rate=0 maxPending=20000000 - -n TQM-Qpid-01-10K -d10M -s[1000] -c[1] -o $QPID_WORK/results -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=false pubsub=false transacted=true commitBatchSize=10 batchSize=1000 messageSize=10240 destinationsCount=1 rate=0 maxPending=20000000 - -n TQM-Qpid-02-10K -d10M -s[1000] -c[1] -o $QPID_WORK/results -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=false pubsub=false transacted=false commitBatchSize=10 batchSize=1000 messageSize=10240 destinationsCount=1 rate=0 maxPending=20000000 - -n TQM-Qpid-01-50K -d10M -s[1000] -c[1] -o $QPID_WORK/results -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=false pubsub=false transacted=true commitBatchSize=10 batchSize=1000 messageSize=51200 destinationsCount=1 rate=0 maxPending=20000000 - -n TQM-Qpid-02-50K -d10M -s[1000] -c[1] -o $QPID_WORK/results -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=false pubsub=false transacted=false commitBatchSize=10 batchSize=1000 messageSize=51200 destinationsCount=1 rate=0 maxPending=20000000 - -n TQM-Qpid-01-100K -d10M -s[1000] -c[1] -o $QPID_WORK/results -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=false pubsub=false transacted=true commitBatchSize=10 batchSize=1000 messageSize=102400 destinationsCount=1 rate=0 maxPending=20000000 - -n TQM-Qpid-02-100K -d10M -s[1000] -c[1] -o $QPID_WORK/results -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=false pubsub=false transacted=false commitBatchSize=10 batchSize=1000 messageSize=102400 destinationsCount=1 rate=0 maxPending=20000000 - -n TQM-Qpid-01-500K -d10M -s[1000] -c[1] -o $QPID_WORK/results -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=false pubsub=false transacted=true commitBatchSize=10 batchSize=1000 messageSize=512000 destinationsCount=1 rate=0 maxPending=20000000 - -n TQM-Qpid-02-500K -d10M -s[1000] -c[1] -o $QPID_WORK/results -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=false pubsub=false transacted=false commitBatchSize=10 batchSize=1000 messageSize=512000 destinationsCount=1 rate=0 maxPending=20000000 - -n TQM-Qpid-01-1M -d10M -s[1000] -c[1] -o $QPID_WORK/results -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=false pubsub=false transacted=true commitBatchSize=10 batchSize=1000 messageSize=1048576 destinationsCount=1 rate=0 maxPending=20000000 - -n TQM-Qpid-02-1M -d10M -s[1000] -c[1] -o $QPID_WORK/results -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=false pubsub=false transacted=false commitBatchSize=10 batchSize=1000 messageSize=1048576 destinationsCount=1 rate=0 maxPending=20000000 + -n TQR-Qpid-01 -d10M -s[1000] -c[8] -o $QPID_WORK/results -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=false pubsub=false transacted=true commitBatchSize=100 batchSize=1000 messageSize=256 destinationCount=1 rate=0 maxPending=1000000 + -n TQR-Qpid-02 -d10M -s[1000] -c[8] -o $QPID_WORK/results -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=false pubsub=false transacted=false commitBatchSize=100 batchSize=1000 messageSize=256 destinationCount=1 rate=0 maxPending=1000000 + -n TQR-Qpid-03 -d24H -s[100000] -c[8] -o $QPID_WORK/results -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=false pubsub=false transacted=true commitBatchSize=100 batchSize=100000 messageSize=256 destinationCount=1 rate=0 maxPending=1000000 + -n TQR-Qpid-04 -d24H -s[100000] -c[8] -o $QPID_WORK/results -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=false pubsub=false transacted=false commitBatchSize=100 batchSize=100000 messageSize=256 destinationCount=1 rate=0 maxPending=1000000 + + -n TQC-Qpid-01 -d1M -s[1000] -c[1,30],samples=30 -o $QPID_WORK/results -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=false pubsub=false transacted=true commitBatchSize=100 batchSize=1000 messageSize=256 destinationCount=1 rate=2000 maxPending=1000000 + -n TQC-Qpid-02 -d1M -s[1000] -c[1,30],samples=30 -o $QPID_WORK/results -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=false pubsub=false transacted=false commitBatchSize=100 batchSize=1000 messageSize=256 destinationCount=1 rate=2000 maxPending=1000000 + -n TQC-Qpid-03 -d10M -s[1000] -c[10] -o $QPID_WORK/results -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=false pubsub=false transacted=true commitBatchSize=100 batchSize=1000 messageSize=256 destinationCount=10 rate=0 maxPending=1000000 + -n TQC-Qpid-04 -d10M -s[1000] -c[10] -o $QPID_WORK/results -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=false pubsub=false transacted=false commitBatchSize=100 batchSize=1000 messageSize=256 destinationCount=10 rate=0 maxPending=1000000 + -n TQC-Qpid-05 -d10M -s[1000] -c[100] -o $QPID_WORK/results -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=false pubsub=false transacted=true commitBatchSize=100 batchSize=1000 messageSize=256 destinationCount=10 rate=0 maxPending=100000 + -n TQC-Qpid-06 -d10M -s[1000] -c[100] -o $QPID_WORK/results -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=false pubsub=false transacted=false commitBatchSize=100 batchSize=1000 messageSize=256 destinationCount=10 rate=0 maxPending=100000 + + -n TQM-Qpid-01-512b -d10M -s[1000] -c[8] -o $QPID_WORK/results -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=false pubsub=false transacted=true commitBatchSize=10 batchSize=1000 messageSize=512 destinationCount=1 rate=0 maxPending=20000000 + -n TQM-Qpid-02-512b -d10M -s[1000] -c[8] -o $QPID_WORK/results -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=false pubsub=false transacted=false commitBatchSize=10 batchSize=1000 messageSize=512 destinationCount=1 rate=0 maxPending=20000000 + -n TQM-Qpid-01-1K -d10M -s[1000] -c[8] -o $QPID_WORK/results -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=false pubsub=false transacted=true commitBatchSize=10 batchSize=1000 messageSize=1024 destinationCount=1 rate=0 maxPending=20000000 + -n TQM-Qpid-02-1K -d10M -s[1000] -c[8] -o $QPID_WORK/results -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=false pubsub=false transacted=false commitBatchSize=10 batchSize=1000 messageSize=1024 destinationCount=1 rate=0 maxPending=20000000 + -n TQM-Qpid-01-5K -d10M -s[1000] -c[8] -o $QPID_WORK/results -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=false pubsub=false transacted=true commitBatchSize=10 batchSize=1000 messageSize=5120 destinationCount=1 rate=0 maxPending=20000000 + -n TQM-Qpid-02-5K -d10M -s[1000] -c[8] -o $QPID_WORK/results -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=false pubsub=false transacted=false commitBatchSize=10 batchSize=1000 messageSize=5120 destinationCount=1 rate=0 maxPending=20000000 + -n TQM-Qpid-01-10K -d10M -s[1000] -c[8] -o $QPID_WORK/results -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=false pubsub=false transacted=true commitBatchSize=10 batchSize=1000 messageSize=10240 destinationCount=1 rate=0 maxPending=20000000 + -n TQM-Qpid-02-10K -d10M -s[1000] -c[8] -o $QPID_WORK/results -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=false pubsub=false transacted=false commitBatchSize=10 batchSize=1000 messageSize=10240 destinationCount=1 rate=0 maxPending=20000000 + -n TQM-Qpid-01-50K -d10M -s[1000] -c[8] -o $QPID_WORK/results -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=false pubsub=false transacted=true commitBatchSize=10 batchSize=1000 messageSize=51200 destinationCount=1 rate=0 maxPending=20000000 + -n TQM-Qpid-02-50K -d10M -s[1000] -c[8] -o $QPID_WORK/results -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=false pubsub=false transacted=false commitBatchSize=10 batchSize=1000 messageSize=51200 destinationCount=1 rate=0 maxPending=20000000 + -n TQM-Qpid-01-100K -d10M -s[1000] -c[8] -o $QPID_WORK/results -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=false pubsub=false transacted=true commitBatchSize=10 batchSize=1000 messageSize=102400 destinationCount=1 rate=0 maxPending=20000000 + -n TQM-Qpid-02-100K -d10M -s[1000] -c[8] -o $QPID_WORK/results -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=false pubsub=false transacted=false commitBatchSize=10 batchSize=1000 messageSize=102400 destinationCount=1 rate=0 maxPending=20000000 + -n TQM-Qpid-01-500K -d10M -s[1000] -c[8] -o $QPID_WORK/results -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=false pubsub=false transacted=true commitBatchSize=10 batchSize=1000 messageSize=512000 destinationCount=1 rate=0 maxPending=20000000 + -n TQM-Qpid-02-500K -d10M -s[1000] -c[8] -o $QPID_WORK/results -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=false pubsub=false transacted=false commitBatchSize=10 batchSize=1000 messageSize=512000 destinationCount=1 rate=0 maxPending=20000000 + -n TQM-Qpid-01-1M -d10M -s[1000] -c[8] -o $QPID_WORK/results -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=false pubsub=false transacted=true commitBatchSize=10 batchSize=1000 messageSize=1048576 destinationCount=1 rate=0 maxPending=20000000 + -n TQM-Qpid-02-1M -d10M -s[1000] -c[8] -o $QPID_WORK/results -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=false pubsub=false transacted=false commitBatchSize=10 batchSize=1000 messageSize=1048576 destinationCount=1 rate=0 maxPending=20000000 - -n TTR-Qpid-01 -d10M -s[1000] -c[8] -o $QPID_WORK/results -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=false pubsub=true transacted=true commitBatchSize=100 batchSize=1000 messageSize=256 destinationsCount=1 rate=0 maxPending=1000000 - -n TTR-Qpid-02 -d10M -s[1000] -c[8] -o $QPID_WORK/results -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=false pubsub=true transacted=false commitBatchSize=100 batchSize=1000 messageSize=256 destinationsCount=1 rate=0 maxPending=1000000 - -n TTR-Qpid-03 -d24H -s[100000] -c[8] -o $QPID_WORK/results -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=false pubsub=true transacted=true commitBatchSize=100 batchSize=10000 messageSize=256 destinationsCount=1 rate=0 maxPending=1000000 - -n TTR-Qpid-04 -d24H -s[100000] -c[8] -o $QPID_WORK/results -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=false pubsub=true transacted=false commitBatchSize=100 batchSize=10000 messageSize=256 destinationsCount=1 rate=0 maxPending=1000000 - - -n TTC-Qpid-01 -d1M -s[1000] -c[1,30],samples=30 -o $QPID_WORK/results -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=false pubsub=true transacted=true commitBatchSize=100 batchSize=1000 messageSize=256 destinationsCount=1 rate=1000 maxPending=1000000 - -n TTC-Qpid-02 -d1M -s[1000] -c[1,30],samples=30 -o $QPID_WORK/results -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=false pubsub=true transacted=false commitBatchSize=100 batchSize=1000 messageSize=256 destinationsCount=1 rate=1000 maxPending=1000000 - -n TTC-Qpid-03 -d10M -s[1000] -c[10] -o $QPID_WORK/results -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=false pubsub=true transacted=true commitBatchSize=100 batchSize=1000 messageSize=256 destinationsCount=10 rate=0 maxPending=1000000 - -n TTC-Qpid-04 -d10M -s[1000] -c[10] -o $QPID_WORK/results -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=false pubsub=true transacted=false commitBatchSize=100 batchSize=1000 messageSize=256 destinationsCount=10 rate=0 maxPending=1000000 - -n TTC-Qpid-05 -d10M -s[1000] -c[100] -o $QPID_WORK/results -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=false pubsub=true transacted=true commitBatchSize=100 batchSize=1000 messageSize=256 destinationsCount=10 rate=0 maxPending=100000 - -n TTC-Qpid-06 -d10M -s[1000] -c[100] -o $QPID_WORK/results -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=false pubsub=true transacted=false commitBatchSize=100 batchSize=1000 messageSize=256 destinationsCount=10 rate=0 maxPending=100000 - - -n TTM-Qpid-01-512b -d10M -s[1000] -c[1] -o $QPID_WORK/results -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=false pubsub=true transacted=true commitBatchSize=10 batchSize=1000 messageSize=512 destinationsCount=1 rate=0 maxPending=20000000 - -n TTM-Qpid-02-512b -d10M -s[1000] -c[1] -o $QPID_WORK/results -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=false pubsub=true transacted=false commitBatchSize=10 batchSize=1000 messageSize=512 destinationsCount=1 rate=0 maxPending=20000000 - -n TTM-Qpid-01-1K -d10M -s[1000] -c[1] -o $QPID_WORK/results -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=false pubsub=true transacted=true commitBatchSize=10 batchSize=1000 messageSize=1024 destinationsCount=1 rate=0 maxPending=20000000 - -n TTM-Qpid-02-1K -d10M -s[1000] -c[1] -o $QPID_WORK/results -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=false pubsub=true transacted=false commitBatchSize=10 batchSize=1000 messageSize=1024 destinationsCount=1 rate=0 maxPending=20000000 - -n TTM-Qpid-01-5K -d10M -s[1000] -c[1] -o $QPID_WORK/results -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=false pubsub=true transacted=true commitBatchSize=10 batchSize=1000 messageSize=5120 destinationsCount=1 rate=0 maxPending=20000000 - -n TTM-Qpid-02-5K -d10M -s[1000] -c[1] -o $QPID_WORK/results -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=false pubsub=true transacted=false commitBatchSize=10 batchSize=1000 messageSize=5120 destinationsCount=1 rate=0 maxPending=20000000 - -n TTM-Qpid-01-10K -d10M -s[1000] -c[1] -o $QPID_WORK/results -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=false pubsub=true transacted=true commitBatchSize=10 batchSize=1000 messageSize=10240 destinationsCount=1 rate=0 maxPending=20000000 - -n TTM-Qpid-02-10K -d10M -s[1000] -c[1] -o $QPID_WORK/results -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=false pubsub=true transacted=false commitBatchSize=10 batchSize=1000 messageSize=10240 destinationsCount=1 rate=0 maxPending=20000000 - -n TTM-Qpid-01-50K -d10M -s[1000] -c[1] -o $QPID_WORK/results -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=false pubsub=true transacted=true commitBatchSize=10 batchSize=1000 messageSize=51200 destinationsCount=1 rate=0 maxPending=20000000 - -n TTM-Qpid-02-50K -d10M -s[1000] -c[1] -o $QPID_WORK/results -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=false pubsub=true transacted=false commitBatchSize=10 batchSize=1000 messageSize=51200 destinationsCount=1 rate=0 maxPending=20000000 - -n TTM-Qpid-01-100K -d10M -s[1000] -c[1] -o $QPID_WORK/results -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=false pubsub=true transacted=true commitBatchSize=10 batchSize=1000 messageSize=102400 destinationsCount=1 rate=0 maxPending=20000000 - -n TTM-Qpid-02-100K -d10M -s[1000] -c[1] -o $QPID_WORK/results -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=false pubsub=true transacted=false commitBatchSize=10 batchSize=1000 messageSize=102400 destinationsCount=1 rate=0 maxPending=20000000 - -n TTM-Qpid-01-500K -d10M -s[1000] -c[1] -o $QPID_WORK/results -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=false pubsub=true transacted=true commitBatchSize=10 batchSize=1000 messageSize=512000 destinationsCount=1 rate=0 maxPending=20000000 - -n TTM-Qpid-02-500K -d10M -s[1000] -c[1] -o $QPID_WORK/results -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=false pubsub=true transacted=false commitBatchSize=10 batchSize=1000 messageSize=512000 destinationsCount=1 rate=0 maxPending=20000000 - -n TTM-Qpid-01-1M -d10M -s[1000] -c[1] -o $QPID_WORK/results -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=false pubsub=true transacted=true commitBatchSize=10 batchSize=1000 messageSize=1048576 destinationsCount=1 rate=0 maxPending=20000000 - -n TTM-Qpid-02-1M -d10M -s[1000] -c[1] -o $QPID_WORK/results -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=false pubsub=true transacted=false commitBatchSize=10 batchSize=1000 messageSize=1048476 destinationsCount=1 rate=0 maxPending=20000000 + -n TTR-Qpid-01 -d10M -s[1000] -c[8] -o $QPID_WORK/results -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=false pubsub=true transacted=true commitBatchSize=100 batchSize=1000 messageSize=256 destinationCount=1 rate=0 maxPending=1000000 + -n TTR-Qpid-02 -d10M -s[1000] -c[8] -o $QPID_WORK/results -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=false pubsub=true transacted=false commitBatchSize=100 batchSize=1000 messageSize=256 destinationCount=1 rate=0 maxPending=1000000 + -n TTR-Qpid-03 -d24H -s[100000] -c[8] -o $QPID_WORK/results -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=false pubsub=true transacted=true commitBatchSize=100 batchSize=10000 messageSize=256 destinationCount=1 rate=0 maxPending=1000000 + -n TTR-Qpid-04 -d24H -s[100000] -c[8] -o $QPID_WORK/results -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=false pubsub=true transacted=false commitBatchSize=100 batchSize=10000 messageSize=256 destinationCount=1 rate=0 maxPending=1000000 + + -n TTC-Qpid-01 -d1M -s[1000] -c[1,30],samples=30 -o $QPID_WORK/results -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=false pubsub=true transacted=true commitBatchSize=100 batchSize=1000 messageSize=256 destinationCount=1 rate=2000 maxPending=1000000 + -n TTC-Qpid-02 -d1M -s[1000] -c[1,30],samples=30 -o $QPID_WORK/results -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=false pubsub=true transacted=false commitBatchSize=100 batchSize=1000 messageSize=256 destinationCount=1 rate=2000 maxPending=1000000 + -n TTC-Qpid-03 -d10M -s[1000] -c[10] -o $QPID_WORK/results -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=false pubsub=true transacted=true commitBatchSize=100 batchSize=1000 messageSize=256 destinationCount=10 rate=0 maxPending=1000000 + -n TTC-Qpid-04 -d10M -s[1000] -c[10] -o $QPID_WORK/results -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=false pubsub=true transacted=false commitBatchSize=100 batchSize=1000 messageSize=256 destinationCount=10 rate=0 maxPending=1000000 + -n TTC-Qpid-05 -d10M -s[1000] -c[100] -o $QPID_WORK/results -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=false pubsub=true transacted=true commitBatchSize=100 batchSize=1000 messageSize=256 destinationCount=10 rate=0 maxPending=100000 + -n TTC-Qpid-06 -d10M -s[1000] -c[100] -o $QPID_WORK/results -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=false pubsub=true transacted=false commitBatchSize=100 batchSize=1000 messageSize=256 destinationCount=10 rate=0 maxPending=100000 + + -n TTM-Qpid-01-512b -d10M -s[1000] -c[8] -o $QPID_WORK/results -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=false pubsub=true transacted=true commitBatchSize=10 batchSize=1000 messageSize=512 destinationCount=1 rate=0 maxPending=20000000 + -n TTM-Qpid-02-512b -d10M -s[1000] -c[8] -o $QPID_WORK/results -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=false pubsub=true transacted=false commitBatchSize=10 batchSize=1000 messageSize=512 destinationCount=1 rate=0 maxPending=20000000 + -n TTM-Qpid-01-1K -d10M -s[1000] -c[8] -o $QPID_WORK/results -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=false pubsub=true transacted=true commitBatchSize=10 batchSize=1000 messageSize=1024 destinationCount=1 rate=0 maxPending=20000000 + -n TTM-Qpid-02-1K -d10M -s[1000] -c[8] -o $QPID_WORK/results -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=false pubsub=true transacted=false commitBatchSize=10 batchSize=1000 messageSize=1024 destinationCount=1 rate=0 maxPending=20000000 + -n TTM-Qpid-01-5K -d10M -s[1000] -c[8] -o $QPID_WORK/results -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=false pubsub=true transacted=true commitBatchSize=10 batchSize=1000 messageSize=5120 destinationCount=1 rate=0 maxPending=20000000 + -n TTM-Qpid-02-5K -d10M -s[1000] -c[8] -o $QPID_WORK/results -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=false pubsub=true transacted=false commitBatchSize=10 batchSize=1000 messageSize=5120 destinationCount=1 rate=0 maxPending=20000000 + -n TTM-Qpid-01-10K -d10M -s[1000] -c[8] -o $QPID_WORK/results -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=false pubsub=true transacted=true commitBatchSize=10 batchSize=1000 messageSize=10240 destinationCount=1 rate=0 maxPending=20000000 + -n TTM-Qpid-02-10K -d10M -s[1000] -c[8] -o $QPID_WORK/results -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=false pubsub=true transacted=false commitBatchSize=10 batchSize=1000 messageSize=10240 destinationCount=1 rate=0 maxPending=20000000 + -n TTM-Qpid-01-50K -d10M -s[1000] -c[8] -o $QPID_WORK/results -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=false pubsub=true transacted=true commitBatchSize=10 batchSize=1000 messageSize=51200 destinationCount=1 rate=0 maxPending=20000000 + -n TTM-Qpid-02-50K -d10M -s[1000] -c[8] -o $QPID_WORK/results -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=false pubsub=true transacted=false commitBatchSize=10 batchSize=1000 messageSize=51200 destinationCount=1 rate=0 maxPending=20000000 + -n TTM-Qpid-01-100K -d10M -s[1000] -c[8] -o $QPID_WORK/results -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=false pubsub=true transacted=true commitBatchSize=10 batchSize=1000 messageSize=102400 destinationCount=1 rate=0 maxPending=20000000 + -n TTM-Qpid-02-100K -d10M -s[1000] -c[8] -o $QPID_WORK/results -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=false pubsub=true transacted=false commitBatchSize=10 batchSize=1000 messageSize=102400 destinationCount=1 rate=0 maxPending=20000000 + -n TTM-Qpid-01-500K -d10M -s[1000] -c[8] -o $QPID_WORK/results -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=false pubsub=true transacted=true commitBatchSize=10 batchSize=1000 messageSize=512000 destinationCount=1 rate=0 maxPending=20000000 + -n TTM-Qpid-02-500K -d10M -s[1000] -c[8] -o $QPID_WORK/results -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=false pubsub=true transacted=false commitBatchSize=10 batchSize=1000 messageSize=512000 destinationCount=1 rate=0 maxPending=20000000 + -n TTM-Qpid-01-1M -d10M -s[1000] -c[8] -o $QPID_WORK/results -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=false pubsub=true transacted=true commitBatchSize=10 batchSize=1000 messageSize=1048576 destinationCount=1 rate=0 maxPending=20000000 + -n TTM-Qpid-02-1M -d10M -s[1000] -c[8] -o $QPID_WORK/results -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=false pubsub=true transacted=false commitBatchSize=10 batchSize=1000 messageSize=1048476 destinationCount=1 rate=0 maxPending=20000000 - -n PQR-Qpid-01 -d10M -s[1000] -c[8] -o $QPID_WORK/results -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=true pubsub=false transacted=true commitBatchSize=100 batchSize=1000 messageSize=256 destinationsCount=1 rate=0 maxPending=1000000 - -n PQR-Qpid-02 -d10M -s[1000] -c[8] -o $QPID_WORK/results -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=true pubsub=false transacted=false commitBatchSize=100 batchSize=1000 messageSize=256 destinationsCount=1 rate=0 maxPending=1000000 - -n PQR-Qpid-03 -d24H -s[100000] -c[8] -o $QPID_WORK/results -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=true pubsub=false transacted=true commitBatchSize=100 batchSize=100000 messageSize=256 destinationsCount=1 rate=0 maxPending=1000000 - -n PQR-Qpid-04 -d24H -s[100000] -c[8] -o $QPID_WORK/results -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=true pubsub=false transacted=false commitBatchSize=100 batchSize=100000 messageSize=256 destinationsCount=1 rate=0 maxPending=1000000 - - -n PQC-Qpid-01 -d1M -s[100] -c[1,30],samples=30 -o $QPID_WORK/results -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=true pubsub=false transacted=true commitBatchSize=100 batchSize=1000 messageSize=256 destinationsCount=1 rate=300 maxPending=1000000 - -n PQC-Qpid-02 -d1M -s[100] -c[1,30],samples=30 -o $QPID_WORK/results -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=true pubsub=false transacted=false commitBatchSize=100 batchSize=1000 messageSize=256 destinationsCount=1 rate=100 maxPending=1000000 - -n PQC-Qpid-03 -d10M -s[1000] -c[10] -o $QPID_WORK/results -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=true pubsub=false transacted=true commitBatchSize=100 batchSize=100 messageSize=256 destinationsCount=10 rate=0 maxPending=1000000 - -n PQC-Qpid-04 -d10M -s[1000] -c[10] -o $QPID_WORK/results -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=true pubsub=false transacted=false commitBatchSize=100 batchSize=1000 messageSize=256 destinationsCount=10 rate=0 maxPending=1000000 - -n PQC-Qpid-05 -d10M -s[1000] -c[100] -o $QPID_WORK/results -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=true pubsub=false transacted=true commitBatchSize=100 batchSize=1000 messageSize=256 destinationsCount=10 rate=0 maxPending=100000 - -n PQC-Qpid-06 -d10M -s[1000] -c[100] -o $QPID_WORK/results -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=true pubsub=false transacted=false commitBatchSize=100 batchSize=1000 messageSize=256 destinationsCount=10 rate=0 maxPending=100000 - - -n PQM-Qpid-01-512b -d10M -s[1000] -c[1] -o $QPID_WORK/results -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=true pubsub=false transacted=true commitBatchSize=10 batchSize=1000 messageSize=512 destinationsCount=1 rate=0 maxPending=20000000 - -n PQM-Qpid-02-512b -d10M -s[1000] -c[1] -o $QPID_WORK/results -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=true pubsub=false transacted=false commitBatchSize=10 batchSize=1000 messageSize=512 destinationsCount=1 rate=0 maxPending=20000000 - -n PQM-Qpid-01-1K -d10M -s[1000] -c[1] -o $QPID_WORK/results -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=true pubsub=false transacted=true commitBatchSize=10 batchSize=1000 messageSize=1024 destinationsCount=1 rate=0 maxPending=20000000 - -n PQM-Qpid-02-1K -d10M -s[1000] -c[1] -o $QPID_WORK/results -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=true pubsub=false transacted=false commitBatchSize=10 batchSize=1000 messageSize=1024 destinationsCount=1 rate=0 maxPending=20000000 - -n PQM-Qpid-01-5K -d10M -s[1000] -c[1] -o $QPID_WORK/results -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=true pubsub=false transacted=true commitBatchSize=10 batchSize=1000 messageSize=5120 destinationsCount=1 rate=0 maxPending=20000000 - -n PQM-Qpid-02-5K -d10M -s[1000] -c[1] -o $QPID_WORK/results -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=true pubsub=false transacted=false commitBatchSize=10 batchSize=1000 messageSize=5120 destinationsCount=1 rate=0 maxPending=20000000 - -n PQM-Qpid-01-10K -d10M -s[1000] -c[1] -o $QPID_WORK/results -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=true pubsub=false transacted=true commitBatchSize=10 batchSize=1000 messageSize=10240 destinationsCount=1 rate=0 maxPending=20000000 - -n PQM-Qpid-02-10K -d10M -s[1000] -c[1] -o $QPID_WORK/results -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=true pubsub=false transacted=false commitBatchSize=10 batchSize=1000 messageSize=10240 destinationsCount=1 rate=0 maxPending=20000000 - -n PQM-Qpid-01-50K -d10M -s[1000] -c[1] -o $QPID_WORK/results -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=true pubsub=false transacted=true commitBatchSize=10 batchSize=1000 messageSize=51200 destinationsCount=1 rate=0 maxPending=20000000 - -n PQM-Qpid-02-50K -d10M -s[1000] -c[1] -o $QPID_WORK/results -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=true pubsub=false transacted=false commitBatchSize=10 batchSize=1000 messageSize=51200 destinationsCount=1 rate=0 maxPending=20000000 - -n PQM-Qpid-01-100K -d10M -s[1000] -c[1] -o $QPID_WORK/results -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=true pubsub=false transacted=true commitBatchSize=10 batchSize=1000 messageSize=102400 destinationsCount=1 rate=0 maxPending=20000000 - -n PQM-Qpid-02-100K -d10M -s[1000] -c[1] -o $QPID_WORK/results -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=true pubsub=false transacted=false commitBatchSize=10 batchSize=1000 messageSize=102400 destinationsCount=1 rate=0 maxPending=20000000 - -n PQM-Qpid-01-500K -d10M -s[1000] -c[1] -o $QPID_WORK/results -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=true pubsub=false transacted=true commitBatchSize=10 batchSize=1000 messageSize=512000 destinationsCount=1 rate=0 maxPending=20000000 - -n PQM-Qpid-02-500K -d10M -s[1000] -c[1] -o $QPID_WORK/results -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=true pubsub=false transacted=false commitBatchSize=10 batchSize=1000 messageSize=512000 destinationsCount=1 rate=0 maxPending=20000000 - -n PQM-Qpid-01-1M -d10M -s[1000] -c[1] -o $QPID_WORK/results -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=true pubsub=false transacted=true commitBatchSize=10 batchSize=1000 messageSize=1048576 destinationsCount=1 rate=0 maxPending=20000000 - -n PQM-Qpid-02-1M -d10M -s[1000] -c[1] -o $QPID_WORK/results -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=true pubsub=false transacted=false commitBatchSize=10 batchSize=1000 messageSize=1048576 destinationsCount=1 rate=0 maxPending=20000000 + -n PQR-Qpid-01 -d10M -s[1000] -c[8] -o $QPID_WORK/results -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=true pubsub=false transacted=true commitBatchSize=100 batchSize=1000 messageSize=256 destinationCount=1 rate=0 maxPending=1000000 + -n PQR-Qpid-02 -d10M -s[1000] -c[8] -o $QPID_WORK/results -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=true pubsub=false transacted=false commitBatchSize=100 batchSize=1000 messageSize=256 destinationCount=1 rate=0 maxPending=1000000 + -n PQR-Qpid-03 -d24H -s[100000] -c[8] -o $QPID_WORK/results -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=true pubsub=false transacted=true commitBatchSize=100 batchSize=100000 messageSize=256 destinationCount=1 rate=0 maxPending=1000000 + -n PQR-Qpid-04 -d24H -s[100000] -c[8] -o $QPID_WORK/results -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=true pubsub=false transacted=false commitBatchSize=100 batchSize=100000 messageSize=256 destinationCount=1 rate=0 maxPending=1000000 + + -n PQC-Qpid-01 -d1M -s[100] -c[1,30],samples=30 -o $QPID_WORK/results -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=true pubsub=false transacted=true commitBatchSize=100 batchSize=1000 messageSize=256 destinationCount=1 rate=600 maxPending=1000000 + -n PQC-Qpid-02 -d1M -s[100] -c[1,30],samples=30 -o $QPID_WORK/results -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=true pubsub=false transacted=false commitBatchSize=100 batchSize=1000 messageSize=256 destinationCount=1 rate=100 maxPending=1000000 + -n PQC-Qpid-03 -d10M -s[1000] -c[10] -o $QPID_WORK/results -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=true pubsub=false transacted=true commitBatchSize=100 batchSize=100 messageSize=256 destinationCount=10 rate=0 maxPending=1000000 + -n PQC-Qpid-04 -d10M -s[1000] -c[10] -o $QPID_WORK/results -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=true pubsub=false transacted=false commitBatchSize=100 batchSize=1000 messageSize=256 destinationCount=10 rate=0 maxPending=1000000 + -n PQC-Qpid-05 -d10M -s[1000] -c[100] -o $QPID_WORK/results -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=true pubsub=false transacted=true commitBatchSize=100 batchSize=1000 messageSize=256 destinationCount=10 rate=0 maxPending=100000 + -n PQC-Qpid-06 -d10M -s[1000] -c[100] -o $QPID_WORK/results -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=true pubsub=false transacted=false commitBatchSize=100 batchSize=1000 messageSize=256 destinationCount=10 rate=0 maxPending=100000 + + -n PQM-Qpid-01-512b -d10M -s[1000] -c[8] -o $QPID_WORK/results -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=true pubsub=false transacted=true commitBatchSize=10 batchSize=1000 messageSize=512 destinationCount=1 rate=0 maxPending=20000000 + -n PQM-Qpid-02-512b -d10M -s[1000] -c[8] -o $QPID_WORK/results -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=true pubsub=false transacted=false commitBatchSize=10 batchSize=1000 messageSize=512 destinationCount=1 rate=0 maxPending=20000000 + -n PQM-Qpid-01-1K -d10M -s[1000] -c[8] -o $QPID_WORK/results -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=true pubsub=false transacted=true commitBatchSize=10 batchSize=1000 messageSize=1024 destinationCount=1 rate=0 maxPending=20000000 + -n PQM-Qpid-02-1K -d10M -s[1000] -c[8] -o $QPID_WORK/results -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=true pubsub=false transacted=false commitBatchSize=10 batchSize=1000 messageSize=1024 destinationCount=1 rate=0 maxPending=20000000 + -n PQM-Qpid-01-5K -d10M -s[1000] -c[8] -o $QPID_WORK/results -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=true pubsub=false transacted=true commitBatchSize=10 batchSize=1000 messageSize=5120 destinationCount=1 rate=0 maxPending=20000000 + -n PQM-Qpid-02-5K -d10M -s[1000] -c[8] -o $QPID_WORK/results -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=true pubsub=false transacted=false commitBatchSize=10 batchSize=1000 messageSize=5120 destinationCount=1 rate=0 maxPending=20000000 + -n PQM-Qpid-01-10K -d10M -s[1000] -c[8] -o $QPID_WORK/results -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=true pubsub=false transacted=true commitBatchSize=10 batchSize=1000 messageSize=10240 destinationCount=1 rate=0 maxPending=20000000 + -n PQM-Qpid-02-10K -d10M -s[1000] -c[8] -o $QPID_WORK/results -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=true pubsub=false transacted=false commitBatchSize=10 batchSize=1000 messageSize=10240 destinationCount=1 rate=0 maxPending=20000000 + -n PQM-Qpid-01-50K -d10M -s[1000] -c[8] -o $QPID_WORK/results -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=true pubsub=false transacted=true commitBatchSize=10 batchSize=1000 messageSize=51200 destinationCount=1 rate=0 maxPending=20000000 + -n PQM-Qpid-02-50K -d10M -s[1000] -c[8] -o $QPID_WORK/results -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=true pubsub=false transacted=false commitBatchSize=10 batchSize=1000 messageSize=51200 destinationCount=1 rate=0 maxPending=20000000 + -n PQM-Qpid-01-100K -d10M -s[1000] -c[8] -o $QPID_WORK/results -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=true pubsub=false transacted=true commitBatchSize=10 batchSize=1000 messageSize=102400 destinationCount=1 rate=0 maxPending=20000000 + -n PQM-Qpid-02-100K -d10M -s[1000] -c[8] -o $QPID_WORK/results -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=true pubsub=false transacted=false commitBatchSize=10 batchSize=1000 messageSize=102400 destinationCount=1 rate=0 maxPending=20000000 + -n PQM-Qpid-01-500K -d10M -s[1000] -c[8] -o $QPID_WORK/results -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=true pubsub=false transacted=true commitBatchSize=10 batchSize=1000 messageSize=512000 destinationCount=1 rate=0 maxPending=20000000 + -n PQM-Qpid-02-500K -d10M -s[1000] -c[8] -o $QPID_WORK/results -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=true pubsub=false transacted=false commitBatchSize=10 batchSize=1000 messageSize=512000 destinationCount=1 rate=0 maxPending=20000000 + -n PQM-Qpid-01-1M -d10M -s[1000] -c[8] -o $QPID_WORK/results -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=true pubsub=false transacted=true commitBatchSize=10 batchSize=1000 messageSize=1048576 destinationCount=1 rate=0 maxPending=20000000 + -n PQM-Qpid-02-1M -d10M -s[1000] -c[8] -o $QPID_WORK/results -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=true pubsub=false transacted=false commitBatchSize=10 batchSize=1000 messageSize=1048576 destinationCount=1 rate=0 maxPending=20000000 - -n PTR-Qpid-01 -d10M -s[1000] -c[8] -o $QPID_WORK/results -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=true pubsub=true transacted=true commitBatchSize=100 batchSize=1000 messageSize=256 destinationsCount=1 rate=0 maxPending=1000000 - -n PTR-Qpid-02 -d10M -s[1000] -c[8] -o $QPID_WORK/results -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=true pubsub=true transacted=false commitBatchSize=100 batchSize=1000 messageSize=256 destinationsCount=1 rate=0 maxPending=1000000 - -n PTR-Qpid-03 -d24H -s[100000] -c[8] -o $QPID_WORK/results -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=true pubsub=true transacted=true commitBatchSize=100 batchSize=10000 messageSize=256 destinationsCount=1 rate=0 maxPending=1000000 - -n PTR-Qpid-04 -d24H -s[100000] -c[8] -o $QPID_WORK/results -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=true pubsub=true transacted=false commitBatchSize=100 batchSize=10000 messageSize=256 destinationsCount=1 rate=0 maxPending=1000000 - - -n PTC-Qpid-01 -d1M -s[100] -c[1,30],samples=30 -o $QPID_WORK/results -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=true pubsub=true transacted=true commitBatchSize=100 batchSize=1000 messageSize=256 destinationsCount=1 rate=300 maxPending=1000000 - -n PTC-Qpid-02 -d1M -s[100] -c[1,30],samples=30 -o $QPID_WORK/results -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=true pubsub=true transacted=false commitBatchSize=100 batchSize=1000 messageSize=256 destinationsCount=1 rate=100 maxPending=1000000 - -n PTC-Qpid-03 -d10M -s[1000] -c[10] -o $QPID_WORK/results -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=true pubsub=true transacted=true commitBatchSize=100 batchSize=1000 messageSize=256 destinationsCount=10 rate=0 maxPending=1000000 - -n PTC-Qpid-04 -d10M -s[1000] -c[10] -o $QPID_WORK/results -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=true pubsub=true transacted=false commitBatchSize=100 batchSize=1000 messageSize=256 destinationsCount=10 rate=0 maxPending=1000000 - -n PTC-Qpid-05 -d10M -s[1000] -c[100] -o $QPID_WORK/results -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=true pubsub=true transacted=true commitBatchSize=100 batchSize=1000 messageSize=256 destinationsCount=10 rate=0 maxPending=100000 - -n PTC-Qpid-06 -d10M -s[1000] -c[100] -o $QPID_WORK/results -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=true pubsub=true transacted=false commitBatchSize=100 batchSize=1000 messageSize=256 destinationsCount=10 rate=0 maxPending=100000 - - -n PTM-Qpid-01-512b -d10M -s[1000] -c[1] -o $QPID_WORK/results -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=true pubsub=true transacted=true commitBatchSize=10 batchSize=1000 messageSize=512 destinationsCount=1 rate=0 maxPending=20000000 - -n PTM-Qpid-02-512b -d10M -s[1000] -c[1] -o $QPID_WORK/results -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=true pubsub=true transacted=false commitBatchSize=10 batchSize=1000 messageSize=512 destinationsCount=1 rate=0 maxPending=20000000 - -n PTM-Qpid-01-1K -d10M -s[1000] -c[1] -o $QPID_WORK/results -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=true pubsub=true transacted=true commitBatchSize=10 batchSize=1000 messageSize=1024 destinationsCount=1 rate=0 maxPending=20000000 - -n PTM-Qpid-02-1K -d10M -s[1000] -c[1] -o $QPID_WORK/results -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=true pubsub=true transacted=false commitBatchSize=10 batchSize=1000 messageSize=1024 destinationsCount=1 rate=0 maxPending=20000000 - -n PTM-Qpid-01-5K -d10M -s[1000] -c[1] -o $QPID_WORK/results -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=true pubsub=true transacted=true commitBatchSize=10 batchSize=1000 messageSize=5120 destinationsCount=1 rate=0 maxPending=20000000 - -n PTM-Qpid-02-5K -d10M -s[1000] -c[1] -o $QPID_WORK/results -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=true pubsub=true transacted=false commitBatchSize=10 batchSize=1000 messageSize=5120 destinationsCount=1 rate=0 maxPending=20000000 - -n PTM-Qpid-01-10K -d10M -s[1000] -c[1] -o $QPID_WORK/results -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=true pubsub=true transacted=true commitBatchSize=10 batchSize=1000 messageSize=10240 destinationsCount=1 rate=0 maxPending=20000000 - -n PTM-Qpid-02-10K -d10M -s[1000] -c[1] -o $QPID_WORK/results -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=true pubsub=true transacted=false commitBatchSize=10 batchSize=1000 messageSize=10240 destinationsCount=1 rate=0 maxPending=20000000 - -n PTM-Qpid-01-50K -d10M -s[1000] -c[1] -o $QPID_WORK/results -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=true pubsub=true transacted=true commitBatchSize=10 batchSize=1000 messageSize=51200 destinationsCount=1 rate=0 maxPending=20000000 - -n PTM-Qpid-02-50K -d10M -s[1000] -c[1] -o $QPID_WORK/results -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=true pubsub=true transacted=false commitBatchSize=10 batchSize=1000 messageSize=51200 destinationsCount=1 rate=0 maxPending=20000000 - -n PTM-Qpid-01-100K -d10M -s[1000] -c[1] -o $QPID_WORK/results -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=true pubsub=true transacted=true commitBatchSize=10 batchSize=1000 messageSize=102400 destinationsCount=1 rate=0 maxPending=20000000 - -n PTM-Qpid-02-100K -d10M -s[1000] -c[1] -o $QPID_WORK/results -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=true pubsub=true transacted=false commitBatchSize=10 batchSize=1000 messageSize=102400 destinationsCount=1 rate=0 maxPending=20000000 - -n PTM-Qpid-01-500K -d10M -s[1000] -c[1] -o $QPID_WORK/results -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=true pubsub=true transacted=true commitBatchSize=10 batchSize=1000 messageSize=512000 destinationsCount=1 rate=0 maxPending=20000000 - -n PTM-Qpid-02-500K -d10M -s[1000] -c[1] -o $QPID_WORK/results -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=true pubsub=true transacted=false commitBatchSize=10 batchSize=1000 messageSize=512000 destinationsCount=1 rate=0 maxPending=20000000 - -n PTM-Qpid-01-1M -d10M -s[1000] -c[1] -o $QPID_WORK/results -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=true pubsub=true transacted=true commitBatchSize=10 batchSize=1000 messageSize=1048576 destinationsCount=1 rate=0 maxPending=20000000 - -n PTM-Qpid-02-1M -d10M -s[1000] -c[1] -o $QPID_WORK/results -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=true pubsub=true transacted=false commitBatchSize=10 batchSize=1000 messageSize=1048476 destinationsCount=1 rate=0 maxPending=20000000 + -n PTR-Qpid-01 -d10M -s[1000] -c[8] -o $QPID_WORK/results -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=true pubsub=true transacted=true commitBatchSize=100 batchSize=1000 messageSize=256 destinationCount=1 rate=0 maxPending=1000000 + -n PTR-Qpid-02 -d10M -s[1000] -c[8] -o $QPID_WORK/results -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=true pubsub=true transacted=false commitBatchSize=100 batchSize=1000 messageSize=256 destinationCount=1 rate=0 maxPending=1000000 + -n PTR-Qpid-03 -d24H -s[100000] -c[8] -o $QPID_WORK/results -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=true pubsub=true transacted=true commitBatchSize=100 batchSize=10000 messageSize=256 destinationCount=1 rate=0 maxPending=1000000 + -n PTR-Qpid-04 -d24H -s[100000] -c[8] -o $QPID_WORK/results -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=true pubsub=true transacted=false commitBatchSize=100 batchSize=10000 messageSize=256 destinationCount=1 rate=0 maxPending=1000000 + + -n PTC-Qpid-01 -d1M -s[100] -c[1,30],samples=30 -o $QPID_WORK/results -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=true pubsub=true transacted=true commitBatchSize=100 batchSize=1000 messageSize=256 destinationCount=1 rate=600 maxPending=1000000 + -n PTC-Qpid-02 -d1M -s[100] -c[1,30],samples=30 -o $QPID_WORK/results -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=true pubsub=true transacted=false commitBatchSize=100 batchSize=1000 messageSize=256 destinationCount=1 rate=100 maxPending=1000000 + -n PTC-Qpid-03 -d10M -s[1000] -c[10] -o $QPID_WORK/results -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=true pubsub=true transacted=true commitBatchSize=100 batchSize=1000 messageSize=256 destinationCount=10 rate=0 maxPending=1000000 + -n PTC-Qpid-04 -d10M -s[1000] -c[10] -o $QPID_WORK/results -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=true pubsub=true transacted=false commitBatchSize=100 batchSize=1000 messageSize=256 destinationCount=10 rate=0 maxPending=1000000 + -n PTC-Qpid-05 -d10M -s[1000] -c[100] -o $QPID_WORK/results -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=true pubsub=true transacted=true commitBatchSize=100 batchSize=1000 messageSize=256 destinationCount=10 rate=0 maxPending=100000 + -n PTC-Qpid-06 -d10M -s[1000] -c[100] -o $QPID_WORK/results -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=true pubsub=true transacted=false commitBatchSize=100 batchSize=1000 messageSize=256 destinationCount=10 rate=0 maxPending=100000 + + -n PTM-Qpid-01-512b -d10M -s[1000] -c[8] -o $QPID_WORK/results -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=true pubsub=true transacted=true commitBatchSize=10 batchSize=1000 messageSize=512 destinationCount=1 rate=0 maxPending=20000000 + -n PTM-Qpid-02-512b -d10M -s[1000] -c[8] -o $QPID_WORK/results -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=true pubsub=true transacted=false commitBatchSize=10 batchSize=1000 messageSize=512 destinationCount=1 rate=0 maxPending=20000000 + -n PTM-Qpid-01-1K -d10M -s[1000] -c[8] -o $QPID_WORK/results -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=true pubsub=true transacted=true commitBatchSize=10 batchSize=1000 messageSize=1024 destinationCount=1 rate=0 maxPending=20000000 + -n PTM-Qpid-02-1K -d10M -s[1000] -c[8] -o $QPID_WORK/results -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=true pubsub=true transacted=false commitBatchSize=10 batchSize=1000 messageSize=1024 destinationCount=1 rate=0 maxPending=20000000 + -n PTM-Qpid-01-5K -d10M -s[1000] -c[8] -o $QPID_WORK/results -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=true pubsub=true transacted=true commitBatchSize=10 batchSize=1000 messageSize=5120 destinationCount=1 rate=0 maxPending=20000000 + -n PTM-Qpid-02-5K -d10M -s[1000] -c[8] -o $QPID_WORK/results -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=true pubsub=true transacted=false commitBatchSize=10 batchSize=1000 messageSize=5120 destinationCount=1 rate=0 maxPending=20000000 + -n PTM-Qpid-01-10K -d10M -s[1000] -c[8] -o $QPID_WORK/results -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=true pubsub=true transacted=true commitBatchSize=10 batchSize=1000 messageSize=10240 destinationCount=1 rate=0 maxPending=20000000 + -n PTM-Qpid-02-10K -d10M -s[1000] -c[8] -o $QPID_WORK/results -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=true pubsub=true transacted=false commitBatchSize=10 batchSize=1000 messageSize=10240 destinationCount=1 rate=0 maxPending=20000000 + -n PTM-Qpid-01-50K -d10M -s[1000] -c[8] -o $QPID_WORK/results -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=true pubsub=true transacted=true commitBatchSize=10 batchSize=1000 messageSize=51200 destinationCount=1 rate=0 maxPending=20000000 + -n PTM-Qpid-02-50K -d10M -s[1000] -c[8] -o $QPID_WORK/results -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=true pubsub=true transacted=false commitBatchSize=10 batchSize=1000 messageSize=51200 destinationCount=1 rate=0 maxPending=20000000 + -n PTM-Qpid-01-100K -d10M -s[1000] -c[8] -o $QPID_WORK/results -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=true pubsub=true transacted=true commitBatchSize=10 batchSize=1000 messageSize=102400 destinationCount=1 rate=0 maxPending=20000000 + -n PTM-Qpid-02-100K -d10M -s[1000] -c[8] -o $QPID_WORK/results -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=true pubsub=true transacted=false commitBatchSize=10 batchSize=1000 messageSize=102400 destinationCount=1 rate=0 maxPending=20000000 + -n PTM-Qpid-01-500K -d10M -s[1000] -c[8] -o $QPID_WORK/results -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=true pubsub=true transacted=true commitBatchSize=10 batchSize=1000 messageSize=512000 destinationCount=1 rate=0 maxPending=20000000 + -n PTM-Qpid-02-500K -d10M -s[1000] -c[8] -o $QPID_WORK/results -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=true pubsub=true transacted=false commitBatchSize=10 batchSize=1000 messageSize=512000 destinationCount=1 rate=0 maxPending=20000000 + -n PTM-Qpid-01-1M -d10M -s[1000] -c[8] -o $QPID_WORK/results -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=true pubsub=true transacted=true commitBatchSize=10 batchSize=1000 messageSize=1048576 destinationCount=1 rate=0 maxPending=20000000 + -n PTM-Qpid-02-1M -d10M -s[1000] -c[8] -o $QPID_WORK/results -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=true pubsub=true transacted=false commitBatchSize=10 batchSize=1000 messageSize=1048476 destinationCount=1 rate=0 maxPending=20000000 -n FT-Qpid-01 -s[250000] -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf messageSize=256 batchSize=10000 transacted=true broker="tcp://127.0.0.1:5001;tcp://127.0.0.1:5002" failBeforeSend=true -o $QPID_WORK/results diff --git a/java/perftests/src/main/java/org/apache/qpid/client/message/TestMessageFactory.java b/java/perftests/src/main/java/org/apache/qpid/client/message/TestMessageFactory.java index eeb4021f34..64ccb719b6 100644 --- a/java/perftests/src/main/java/org/apache/qpid/client/message/TestMessageFactory.java +++ b/java/perftests/src/main/java/org/apache/qpid/client/message/TestMessageFactory.java @@ -1,18 +1,21 @@ /* * - * Copyright (c) 2006 The Apache Software Foundation + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * http://www.apache.org/licenses/LICENSE-2.0 * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. * */ package org.apache.qpid.client.message; diff --git a/java/perftests/src/main/java/org/apache/qpid/ping/PingDurableClient.java b/java/perftests/src/main/java/org/apache/qpid/ping/PingDurableClient.java index 2765986868..c5f71b4774 100644 --- a/java/perftests/src/main/java/org/apache/qpid/ping/PingDurableClient.java +++ b/java/perftests/src/main/java/org/apache/qpid/ping/PingDurableClient.java @@ -20,18 +20,6 @@ */ package org.apache.qpid.ping; -import java.io.BufferedReader; -import java.io.IOException; -import java.io.InputStreamReader; -import java.util.List; -import java.util.Properties; -import java.util.concurrent.atomic.AtomicInteger; - -import javax.jms.Destination; -import javax.jms.ExceptionListener; -import javax.jms.JMSException; -import javax.jms.Message; - import org.apache.log4j.Logger; import org.apache.qpid.requestreply.PingPongProducer; @@ -40,6 +28,18 @@ import org.apache.qpid.util.CommandLineParser; import uk.co.thebadgerset.junit.extensions.util.MathUtils; import uk.co.thebadgerset.junit.extensions.util.ParsedProperties; +import javax.jms.Destination; +import javax.jms.ExceptionListener; +import javax.jms.JMSException; +import javax.jms.Message; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStreamReader; +import java.util.List; +import java.util.Properties; +import java.util.concurrent.atomic.AtomicInteger; + /** * PingDurableClient is a variation of the {@link PingPongProducer} ping tool. Instead of sending its pings and * receiving replies to them at the same time, this tool sends pings until it is signalled by some 'event' to stop @@ -167,7 +167,8 @@ public class PingDurableClient extends PingPongProducer implements ExceptionList try { // Create a ping producer overriding its defaults with all options passed on the command line. - Properties options = CommandLineParser.processCommandLine(args, new CommandLineParser(new String[][] {})); + Properties options = + CommandLineParser.processCommandLine(args, new CommandLineParser(new String[][] {}), System.getProperties()); PingDurableClient pingProducer = new PingDurableClient(options); // Create a shutdown hook to terminate the ping-pong producer. diff --git a/java/perftests/src/main/java/org/apache/qpid/ping/PingSendOnlyClient.java b/java/perftests/src/main/java/org/apache/qpid/ping/PingSendOnlyClient.java index bbe337ca0a..2879f0c322 100644 --- a/java/perftests/src/main/java/org/apache/qpid/ping/PingSendOnlyClient.java +++ b/java/perftests/src/main/java/org/apache/qpid/ping/PingSendOnlyClient.java @@ -57,7 +57,7 @@ public class PingSendOnlyClient extends PingDurableClient try { // Create a ping producer overriding its defaults with all options passed on the command line. - Properties options = CommandLineParser.processCommandLine(args, new CommandLineParser(new String[][] {})); + Properties options = CommandLineParser.processCommandLine(args, new CommandLineParser(new String[][] {}), System.getProperties()); PingSendOnlyClient pingProducer = new PingSendOnlyClient(options); // Create a shutdown hook to terminate the ping-pong producer. diff --git a/java/perftests/src/main/java/org/apache/qpid/requestreply/PingPongProducer.java b/java/perftests/src/main/java/org/apache/qpid/requestreply/PingPongProducer.java index d5d1c304e9..03f5f0549d 100644 --- a/java/perftests/src/main/java/org/apache/qpid/requestreply/PingPongProducer.java +++ b/java/perftests/src/main/java/org/apache/qpid/requestreply/PingPongProducer.java @@ -20,20 +20,6 @@ */ package org.apache.qpid.requestreply; -import java.io.IOException; -import java.net.InetAddress; -import java.text.DateFormat; -import java.text.SimpleDateFormat; -import java.util.*; -import java.util.concurrent.BrokenBarrierException; -import java.util.concurrent.CountDownLatch; -import java.util.concurrent.CyclicBarrier; -import java.util.concurrent.TimeUnit; -import java.util.concurrent.atomic.AtomicInteger; -import java.util.concurrent.atomic.AtomicLong; - -import javax.jms.*; - import org.apache.log4j.Logger; import org.apache.qpid.AMQException; @@ -51,6 +37,18 @@ import uk.co.thebadgerset.junit.extensions.BatchedThrottle; import uk.co.thebadgerset.junit.extensions.Throttle; import uk.co.thebadgerset.junit.extensions.util.ParsedProperties; +import javax.jms.*; + +import java.io.IOException; +import java.net.InetAddress; +import java.text.DateFormat; +import java.text.SimpleDateFormat; +import java.util.*; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicInteger; +import java.util.concurrent.atomic.AtomicLong; + /** * PingPongProducer is a client that sends test messages, and waits for replies to these messages. The replies may * either be generated by another client (see {@link PingPongBouncer}, or an extension of it may be used that listens @@ -89,7 +87,7 @@ import uk.co.thebadgerset.junit.extensions.util.ParsedProperties; *

destinationCount 1 The number of receivers listening to the pings. *
timeout 30000 In milliseconds. The timeout to stop waiting for replies. *
commitBatchSize 1 The number of messages per transaction in transactional mode. - *
uniqueDests true Whether each receiver only listens to one ping destination or all. + *
uniqueDests true Whether each receivers only listens to one ping destination or all. *
durableDests false Whether or not durable destinations are used. *
ackMode AUTO_ACK The message acknowledgement mode. Possible values are: * 0 - SESSION_TRANSACTED @@ -237,7 +235,7 @@ public class PingPongProducer implements Runnable, MessageListener, ExceptionLis /** Holds the default message selector. */ public static final String SELECTOR_DEFAULT = ""; - /** Holds the name of the proeprty to get the destination count from. */ + /** Holds the name of the property to get the destination count from. */ public static final String DESTINATION_COUNT_PROPNAME = "destinationCount"; /** Defines the default number of destinations to ping. */ @@ -373,7 +371,7 @@ public class PingPongProducer implements Runnable, MessageListener, ExceptionLis protected int _maxPendingSize; /** - * Holds a monitor which is used to synchronize sender and receiver threads, where the sender has elected + * Holds a monitor which is used to synchronize sender and receivers threads, where the sender has elected * to wait until the number of unreceived message is reduced before continuing to send. */ protected Object _sendPauseMonitor = new Object(); @@ -570,7 +568,8 @@ public class PingPongProducer implements Runnable, MessageListener, ExceptionLis { try { - Properties options = CommandLineParser.processCommandLine(args, new CommandLineParser(new String[][] {})); + Properties options = + CommandLineParser.processCommandLine(args, new CommandLineParser(new String[][] {}), System.getProperties()); // Create a ping producer overriding its defaults with all options passed on the command line. PingPongProducer pingProducer = new PingPongProducer(options); diff --git a/java/pom.xml b/java/pom.xml index 87ed34846f..f6f719eb80 100644 --- a/java/pom.xml +++ b/java/pom.xml @@ -155,14 +155,26 @@ under the License. perftests integrationtests management/eclipse-plugin - client/example - client-java14 + client/example + client-java14 + + + META-INF/ + false + ../resources + + DISCLAIMER + LICENSE + NOTICE + + + src/main/java @@ -172,26 +184,28 @@ under the License. src/main/resources - - ** - src/main/resources-filtered - - ** - true target/generated/src/main/resources - - ** - + + META-INF/ + false + ../resources + + DISCLAIMER + LICENSE + NOTICE + + + src/test/java @@ -200,9 +214,6 @@ under the License. src/test/resources - - ** - src/test/java @@ -391,7 +402,19 @@ under the License. 0.5 - + + + + + + + + + + + install @@ -586,7 +606,6 @@ under the License. --> -