summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRobert Greig <rgreig@apache.org>2007-04-19 16:24:30 +0000
committerRobert Greig <rgreig@apache.org>2007-04-19 16:24:30 +0000
commitffe5e29f94b376c6f5900b2f9577c8bbaef7407b (patch)
treebb431cc6da73c5199fb391f66fddd831b047dce4
parentc40abb2580b2da657249b74a202d75eaee3362e2 (diff)
downloadqpid-python-ffe5e29f94b376c6f5900b2f9577c8bbaef7407b.tar.gz
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-521792,521794-522462,522464-522527,522529-522534,522536-522566,522568-522993,522995-523244,523246-525530,525532,525534,525537-526149,526151-526682,526686-526713,526715-530399 via svnmerge from
https://svn.apache.org/repos/asf/incubator/qpid/branches/M2 ........ r521682 | bhupendrab | 2007-03-23 11:50:55 +0000 (Fri, 23 Mar 2007) | 2 lines QPID-418 (merged from trunk) svn merge -r521336:521345 https://svn.apache.org/repos/asf/incubator/qpid/trunk/qpid/java . ........ r521705 | rgreig | 2007-03-23 12:44:14 +0000 (Fri, 23 Mar 2007) | 1 line Updates to performance tests. ........ r521710 | ritchiem | 2007-03-23 12:59:18 +0000 (Fri, 23 Mar 2007) | 2 lines QPID-419 Access Control QPID-423 Authentication per virtualhost Improved error handling when hostconfig is not specifed. Was NPE-ing ........ r521715 | ritchiem | 2007-03-23 13:10:33 +0000 (Fri, 23 Mar 2007) | 2 lines QPID-423 Authentication per virtualhost Improved error handling when hostconfig is not specifed. Was NPE-ing ........ r521782 | bhupendrab | 2007-03-23 16:02:51 +0000 (Fri, 23 Mar 2007) | 1 line QPID-420 (merged from trunk) And r518998:518999 and r520846:520850 ........ r522959 | ritchiem | 2007-03-27 16:39:51 +0100 (Tue, 27 Mar 2007) | 2 lines Updated assembly/bin.xml to include transient_config.xml persistent_config.xml ........ r522961 | ritchiem | 2007-03-27 16:42:40 +0100 (Tue, 27 Mar 2007) | 1 line forgot to rename files after they had been copied ........ r522967 | ritchiem | 2007-03-27 16:56:03 +0100 (Tue, 27 Mar 2007) | 1 line correctly renamed transient and persistent config files ........ r522977 | ritchiem | 2007-03-27 17:06:15 +0100 (Tue, 27 Mar 2007) | 1 line updated config files ........ r522981 | ritchiem | 2007-03-27 17:10:45 +0100 (Tue, 27 Mar 2007) | 1 line Added echo of progress and reduced timeout ........ r522989 | ritchiem | 2007-03-27 17:33:04 +0100 (Tue, 27 Mar 2007) | 1 line fixed error where script wouldn't pickup running pids ........ r522990 | ritchiem | 2007-03-27 17:36:34 +0100 (Tue, 27 Mar 2007) | 1 line Added additional logging and comments ........ r522991 | ritchiem | 2007-03-27 17:37:17 +0100 (Tue, 27 Mar 2007) | 1 line Added additional comments ........ r523747 | rajith | 2007-03-29 16:32:56 +0100 (Thu, 29 Mar 2007) | 1 line Fix for setting the message id ........ r524050 | rgreig | 2007-03-30 12:51:09 +0100 (Fri, 30 Mar 2007) | 1 line Removed excess logging to optimize performance. ........ r524739 | ritchiem | 2007-04-02 08:29:06 +0100 (Mon, 02 Apr 2007) | 1 line Added BDB Test scripts and updated pom to contain same tests as were used in perftesting ........ r524740 | ritchiem | 2007-04-02 08:47:29 +0100 (Mon, 02 Apr 2007) | 1 line Fixed error with passwordfile parameter ........ r524743 | ritchiem | 2007-04-02 09:07:55 +0100 (Mon, 02 Apr 2007) | 1 line Added CTQ tests ........ r524763 | ritchiem | 2007-04-02 11:50:06 +0100 (Mon, 02 Apr 2007) | 1 line Added verify password method to PrincipalDatabase ........ r524765 | ritchiem | 2007-04-02 11:55:12 +0100 (Mon, 02 Apr 2007) | 1 line Moved broker details to a separate variable. ........ r524767 | ritchiem | 2007-04-02 12:17:54 +0100 (Mon, 02 Apr 2007) | 1 line ignored idea files ........ r525487 | ritchiem | 2007-04-04 11:42:59 +0100 (Wed, 04 Apr 2007) | 3 lines Added default timeout to AMQConnection.close(); ........ r525553 | ritchiem | 2007-04-04 17:34:35 +0100 (Wed, 04 Apr 2007) | 1 line Updated case of properties ........ r525766 | ritchiem | 2007-04-05 09:51:55 +0100 (Thu, 05 Apr 2007) | 1 line QPID-308 Added test case to demonstrate heap exhaustion of broker. Can't be run InVM as it kills the broker. ........ r525777 | ritchiem | 2007-04-05 10:29:22 +0100 (Thu, 05 Apr 2007) | 20 lines QPID-414 : Addition of CRAM-MD5-HASHED authentication. Same as CRAM-MD5 but the client uses the hash of the password rather than the original password. This allows the broker to store the hash not the original password. Added initial tool for generation passwords. Broker: Renamed MD5PasswordFilePrincipalDatabase.java to Base64MD5PasswordFilePrincipalDatabase.java as that more accurately represents the file contents. PlainPasswordVhostFilePrincipalDatabase.java - import tidy up PrincipalDatabaseAuthenticationManager.java - Changed to add our SASL providers at the start of the SASL list. CRAMMD5Hashed* - New SASL mechanism that delegates to CRAM-MD5 but understands that the password to use is the hash of the users password. JCAProvider - Removed the addProvider() line as this is done after the construction in PrincipalDatabaseAuthenticationManager. PlainSaslServerFactory - White Space Passwd.java - New util stub for managing passwords ala htpasswd. Client Added CRAM-MD5-HASHED to CallbackHandlerRegistry Added ClientFactory for CRAMMD5Hashed that returns the first CRAM-MD5 SaslClient. DynamicSaslRegistrar.java - Tidied imports added new JCAProviders at the start of the Sasl lists. DynamicSaslRegistrar.properties - Added CRAM-MD5-HASHED handler. JCAProvider.java - as with broker stopped JCAProvider.java adding itself as the DynamicSaslRegistrar.java does this on the client. UsernameHashedPasswordCallbackHandler.java - New callback handler that is used by CRAM-MD5-HASHED. It hashes the client's password and uses that in the CRAM-MD5 algorithm. ........ r525785 | ritchiem | 2007-04-05 10:48:43 +0100 (Thu, 05 Apr 2007) | 1 line Old ant folder ........ r525786 | ritchiem | 2007-04-05 10:57:33 +0100 (Thu, 05 Apr 2007) | 1 line QPID-440 - added comments in the code relating to this bug. ........ r525787 | ritchiem | 2007-04-05 10:58:20 +0100 (Thu, 05 Apr 2007) | 2 lines QPID-308 removed closeConnection() that calls close(-1) and may result in a client hang. better to call closeConnection(long timeout) so forced this my removing closeConnection(); ........ r525788 | ritchiem | 2007-04-05 11:00:56 +0100 (Thu, 05 Apr 2007) | 1 line QPID-414 update to config.xml to give usage example. ........ r525804 | ritchiem | 2007-04-05 13:19:31 +0100 (Thu, 05 Apr 2007) | 1 line QPID-308 Updated HeapExhaustion to be able to be run from command line ........ r525817 | ritchiem | 2007-04-05 14:14:50 +0100 (Thu, 05 Apr 2007) | 1 line Update to qpid stop scripts to properly check for existing broker instances and promptly stop them. ........ r525829 | ritchiem | 2007-04-05 14:50:56 +0100 (Thu, 05 Apr 2007) | 1 line Updated scripts to work correctly under solaris and bash 2.0 ........ r525862 | rgodfrey | 2007-04-05 17:37:40 +0100 (Thu, 05 Apr 2007) | 1 line QPID-443 : Fix to transactionality of message publishing ........ r525867 | ritchiem | 2007-04-05 17:47:59 +0100 (Thu, 05 Apr 2007) | 2 lines QPID-416 Provided simple update to Access Control via FileAccessManager to allow access rights for a virtualhost to be stored in a separate file. Updated PrincipalDatabaseAccessManager to use the default AccessManager if the specified PrincipalDatabase is not an AccessManager. ........ r526091 | ritchiem | 2007-04-06 09:21:01 +0100 (Fri, 06 Apr 2007) | 5 lines QPID-416 Update to Access control to allow simply read/write permissions per Virtual host. access - updated file to have examples of access control. AccessManager - Deprecated old isAuthorised method Implemented new isAuthorized method on all AccessManagers ........ r526113 | ritchiem | 2007-04-06 11:28:43 +0100 (Fri, 06 Apr 2007) | 1 line Updated case of properties to be true cammelCase and updated tests to run for a duration of 10 minutes rather than set message count. To provide better results for graphing. ........ r526117 | ritchiem | 2007-04-06 11:42:11 +0100 (Fri, 06 Apr 2007) | 9 lines QPID-416 Update to Access control to allow simply read/write permissions per Virtual host. access - updated file to have examples of access control. Changed AMQProtocolSession to record an authorized Principal not just a String. - Required Added AccessRights files needed for VirtualHostAccess control. Updated ConnectionOpenMethodHandler to allow Principals with any access to connect not just read. UsernamePrincipal - Added a toString ........ r526118 | rgodfrey | 2007-04-06 11:55:17 +0100 (Fri, 06 Apr 2007) | 1 line ........ r526122 | ritchiem | 2007-04-06 12:26:06 +0100 (Fri, 06 Apr 2007) | 1 line removed pauses between batches ........ r526154 | rgodfrey | 2007-04-06 14:24:46 +0100 (Fri, 06 Apr 2007) | 1 line QPID-443 : Fix to transactionality of message publishing ........ r526157 | bhupendrab | 2007-04-06 14:32:56 +0100 (Fri, 06 Apr 2007) | 1 line QPID-444 : Enabling the Qpid to use SASL. jmxmp can be plugged into for SASL. Can be configured to use security. ........ r526158 | ritchiem | 2007-04-06 14:34:52 +0100 (Fri, 06 Apr 2007) | 1 line Duplicate of BDB-Qpid.sh ........ r526159 | bhupendrab | 2007-04-06 14:37:47 +0100 (Fri, 06 Apr 2007) | 1 line QPID-444 : adding jmxport, which is used when out of the box JMXAgent is not used ........ r526166 | ritchiem | 2007-04-06 14:51:41 +0100 (Fri, 06 Apr 2007) | 1 line QPID-414 - Initial script to run the passwd gen. ........ r526187 | bhupendrab | 2007-04-06 15:53:36 +0100 (Fri, 06 Apr 2007) | 2 lines QPID-444 : Enabling the SASL support. jmxmp can be plugged into for SASL. ........ r526194 | rgreig | 2007-04-06 16:21:19 +0100 (Fri, 06 Apr 2007) | 1 line Added some ramping up performance tests. ........ r526195 | marnie | 2007-04-06 16:21:33 +0100 (Fri, 06 Apr 2007) | 1 line QPID-381 Amended session constructor to be non-transactional and use client ack mode. ........ r526198 | rgreig | 2007-04-06 16:26:02 +0100 (Fri, 06 Apr 2007) | 1 line Fixed message sizes. ........ r526199 | rgreig | 2007-04-06 16:29:06 +0100 (Fri, 06 Apr 2007) | 1 line Fixed commit batch size. ........ r526666 | ritchiem | 2007-04-09 08:47:14 +0100 (Mon, 09 Apr 2007) | 1 line Updated so the FileAppender includes time stamps by default.. ConversionPattern made the same as STDOUT and RollingFileAppender ........ r526691 | ritchiem | 2007-04-09 10:39:47 +0100 (Mon, 09 Apr 2007) | 1 line Added $@ to allow pass through of command line args to each sub process ........ r526692 | bhupendrab | 2007-04-09 10:45:06 +0100 (Mon, 09 Apr 2007) | 4 lines QPID-444 : added log statements and some config parameters. Removed the autoDelete parameter from createNewQueue method used from Management Console. ........ r526694 | bhupendrab | 2007-04-09 10:51:46 +0100 (Mon, 09 Apr 2007) | 1 line ........ r526709 | bhupendrab | 2007-04-09 12:02:08 +0100 (Mon, 09 Apr 2007) | 2 lines QPID-444 : updated the management console dependency configuration for sasl support ........ r526776 | rgreig | 2007-04-09 16:26:04 +0100 (Mon, 09 Apr 2007) | 1 line Stopped throwing away exception causes. ........ r526803 | rgreig | 2007-04-09 17:09:24 +0100 (Mon, 09 Apr 2007) | 1 line Got rid of some uses of System.out instead of log4j logging. ........ r526807 | rgreig | 2007-04-09 17:12:49 +0100 (Mon, 09 Apr 2007) | 1 line Got rid of some uses of System.out instead of log4j logging. ........ r527049 | ritchiem | 2007-04-10 08:58:26 +0100 (Tue, 10 Apr 2007) | 1 line Moved bdb tests to bdbstore package ........ r527050 | ritchiem | 2007-04-10 09:00:42 +0100 (Tue, 10 Apr 2007) | 1 line QueueDeclareHandler.java - Added more detail to error messages. Such as returning the queue name that was attempted to be declared but failed. ........ r527053 | ritchiem | 2007-04-10 09:03:15 +0100 (Tue, 10 Apr 2007) | 1 line Added a test to check that Persistent Queues do actually persist. ........ r527182 | ritchiem | 2007-04-10 17:29:47 +0100 (Tue, 10 Apr 2007) | 1 line QPID-446 Initial MBean framework. ........ r527487 | ritchiem | 2007-04-11 14:31:18 +0100 (Wed, 11 Apr 2007) | 5 lines QPID-446 AMQUserManagementMBean Initial implementation of user management in authentication file. UserManagement - Added annotations for MBeanOperations PrincipalDatabase - Added new methods to update,create,delete Principal. - Implemented method on all PrincipalDatabase implementations, most return false to say not complete except Base64MD5PasswordFilePrincipalDatabase - which now stores in memory the password file and flushes any changes to disk. ........ r527493 | ritchiem | 2007-04-11 14:50:40 +0100 (Wed, 11 Apr 2007) | 1 line QPID-446 Missed the commit of JMXManagedObjectRegistry change on verifyPassword char[] to String ........ r527499 | bhupendrab | 2007-04-11 15:16:02 +0100 (Wed, 11 Apr 2007) | 1 line QPID-444 : added CRAM-MD5-HASHED mechanism for sasl ........ r527509 | bhupendrab | 2007-04-11 15:47:22 +0100 (Wed, 11 Apr 2007) | 1 line ........ r527518 | ritchiem | 2007-04-11 16:21:37 +0100 (Wed, 11 Apr 2007) | 14 lines QPID-446 JMXManagedObjectRegistry - Split instantiation from starting up. To all the setting of the Access file when loaded later in the startup sequence. ManagedObjectRegistry - Added Start method MBeanInvocationHandlerImpl - Updated to allow the setting of the access properties object from the AMQUserManagementMBean NoopManagedObjectRegistry - implemented no-op start ConfigurationFileApplicationRegistry - Adjusted to split creation of ManagedObjectRegistry from starting server to allow the setting of access rights. AMQUserManagementMBean - Implemented reading of access rights file. Base64MD5PasswordFilePrincipalDatabase - added comment for future Management. PrincipalDatabaseManager - added initialiseManagement method ConfigurationFilePrincipalDatabaseManager - implemented general Management initialisation. PropertiesPrincipalDatabaseManager - no-op implementation ........ r527537 | ritchiem | 2007-04-11 16:47:30 +0100 (Wed, 11 Apr 2007) | 2 lines QPID-446 Update to contain jmx config settings. ........ r527556 | bhupendrab | 2007-04-11 17:07:58 +0100 (Wed, 11 Apr 2007) | 1 line synchronized with hash mechanism used in Broker ........ r527557 | ritchiem | 2007-04-11 17:08:54 +0100 (Wed, 11 Apr 2007) | 1 line Fixed Bug in convertPassword where data wasn't correctly updated PropertiesPrincipalDatabase, ........ r527558 | ritchiem | 2007-04-11 17:09:54 +0100 (Wed, 11 Apr 2007) | 1 line QpiQPID-446 Update to ensure qpid.password file is correctly written in savePasswordFile ........ r527803 | ritchiem | 2007-04-12 08:16:54 +0100 (Thu, 12 Apr 2007) | 5 lines QPID-446 Update to write accessRights file and correctly write Base64 MD5 Hashed password to password file. MBeanInvocationHandlerImpl - made statics ADMIN,READONLY,READWRITE public so they can be used in writing the access file. AMQUserManagementMBean - Update to write the access File. PrincipalDatabase - create getUser(username) to retrieve a Principal from the database this is then implemented in all PDs. Used to check for existence of a user. ........ r527843 | ritchiem | 2007-04-12 09:52:19 +0100 (Thu, 12 Apr 2007) | 10 lines QPID-446 Update to send userList to JMX Management console. Currently niave implementation just sending ALL users in one go. If a LDAPPrincipalDatabase was created this could be quite a lot of data a) to send but b) to create in broker Heap. PrincipalDatabase - javadoc'd and getUsers method, -changed verifyPassword method to take String for username rather than Principal only the Managment Console uses this method and it the MC should be changed to use the Broker SASL modules directly rather than having very similar ones of its own. - Removed AccountNotFound exception from createPrincipal as it made no sence No-op implementation in PlainPasswordFilePrincipalDatabase and PropertiesPrincipalDatabase Base64MD5PasswordFilePrincipalDatabase changed local User class to implement Principal so current Map can be returned via getUsers - Added locking to ensure integrity of files in the face of multiple edits. ........ r527848 | ritchiem | 2007-04-12 10:11:19 +0100 (Thu, 12 Apr 2007) | 1 line QPID-446 Removed hashing of presented password in Base64MD5PasswordFilePrincipalDatabase. ........ r527876 | rgodfrey | 2007-04-12 11:31:51 +0100 (Thu, 12 Apr 2007) | 3 lines QPID-451 Throw InvalidDestinationException on attempt to publish to a Queue which does not exist Changed QueueSenderAdapter to check if the routing key is bound to a queue on the given exchange. The checking can be turned off by setting the system property org.apache.qpid.client.verifyQueueBindingBeforePublish to anything but true ........ r527941 | bhupendrab | 2007-04-12 14:49:10 +0100 (Thu, 12 Apr 2007) | 1 line not needed for management console ........ r527959 | bhupendrab | 2007-04-12 15:40:36 +0100 (Thu, 12 Apr 2007) | 1 line refining the mbean operations ........ r527972 | ritchiem | 2007-04-12 16:11:16 +0100 (Thu, 12 Apr 2007) | 3 lines QPID-446 Updated sample configs to contain jmx security options. ........ r528003 | marnie | 2007-04-12 17:15:48 +0100 (Thu, 12 Apr 2007) | 1 line QPID-352 Changes ........ r528005 | marnie | 2007-04-12 17:16:34 +0100 (Thu, 12 Apr 2007) | 1 line QPID-352 Changes ........ r528424 | rgreig | 2007-04-13 11:17:12 +0100 (Fri, 13 Apr 2007) | 1 line Created new ping client that sends messages only. Usefull for examaning known queue states in mgmnt console. ........ r529233 | bhupendrab | 2007-04-16 14:25:58 +0100 (Mon, 16 Apr 2007) | 1 line added parameter for SASL ........ r529246 | bhupendrab | 2007-04-16 14:48:31 +0100 (Mon, 16 Apr 2007) | 1 line removed default username as guest. Added hashing for new user password field. ........ r529297 | rgodfrey | 2007-04-16 16:53:45 +0100 (Mon, 16 Apr 2007) | 1 line QPID-453 : AMQShortString should implement Comparable ........ r529635 | bhupendrab | 2007-04-17 16:07:06 +0100 (Tue, 17 Apr 2007) | 1 line QPID-422 : Combined all user configured notifications on one view. ........ r529659 | ritchiem | 2007-04-17 17:08:00 +0100 (Tue, 17 Apr 2007) | 7 lines QPID-454 Message 'taken' notion is per message. But should be per message per queue AMQChannel - pass queue in on all take/release/getSubscriptionDelievered calls BasicRejectMethodHandler - pass queue in on getSubscriptionDelievered calls AMQMessage - Changes to require AMQQueue on all take/release/getSubscriptionDelievered calls ConcurrentSelectorDeliveryManager - pass queue in on take/release/getSubscriptionDelievered calls SubscriptionImpl - - pass queue in on release calls ........ r529666 | ritchiem | 2007-04-17 17:19:59 +0100 (Tue, 17 Apr 2007) | 11 lines QPID-455 Prefetched messages can cause problems with client tools. AMQSession - suspend channel at startup until start() and recieve/setMessageListener are called. BasicMessageConsumer - mainly style sheet changes MessageListenerMultiConsumerTest - removed one test case as we cannot ensure round-robin effect at start up .. added test case for only c2 consuming when c1 does nothing. MessageListenerTest - added new test that can demonstrate a further bug of message 'loss' when a receive is called only once before a message listener is set. Prefetched message end up on _SynchronousQueue regression of QPID-293 as of r501004. MessageRequeueTest - Was missing a conn.start() DurableSubscriptionTest - Removed blocking receives() so we don't block on failure CommitRollbackTest - Text message was wrong on testGetThenDisconnect tests so adjusted ........ r529669 | bhupendrab | 2007-04-17 17:43:53 +0100 (Tue, 17 Apr 2007) | 1 line QPID-417 ........ r530034 | bhupendrab | 2007-04-18 15:32:02 +0100 (Wed, 18 Apr 2007) | 2 lines AMQUserManagementMBean.java - calling relaod within viewUsers method. Creating user list on management console instead of typing the user name. ........ r530037 | ritchiem | 2007-04-18 15:37:30 +0100 (Wed, 18 Apr 2007) | 1 line QPID-454 Message 'taken' notion is per message. REVERTED as it just wasn't right.. needs to be refactored. ........ r530041 | ritchiem | 2007-04-18 15:40:47 +0100 (Wed, 18 Apr 2007) | 1 line QPID-457 Fixed rollback inTran problem with test case ........ r530042 | ritchiem | 2007-04-18 15:42:16 +0100 (Wed, 18 Apr 2007) | 1 line QPID-457 Fixed rollback inTran problem with test case Missed the actual file fix. ........ r530043 | ritchiem | 2007-04-18 15:46:36 +0100 (Wed, 18 Apr 2007) | 1 line QPID-458 Fix to make the CSDM check if a message is taken when deliverying to browser. Removing the message from the queue and continuing if that is the caee. ........ r530044 | ritchiem | 2007-04-18 15:54:36 +0100 (Wed, 18 Apr 2007) | 1 line Removed e.printstacktrace that sneaked in with the other code style changes. ........ r530047 | ritchiem | 2007-04-18 16:09:28 +0100 (Wed, 18 Apr 2007) | 1 line Fix for intermittent CRT expected <1> but was <2> errors ........ r530048 | ritchiem | 2007-04-18 16:10:24 +0100 (Wed, 18 Apr 2007) | 3 lines ResetMessageListenerTest was using the wrong queue for running tests. This was causing problems during testing. Changed queue to use ResetMessageListenerTest queue ........ r530049 | ritchiem | 2007-04-18 16:11:22 +0100 (Wed, 18 Apr 2007) | 2 lines QPID-455 Prefetched messages can cause problems with client tools. Removed the changes as this was causing problems. Guarded with a check for now but solution is till not correct. ........ r530052 | ritchiem | 2007-04-18 16:12:45 +0100 (Wed, 18 Apr 2007) | 1 line QPID-455 - Guarded test with a check until a full solution is found ........ git-svn-id: https://svn.apache.org/repos/asf/incubator/qpid/trunk@530474 13f79535-47bb-0310-9956-ffa450edef68
-rw-r--r--qpid/java/broker/bin/passwd21
-rw-r--r--qpid/java/broker/bin/qpid-server9
-rw-r--r--qpid/java/broker/bin/qpid.stop38
-rw-r--r--qpid/java/broker/bin/qpid.stopall15
-rw-r--r--qpid/java/broker/distribution/src/main/assembly/broker-bin.xml12
-rw-r--r--qpid/java/broker/etc/access1
-rw-r--r--qpid/java/broker/etc/config.xml20
-rw-r--r--qpid/java/broker/etc/jmxremote.access3
-rw-r--r--qpid/java/broker/etc/log4j.xml10
-rw-r--r--qpid/java/broker/etc/persistent_config.xml132
-rw-r--r--qpid/java/broker/etc/transient_config.xml128
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/AMQBrokerManagerMBean.java53
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/AMQChannel.java13
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/Main.java91
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/exchange/DestNameExchange.java1
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/handler/BasicRejectMethodHandler.java2
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/handler/ConnectionOpenMethodHandler.java16
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/handler/ConnectionSecureOkMethodHandler.java3
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/handler/ConnectionStartOkMethodHandler.java3
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/handler/QueueDeclareHandler.java52
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/management/JMXManagedObjectRegistry.java258
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/management/MBeanInvocationHandlerImpl.java217
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/management/ManagedBroker.java6
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/management/ManagedObjectRegistry.java5
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/management/NoopManagedObjectRegistry.java12
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/protocol/AMQMinaProtocolSession.java7
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/protocol/AMQProtocolSession.java8
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/protocol/AMQProtocolSessionMBean.java96
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/protocol/ManagedConnection.java8
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/queue/AMQMessage.java38
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/queue/AMQQueueMBean.java136
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/queue/ConcurrentSelectorDeliveryManager.java31
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/queue/SubscriptionImpl.java2
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/registry/ApplicationRegistry.java10
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/registry/ConfigurationFileApplicationRegistry.java9
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/security/Passwd.java81
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/security/access/AMQUserManagementMBean.java457
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/security/access/AccessManager.java5
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/security/access/AccessManagerImpl.java33
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/security/access/AccessRights.java63
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/security/access/AllowAll.java7
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/security/access/DenyAll.java7
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/security/access/FileAccessManager.java183
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/security/access/PrincipalDatabaseAccessManager.java21
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/security/access/UserManagement.java111
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/security/access/VirtualHostAccess.java68
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/database/Base64MD5PasswordFilePrincipalDatabase.java626
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/database/ConfigurationFilePrincipalDatabaseManager.java144
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/database/MD5PasswordFilePrincipalDatabase.java160
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/database/PlainPasswordFilePrincipalDatabase.java92
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/database/PlainPasswordVhostFilePrincipalDatabase.java22
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/database/PrincipalDatabase.java50
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/database/PrincipalDatabaseManager.java4
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/database/PropertiesPrincipalDatabase.java82
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/database/PropertiesPrincipalDatabaseManager.java7
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/PrincipalDatabaseAuthenticationManager.java19
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/JCAProvider.java2
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/UsernamePasswordInitialiser.java15
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/UsernamePrincipal.java10
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/crammd5/CRAMMD5HashedInitialiser.java50
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/crammd5/CRAMMD5HashedSaslServer.java105
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/crammd5/CRAMMD5HashedServerFactory.java61
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/plain/PlainSaslServerFactory.java2
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/txn/CleanupMessageOperation.java13
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/txn/LocalTransactionalContext.java10
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/txn/TxnBuffer.java2
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/virtualhost/VirtualHost.java2
-rw-r--r--qpid/java/broker/src/test/java/org/apache/qpid/server/queue/AMQQueueAlertTest.java2
-rw-r--r--qpid/java/client/example/src/main/java/org/apache/qpid/example/publisher/FileMessageDispatcher.java61
-rw-r--r--qpid/java/client/example/src/main/java/org/apache/qpid/example/publisher/FileMessageFactory.java4
-rw-r--r--qpid/java/client/example/src/main/java/org/apache/qpid/example/shared/InitialContextHelper.java4
-rw-r--r--qpid/java/client/src/main/java/org/apache/qpid/client/AMQConnection.java355
-rw-r--r--qpid/java/client/src/main/java/org/apache/qpid/client/AMQConnectionURL.java60
-rw-r--r--qpid/java/client/src/main/java/org/apache/qpid/client/AMQDestination.java31
-rw-r--r--qpid/java/client/src/main/java/org/apache/qpid/client/AMQSession.java75
-rw-r--r--qpid/java/client/src/main/java/org/apache/qpid/client/BasicMessageConsumer.java164
-rw-r--r--qpid/java/client/src/main/java/org/apache/qpid/client/BasicMessageProducer.java26
-rw-r--r--qpid/java/client/src/main/java/org/apache/qpid/client/JMSAMQException.java45
-rw-r--r--qpid/java/client/src/main/java/org/apache/qpid/client/QueueSenderAdapter.java35
-rw-r--r--qpid/java/client/src/main/java/org/apache/qpid/client/TopicPublisherAdapter.java5
-rw-r--r--qpid/java/client/src/main/java/org/apache/qpid/client/handler/ChannelCloseMethodHandler.java2
-rw-r--r--qpid/java/client/src/main/java/org/apache/qpid/client/message/AbstractBytesMessage.java10
-rw-r--r--qpid/java/client/src/main/java/org/apache/qpid/client/message/AbstractJMSMessage.java12
-rw-r--r--qpid/java/client/src/main/java/org/apache/qpid/client/message/JMSHeaderAdapter.java4
-rw-r--r--qpid/java/client/src/main/java/org/apache/qpid/client/message/JMSObjectMessage.java28
-rw-r--r--qpid/java/client/src/main/java/org/apache/qpid/client/protocol/AMQProtocolHandler.java12
-rw-r--r--qpid/java/client/src/main/java/org/apache/qpid/client/security/CallbackHandlerRegistry.properties1
-rw-r--r--qpid/java/client/src/main/java/org/apache/qpid/client/security/DynamicSaslRegistrar.java33
-rw-r--r--qpid/java/client/src/main/java/org/apache/qpid/client/security/DynamicSaslRegistrar.properties1
-rw-r--r--qpid/java/client/src/main/java/org/apache/qpid/client/security/JCAProvider.java2
-rw-r--r--qpid/java/client/src/main/java/org/apache/qpid/client/security/UsernameHashedPasswordCallbackHandler.java104
-rw-r--r--qpid/java/client/src/main/java/org/apache/qpid/client/security/crammd5hashed/CRAMMD5HashedSaslClientFactory.java72
-rw-r--r--qpid/java/client/src/main/java/org/apache/qpid/client/transport/AMQNoTransportForProtocolException.java6
-rw-r--r--qpid/java/client/src/main/java/org/apache/qpid/client/transport/AMQTransportConnectionException.java10
-rw-r--r--qpid/java/client/src/main/java/org/apache/qpid/client/transport/TransportConnection.java95
-rw-r--r--qpid/java/client/src/main/java/org/apache/qpid/client/vmbroker/AMQVMBrokerCreationException.java16
-rw-r--r--qpid/java/client/src/main/java/org/apache/qpid/jms/FailoverPolicy.java2
-rw-r--r--qpid/java/client/src/test/java/org/apache/qpid/client/MessageListenerMultiConsumerTest.java60
-rw-r--r--qpid/java/client/src/test/java/org/apache/qpid/client/MessageListenerTest.java30
-rw-r--r--qpid/java/client/src/test/java/org/apache/qpid/client/ResetMessageListenerTest.java2
-rw-r--r--qpid/java/client/src/test/java/org/apache/qpid/test/unit/basic/InvalidDestinationTest.java109
-rw-r--r--qpid/java/client/src/test/java/org/apache/qpid/test/unit/close/MessageRequeueTest.java13
-rw-r--r--qpid/java/client/src/test/java/org/apache/qpid/test/unit/topic/DurableSubscriptionTest.java16
-rw-r--r--qpid/java/client/src/test/java/org/apache/qpid/test/unit/transacted/CommitRollbackTest.java76
-rw-r--r--qpid/java/client/src/test/java/org/apache/qpid/testutil/Config.java2
-rw-r--r--qpid/java/client/src/test/java/org/apache/qpid/testutil/QpidClientConnection.java3
-rw-r--r--qpid/java/common/bin/qpid-run17
-rw-r--r--qpid/java/common/src/main/java/org/apache/qpid/AMQException.java58
-rw-r--r--qpid/java/common/src/main/java/org/apache/qpid/configuration/PropertyException.java10
-rw-r--r--qpid/java/common/src/main/java/org/apache/qpid/framing/AMQDataBlockDecoder.java8
-rw-r--r--qpid/java/common/src/main/java/org/apache/qpid/framing/AMQFrameDecodingException.java20
-rw-r--r--qpid/java/common/src/main/java/org/apache/qpid/framing/AMQShortString.java2
-rw-r--r--qpid/java/common/src/main/java/org/apache/qpid/framing/BasicContentHeaderProperties.java4
-rw-r--r--qpid/java/common/src/main/java/org/apache/qpid/framing/ContentHeaderPropertiesFactory.java2
-rw-r--r--qpid/java/common/src/main/java/org/apache/qpid/framing/EncodingUtils.java261
-rw-r--r--qpid/java/common/src/main/java/org/apache/qpid/framing/VersionSpecificRegistry.java24
-rw-r--r--qpid/java/common/src/main/java/org/apache/qpid/pool/Event.java23
-rw-r--r--qpid/java/common/src/main/java/org/apache/qpid/pool/PoolingFilter.java107
-rw-r--r--qpid/java/common/src/main/java/org/apache/qpid/url/AMQBindingURL.java53
-rw-r--r--qpid/java/common/src/main/java/org/apache/qpid/url/URLHelper.java44
-rw-r--r--qpid/java/distribution/src/main/assembly/bin.xml30
-rw-r--r--qpid/java/distribution/src/main/assembly/management-eclipse-plugin.xml7
-rw-r--r--qpid/java/management/eclipse-plugin/META-INF/MANIFEST.MF3
-rw-r--r--qpid/java/management/eclipse-plugin/bin/qpidmc.bat2
-rwxr-xr-xqpid/java/management/eclipse-plugin/bin/qpidmc.sh2
-rw-r--r--qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/ApplicationRegistry.java9
-rw-r--r--qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/ApplicationWorkbenchWindowAdvisor.java2
-rw-r--r--qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/Constants.java197
-rw-r--r--qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/ManagedBean.java16
-rw-r--r--qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/Perspective.java4
-rw-r--r--qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/ServerRegistry.java6
-rw-r--r--qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/actions/AddServer.java13
-rw-r--r--qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/actions/ReconnectServer.java13
-rw-r--r--qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/jmx/ClientListener.java5
-rw-r--r--qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/jmx/JMXServerRegistry.java170
-rw-r--r--qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/jmx/MBeanUtility.java52
-rw-r--r--qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/model/NotificationObject.java15
-rw-r--r--qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/model/OperationData.java8
-rw-r--r--qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/sasl/CRAMMD5HashedSaslClientFactory.java60
-rw-r--r--qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/sasl/ClientSaslFactory.java54
-rw-r--r--qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/sasl/JCAProvider.java56
-rw-r--r--qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/sasl/PlainSaslClient.java203
-rw-r--r--qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/sasl/SaslProvider.java35
-rw-r--r--qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/sasl/UserPasswordCallbackHandler.java73
-rw-r--r--qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/sasl/UsernameHashedPasswordCallbackHandler.java82
-rw-r--r--qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/AttributesTabControl.java2
-rw-r--r--qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/MBeanView.java98
-rw-r--r--qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/NavigationView.java27
-rw-r--r--qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/NotificationsTabControl.java410
-rw-r--r--qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/OperationTabControl.java84
-rw-r--r--qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/TabControl.java13
-rw-r--r--qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/TreeObject.java12
-rw-r--r--qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/VHNotificationsTabControl.java462
-rw-r--r--qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/ViewUtility.java69
-rw-r--r--qpid/java/management/eclipse-plugin/src/main/resources/sasl/MANIFEST.MF19
-rw-r--r--qpid/java/management/eclipse-plugin/src/main/resources/win32/configuration/config.ini2
-rwxr-xr-xqpid/java/perftests/etc/scripts/BDB-Qpid-4.sh28
-rwxr-xr-xqpid/java/perftests/etc/scripts/BDB-Qpid.sh12
-rwxr-xr-xqpid/java/perftests/etc/scripts/CTQ-Qpid-1.sh1
-rwxr-xr-xqpid/java/perftests/etc/scripts/CTQ-Qpid-2.sh1
-rwxr-xr-xqpid/java/perftests/etc/scripts/CTQ-Qpid-3.sh1
-rwxr-xr-xqpid/java/perftests/etc/scripts/CTQ-Qpid-4.sh1
-rwxr-xr-xqpid/java/perftests/etc/scripts/CTQ-Qpid-5.sh1
-rwxr-xr-xqpid/java/perftests/etc/scripts/CTQ-Qpid-6.sh1
-rwxr-xr-xqpid/java/perftests/etc/scripts/PT-Qpid-13.sh24
-rwxr-xr-xqpid/java/perftests/etc/scripts/PT-Qpid-14.sh23
-rw-r--r--qpid/java/perftests/etc/scripts/bdb-qpid-4/device.xml98
-rw-r--r--qpid/java/perftests/etc/scripts/bdb-qpid-4/filepath.xml97
-rw-r--r--qpid/java/perftests/etc/scripts/bdb-qpid-4/noneexistantpath.xml97
-rw-r--r--qpid/java/perftests/etc/scripts/bdb-qpid-4/nopermission.xml98
-rw-r--r--qpid/java/perftests/etc/scripts/bdb-qpid-4/starpath.xml98
-rw-r--r--qpid/java/perftests/pom.xml294
-rw-r--r--qpid/java/perftests/src/main/java/org/apache/qpid/client/message/TestMessageFactory.java2
-rw-r--r--qpid/java/perftests/src/main/java/org/apache/qpid/config/AbstractConfig.java4
-rw-r--r--qpid/java/perftests/src/main/java/org/apache/qpid/config/JBossConnectionFactoryInitialiser.java5
-rw-r--r--qpid/java/perftests/src/main/java/org/apache/qpid/ping/PingDurableClient.java40
-rw-r--r--qpid/java/perftests/src/main/java/org/apache/qpid/ping/PingSendOnlyClient.java57
-rw-r--r--qpid/java/perftests/src/main/java/org/apache/qpid/requestreply/PingPongProducer.java59
-rw-r--r--qpid/java/perftests/src/main/java/org/apache/qpid/topic/Config.java2
-rw-r--r--qpid/java/perftests/src/test/java/org/apache/qpid/ping/PingAsyncTestPerf.java11
-rw-r--r--qpid/java/systests/src/main/java/org/apache/qpid/server/AMQBrokerManagerMBeanTest.java8
-rw-r--r--qpid/java/systests/src/main/java/org/apache/qpid/server/failure/HeapExhaustion.java208
-rw-r--r--qpid/java/systests/src/main/java/org/apache/qpid/server/queue/MockProtocolSession.java5
-rw-r--r--qpid/java/systests/src/main/java/org/apache/qpid/server/queue/PersistentTest.java276
-rw-r--r--qpid/java/systests/src/main/java/org/apache/qpid/testutil/QpidClientConnection.java268
185 files changed, 8355 insertions, 1981 deletions
diff --git a/qpid/java/broker/bin/passwd b/qpid/java/broker/bin/passwd
new file mode 100644
index 0000000000..c1bb05c082
--- /dev/null
+++ b/qpid/java/broker/bin/passwd
@@ -0,0 +1,21 @@
+#!/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.
+#
+
+. qpid-run org.apache.qpid.server.security.Passwd "$@"
diff --git a/qpid/java/broker/bin/qpid-server b/qpid/java/broker/bin/qpid-server
index 0080209479..a2b416b12b 100644
--- a/qpid/java/broker/bin/qpid-server
+++ b/qpid/java/broker/bin/qpid-server
@@ -18,4 +18,13 @@
# under the License.
#
+# Set classpath to include Qpid jar with all required jars in manifest
+QPID_LIBS=$QPID_HOME/lib/qpid-incubating.jar:$QPID_HOME/lib/bdbstore-launch.jar
+
+# Set other variables used by the qpid-run script before calling
+export JAVA=java \
+ JAVA_VM=-server \
+ JAVA_MEM=-Xmx1024m \
+ QPID_CLASSPATH=$QPID_LIBS
+
. qpid-run org.apache.qpid.server.Main "$@"
diff --git a/qpid/java/broker/bin/qpid.stop b/qpid/java/broker/bin/qpid.stop
index 1bffc8cdb8..9193d3c4e1 100644
--- a/qpid/java/broker/bin/qpid.stop
+++ b/qpid/java/broker/bin/qpid.stop
@@ -5,9 +5,9 @@
# Script checks for a given pid running PROGRAM and attempts to quit it
#
-MAX_ATTEMPTS=5
-SLEEP_DELAY=2
-PROGRAM="org.apache.qpid.server.Main"
+MAX_ATTEMPTS=1
+SLEEP_DELAY=1
+PROGRAM="DQPID"
#
@@ -15,7 +15,8 @@ PROGRAM="org.apache.qpid.server.Main"
#
printActions()
{
-ps=`ps o command p $1|grep $PROGRAM`
+#ps=`ps o command p $1|grep $PROGRAM`
+ps=`ps -o args -p $1|grep $PROGRAM`
echo "Attempting to kill: $ps"
}
@@ -36,25 +37,25 @@ quit()
kill $1
}
+#
+# Grep the ps log for the PID ($1) to ensure that it has quit
+#
+lookup()
+{
+result=`ps -o args -p $1 |grep -v grep |grep $PROGRAM |wc -l`
+}
#
# Sleep and then check then lookup the PID($1) to ensure it has quit
#
check()
{
+echo "Waiting $SLEEP_DELAY second for $1 to exit"
sleep $SLEEP_DELAY
lookup $1
}
-#
-# Grep the ps log for the PID ($1) to ensure that it has quit
-#
-lookup()
-{
-result=`ps p $1 |grep -v grep |grep $PROGRAM |wc -l`
-}
-
#
# Verify the PID($1) is available
@@ -62,7 +63,7 @@ result=`ps p $1 |grep -v grep |grep $PROGRAM |wc -l`
verifyPid()
{
lookup $1
-if [[ $result == 1 ]] ; then
+if [[ $[$result] == 1 ]] ; then
brokerspid=$1
else
echo "Unable to locate Qpid Process with PID $1"
@@ -70,8 +71,6 @@ else
fi
}
-
-
#
# Main Run
#
@@ -89,22 +88,21 @@ printActions $brokerspid
# Attempt to quit the process MAX_ATTEMPTS Times
attempt=0
-while [[ $result > 0 && $attempt < $MAX_ATTEMPTS ]] ; do
+while [[ $[$result] > 0 && $[$attempt] < $[$MAX_ATTEMPTS] ]] ; do
quit $brokerspid
check $brokerspid
attempt=$[$attempt + 1]
done
-
# Check that it has quit
-if [[ $results == 0 ]] ; then
+if [[ $[$result] == 0 ]] ; then
echo "Process quit"
exit 0
else
# Now attempt to force quit the process
attempt=0
- while [[ $result > 0 && $attempt < $MAX_ATTEMPTS ]] ; do
+ while [[ $[$result] > 0 && $[$attempt] < $[$MAX_ATTEMPTS] ]] ; do
forceQuit $brokerspid
check $brokerspid
attempt=$[$attempt + 1]
@@ -112,7 +110,7 @@ else
# Output final status
- if [[ $attempt == $MAX_ATTEMPTS ]] ; then
+ if [[ $[$result] > 0 && $[$attempt] == $[$MAX_ATTEMPTS] ]] ; then
echo "Stopped trying to kill process: $brokerspid"
echo "Attempted to stop $attempt times"
else
diff --git a/qpid/java/broker/bin/qpid.stopall b/qpid/java/broker/bin/qpid.stopall
index f6862842c9..2e762bdd50 100644
--- a/qpid/java/broker/bin/qpid.stopall
+++ b/qpid/java/broker/bin/qpid.stopall
@@ -6,17 +6,16 @@
# Utilises qpid.stop to perform the actual stopping
#
-MAX_ATTEMPTS=5
-SLEEP_DELAY=2
-PROGRAM="org.apache.qpid.server.Main"
+PROGRAM="DQPID"
#
# grep ps for instances of $PROGRAM and collect PIDs
#
lookup()
{
-pids=`ps o pid,command |grep -v grep | grep $PROGRAM | cut -d ' ' -f 1`
-result=`echo -n $pids | wc -l`
+#pids=`ps o pid,command | grep $PROGRAM | grep -v grep | cut -d ' ' -f 1`
+pids=`ps -ef |grep $USER | grep $PROGRAM | grep -v grep | awk '{print $2}'`
+result=`echo -n $pids | wc -w`
}
@@ -25,7 +24,7 @@ result=`echo -n $pids | wc -l`
#
showPids()
{
-ps p $pids
+ps -o user,pid,args -p $pids
}
@@ -35,7 +34,7 @@ ps p $pids
lookup
-if [[ $result == 0 ]] ; then
+if [[ $[$result] == 0 ]] ; then
echo "No Qpid Brokers found running under user '$USER'"
exit 0
fi
@@ -49,7 +48,7 @@ done
# Check we have quit all
lookup
-if [[ $result == 0 ]] ; then
+if [[ $[$result] == 0 ]] ; then
echo "All Qpid brokers successfully quit"
else
echo "Some brokers were not quit"
diff --git a/qpid/java/broker/distribution/src/main/assembly/broker-bin.xml b/qpid/java/broker/distribution/src/main/assembly/broker-bin.xml
index 4a7343660d..4b32630771 100644
--- a/qpid/java/broker/distribution/src/main/assembly/broker-bin.xml
+++ b/qpid/java/broker/distribution/src/main/assembly/broker-bin.xml
@@ -78,6 +78,12 @@
<fileMode>420</fileMode>
</file>
<file>
+ <source>../etc/jmxremote.access</source>
+ <outputDirectory>qpid-${qpid.version}/etc</outputDirectory>
+ <destName>jmxremote.access</destName>
+ <fileMode>420</fileMode>
+ </file>
+ <file>
<source>../etc/log4j.xml</source>
<outputDirectory>qpid-${qpid.version}/etc</outputDirectory>
<destName>log4j.xml</destName>
@@ -108,6 +114,12 @@
<fileMode>473</fileMode>
</file>
<file>
+ <source>../bin/passwd</source>
+ <outputDirectory>qpid-${qpid.version}/bin</outputDirectory>
+ <destName>passwd</destName>
+ <fileMode>473</fileMode>
+ </file>
+ <file>
<source>../bin/qpid-server</source>
<outputDirectory>qpid-${qpid.version}/bin</outputDirectory>
<destName>qpid-server</destName>
diff --git a/qpid/java/broker/etc/access b/qpid/java/broker/etc/access
new file mode 100644
index 0000000000..a781ed8aa9
--- /dev/null
+++ b/qpid/java/broker/etc/access
@@ -0,0 +1 @@
+guest:localhost(rw),test(rw) \ No newline at end of file
diff --git a/qpid/java/broker/etc/config.xml b/qpid/java/broker/etc/config.xml
index 3789e6fcb6..c66c2f632e 100644
--- a/qpid/java/broker/etc/config.xml
+++ b/qpid/java/broker/etc/config.xml
@@ -41,6 +41,8 @@
</connector>
<management>
<enabled>true</enabled>
+ <jmxport>8999</jmxport>
+ <security-enabled>true</security-enabled>
</management>
<advanced>
<filterchain enableExecutorPool="true"/>
@@ -63,13 +65,14 @@
</attributes>
</principal-database>
- <!--principal-database>
- <name>md5passwordfile</name>
- <class>org.apache.qpid.server.security.auth.database.MD5PasswordFilePrincipalDatabase</class>
+ <!-- Example use of Base64 encoded MD5 hashes for authentication via CRAM-MD5-Hashed
+ <principal-database>
+ <name>passwordfile</name>
+ <class>org.apache.qpid.server.security.auth.database.Base64MD5PasswordFilePrincipalDatabase</class>
<attributes>
<attribute>
<name>passwordFile</name>
- <value>${conf}/md5passwd</value>
+ <value>${conf}/qpid.passwd</value>
</attribute>
</attributes>
</principal-database-->
@@ -78,6 +81,10 @@
<access>
<class>org.apache.qpid.server.security.access.AllowAll</class>
</access>
+ <jmx>
+ <access>${conf}/jmxremote.access</access>
+ <principal-database>passwordfile</principal-database>
+ </jmx>
</security>
<virtualhosts>
@@ -85,9 +92,10 @@
<name>localhost</name>
<localhost>
<store>
- <!-- <class>org.apache.qpid.server.store.berkeleydb.BDBMessageStore</class> -->
+ <!-- <class>org.apache.qpid.server.store.berkeleydb.BDBMessageStore</class>
+ <environment-path>${work}/localhost-store</environment-path> -->
+
<class>org.apache.qpid.server.store.MemoryMessageStore</class>
- <environment-path>localhost-store</environment-path>
</store>
<security>
diff --git a/qpid/java/broker/etc/jmxremote.access b/qpid/java/broker/etc/jmxremote.access
new file mode 100644
index 0000000000..d1172fc197
--- /dev/null
+++ b/qpid/java/broker/etc/jmxremote.access
@@ -0,0 +1,3 @@
+admin=admin
+guest=readonly
+user=readwrite
diff --git a/qpid/java/broker/etc/log4j.xml b/qpid/java/broker/etc/log4j.xml
index 74b80c0e80..b442227607 100644
--- a/qpid/java/broker/etc/log4j.xml
+++ b/qpid/java/broker/etc/log4j.xml
@@ -44,20 +44,16 @@
<param name="backupFilesToPath" value="${QPID_WORK}/backup/log"/>
<layout class="org.apache.log4j.PatternLayout">
- <param name="ConversionPattern" value="%d %-5p [%t] %C{2} (%F:%L) - %m%n"/>
- <!--param name="ConversionPattern" value="%t %-5p %c{2} - %m%n"/-->
+ <param name="ConversionPattern" value="%d %-5p [%t] %C{2} (%F:%L) - %m%n"/>
</layout>
</appender>
- <appender name="FileAppender" class="org.apache.log4j.FileAppender">
- <param name="staticLogFileName" value="false"/>
-
+ <appender name="FileAppender" class="org.apache.log4j.FileAppender">
<param name="File" value="${QPID_WORK}/log/${logprefix}qpid${logsuffix}.log"/>
<param name="Append" value="false"/>
<layout class="org.apache.log4j.PatternLayout">
- <param name="ConversionPattern" value="%t %-5p %c{2} - %m%n"/>
-
+ <param name="ConversionPattern" value="%d %-5p [%t] %C{2} (%F:%L) - %m%n"/>
</layout>
</appender>
diff --git a/qpid/java/broker/etc/persistent_config.xml b/qpid/java/broker/etc/persistent_config.xml
new file mode 100644
index 0000000000..178a73515c
--- /dev/null
+++ b/qpid/java/broker/etc/persistent_config.xml
@@ -0,0 +1,132 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<!--
+ -
+ - 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.
+ -
+
+ This is an example config using the BDBMessageStore available from
+ the Red Hat Messaging project at etp.108.redhat.com and distributed under GPL.
+ -->
+
+<broker>
+ <prefix>${QPID_HOME}</prefix>
+ <work>${QPID_WORK}</work>
+ <conf>${prefix}/etc</conf>
+ <connector>
+ <qpidnio>true</qpidnio>
+ <transport>nio</transport>
+ <port>5672</port>
+ <sslport>8672</sslport>
+ <socketReceiveBuffer>32768</socketReceiveBuffer>
+ <socketSendBuffer>32768</socketSendBuffer>
+ </connector>
+ <management>
+ <enabled>true</enabled>
+ <jmxport>8999</jmxport>
+ </management>
+ <advanced>
+ <filterchain enableExecutorPool="true"/>
+ <enablePooledAllocator>false</enablePooledAllocator>
+ <enableDirectBuffers>false</enableDirectBuffers>
+ <framesize>65535</framesize>
+ <compressBufferOnQueue>false</compressBufferOnQueue>
+ </advanced>
+
+ <security>
+ <principal-databases>
+ <principal-database>
+ <name>passwordfile</name>
+ <class>org.apache.qpid.server.security.auth.database.PlainPasswordVhostFilePrincipalDatabase</class>
+ <attributes>
+ <attribute>
+ <name>passwordFile</name>
+ <value>${conf}/passwdVhost</value>
+ </attribute>
+ </attributes>
+ </principal-database>
+ </principal-databases>
+
+ <access>
+ <class>org.apache.qpid.server.security.access.AllowAll</class>
+ </access>
+ <jmx>
+ <access>${conf}/jmxremote.access</access>
+ <principal-database>passwordfile</principal-database>
+ </jmx>
+ </security>
+
+ <virtualhosts>
+ <virtualhost>
+ <name>localhost</name>
+ <localhost>
+ <store>
+ <class>org.apache.qpid.server.store.berkeleydb.BDBMessageStore</class>
+ <environment-path>${work}/bdbstore/localhost-store</environment-path>
+ </store>
+
+ <security>
+ <access>
+ <class>org.apache.qpid.server.security.access.PrincipalDatabaseAccessManager</class>
+ <attributes>
+ <attribute>
+ <name>principalDatabase</name>
+ <value>passwordfile</value>
+ </attribute>
+ <attribute>
+ <name>defaultAccessManager</name>
+ <value>DenyAll</value>
+ </attribute>
+ </attributes>
+ </access>
+ </security>
+ </localhost>
+ </virtualhost>
+
+ <virtualhost>
+ <name>development</name>
+ <development>
+ <store>
+ <class>org.apache.qpid.server.store.berkeleydb.BDBMessageStore</class>
+ <environment-path>${work}/bdbstore/development-store</environment-path>
+ </store>
+ </development>
+ </virtualhost>
+
+ <virtualhost>
+ <name>test</name>
+ <test>
+ <store>
+ <class>org.apache.qpid.server.store.berkeleydb.BDBMessageStore</class>
+ <environment-path>${work}/bdbstore/test-store</environment-path>
+ </store>
+ </test>
+ </virtualhost>
+
+ </virtualhosts>
+ <heartbeat>
+ <delay>0</delay>
+ <timeoutFactor>2.0</timeoutFactor>
+ </heartbeat>
+ <queue>
+ <auto_register>true</auto_register>
+ </queue>
+
+ <virtualhosts>${conf}/virtualhosts.xml</virtualhosts>
+</broker>
+
+
diff --git a/qpid/java/broker/etc/transient_config.xml b/qpid/java/broker/etc/transient_config.xml
new file mode 100644
index 0000000000..164d66cd1b
--- /dev/null
+++ b/qpid/java/broker/etc/transient_config.xml
@@ -0,0 +1,128 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<!--
+ -
+ - 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.
+ -
+
+ This is an example config file that uses the MemoryMessageStore.
+ As a result it is aimed at brokers sending transient messages.
+
+ -->
+<broker>
+ <prefix>${QPID_HOME}</prefix>
+ <work>${QPID_WORK}</work>
+ <conf>${prefix}/etc</conf>
+ <connector>
+ <qpidnio>true</qpidnio>
+ <transport>nio</transport>
+ <port>5672</port>
+ <sslport>8672</sslport>
+ <socketReceiveBuffer>32768</socketReceiveBuffer>
+ <socketSendBuffer>32768</socketSendBuffer>
+ </connector>
+ <management>
+ <enabled>true</enabled>
+ <jmxport>8999</jmxport>
+ </management>
+ <advanced>
+ <filterchain enableExecutorPool="true"/>
+ <enablePooledAllocator>false</enablePooledAllocator>
+ <enableDirectBuffers>false</enableDirectBuffers>
+ <framesize>65535</framesize>
+ <compressBufferOnQueue>false</compressBufferOnQueue>
+ </advanced>
+
+ <security>
+ <principal-databases>
+ <principal-database>
+ <name>passwordfile</name>
+ <class>org.apache.qpid.server.security.auth.database.PlainPasswordVhostFilePrincipalDatabase</class>
+ <attributes>
+ <attribute>
+ <name>passwordFile</name>
+ <value>${conf}/passwdVhost</value>
+ </attribute>
+ </attributes>
+ </principal-database>
+ </principal-databases>
+ <access>
+ <class>org.apache.qpid.server.security.access.AllowAll</class>
+ </access>
+ <jmx>
+ <access>${conf}/jmxremote.access</access>
+ <principal-database>passwordfile</principal-database>
+ </jmx>
+ </security>
+
+ <virtualhosts>
+ <virtualhost>
+ <name>localhost</name>
+ <localhost>
+ <store>
+ <class>org.apache.qpid.server.store.MemoryMessageStore</class>
+ </store>
+
+ <security>
+ <access>
+ <class>org.apache.qpid.server.security.access.PrincipalDatabaseAccessManager</class>
+ <attributes>
+ <attribute>
+ <name>principalDatabase</name>
+ <value>passwordfile</value>
+ </attribute>
+ <attribute>
+ <name>defaultAccessManager</name>
+ <value>DenyAll</value>
+ </attribute>
+ </attributes>
+ </access>
+ </security>
+ </localhost>
+ </virtualhost>
+
+ <virtualhost>
+ <name>development</name>
+ <development>
+ <store>
+ <class>org.apache.qpid.server.store.MemoryMessageStore</class>
+ </store>
+ </development>
+ </virtualhost>
+
+ <virtualhost>
+ <name>test</name>
+ <test>
+ <store>
+ <class>org.apache.qpid.server.store.MemoryMessageStore</class>
+ </store>
+ </test>
+ </virtualhost>
+
+ </virtualhosts>
+ <heartbeat>
+ <delay>0</delay>
+ <timeoutFactor>2.0</timeoutFactor>
+ </heartbeat>
+ <queue>
+ <auto_register>true</auto_register>
+ </queue>
+
+ <virtualhosts>${conf}/virtualhosts.xml</virtualhosts>
+</broker>
+
+
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/AMQBrokerManagerMBean.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/AMQBrokerManagerMBean.java
index 23c32aceab..d31359b019 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/AMQBrokerManagerMBean.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/AMQBrokerManagerMBean.java
@@ -1,5 +1,25 @@
/*
*
+ * 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.
+ *
+ */
+/*
+ *
* Copyright (c) 2006 The Apache Software Foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
@@ -22,8 +42,12 @@ import javax.management.MBeanException;
import javax.management.MalformedObjectNameException;
import javax.management.ObjectName;
+import org.apache.commons.configuration.Configuration;
+
import org.apache.qpid.AMQException;
import org.apache.qpid.framing.AMQShortString;
+import org.apache.qpid.server.configuration.Configurator;
+import org.apache.qpid.server.configuration.VirtualHostConfiguration;
import org.apache.qpid.server.exchange.Exchange;
import org.apache.qpid.server.exchange.ExchangeFactory;
import org.apache.qpid.server.exchange.ExchangeRegistry;
@@ -36,9 +60,6 @@ import org.apache.qpid.server.queue.AMQQueue;
import org.apache.qpid.server.queue.QueueRegistry;
import org.apache.qpid.server.store.MessageStore;
import org.apache.qpid.server.virtualhost.VirtualHost;
-import org.apache.qpid.server.configuration.Configurator;
-import org.apache.qpid.server.configuration.VirtualHostConfiguration;
-import org.apache.commons.configuration.Configuration;
/**
* This MBean implements the broker management interface and exposes the
@@ -82,8 +103,7 @@ public class AMQBrokerManagerMBean extends AMQManagedObject implements ManagedBr
* @param autoDelete
* @throws JMException
*/
- public void createNewExchange(String exchangeName, String type, boolean durable, boolean autoDelete)
- throws JMException
+ public void createNewExchange(String exchangeName, String type, boolean durable) throws JMException
{
try
{
@@ -92,7 +112,8 @@ public class AMQBrokerManagerMBean extends AMQManagedObject implements ManagedBr
Exchange exchange = _exchangeRegistry.getExchange(new AMQShortString(exchangeName));
if (exchange == null)
{
- exchange = _exchangeFactory.createExchange(new AMQShortString(exchangeName), new AMQShortString(type), durable, autoDelete, 0);
+ exchange = _exchangeFactory.createExchange(new AMQShortString(exchangeName), new AMQShortString(type),
+ durable, false, 0);
_exchangeRegistry.registerExchange(exchange);
}
else
@@ -140,8 +161,7 @@ public class AMQBrokerManagerMBean extends AMQManagedObject implements ManagedBr
* @param autoDelete
* @throws JMException
*/
- public void createNewQueue(String queueName, String owner, boolean durable,boolean autoDelete)
- throws JMException
+ public void createNewQueue(String queueName, String owner, boolean durable) throws JMException
{
AMQQueue queue = _queueRegistry.getQueue(new AMQShortString(queueName));
if (queue != null)
@@ -156,22 +176,27 @@ public class AMQBrokerManagerMBean extends AMQManagedObject implements ManagedBr
{
ownerShortString = new AMQShortString(owner);
}
- queue = new AMQQueue(new AMQShortString(queueName), durable, ownerShortString, autoDelete, getVirtualHost());
+
+ queue = new AMQQueue(new AMQShortString(queueName), durable, ownerShortString, false, getVirtualHost());
if (queue.isDurable() && !queue.isAutoDelete())
{
_messageStore.createQueue(queue);
}
- Configuration virtualHostDefaultQueueConfiguration = VirtualHostConfiguration.getDefaultQueueConfiguration(queue);
+ Configuration virtualHostDefaultQueueConfiguration =
+ VirtualHostConfiguration.getDefaultQueueConfiguration(queue);
if (virtualHostDefaultQueueConfiguration != null)
{
Configurator.configure(queue, virtualHostDefaultQueueConfiguration);
}
+
_queueRegistry.registerQueue(queue);
}
catch (AMQException ex)
{
- throw new MBeanException(new JMException(ex.getMessage()),"Error in creating queue " + queueName);
+ JMException jme = new JMException(ex.getMessage());
+ jme.initCause(ex);
+ throw new MBeanException(jme, "Error in creating queue " + queueName);
}
}
@@ -202,7 +227,9 @@ public class AMQBrokerManagerMBean extends AMQManagedObject implements ManagedBr
}
catch (AMQException ex)
{
- throw new MBeanException(new JMException(ex.getMessage()), "Error in deleting queue " + queueName);
+ JMException jme = new JMException(ex.getMessage());
+ jme.initCause(ex);
+ throw new MBeanException(jme, "Error in deleting queue " + queueName);
}
}
@@ -213,7 +240,7 @@ public class AMQBrokerManagerMBean extends AMQManagedObject implements ManagedBr
// This will have a single instance for a virtual host, so not having the name property in the ObjectName
public ObjectName getObjectName() throws MalformedObjectNameException
- {
+ {
return getObjectNameForSingleInstanceMBean();
}
} // End of MBean class
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/AMQChannel.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/AMQChannel.java
index 1ebe5fa0a2..2e1653e69d 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/AMQChannel.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/AMQChannel.java
@@ -472,7 +472,7 @@ public class AMQChannel
if (unacked.queue != null)
{
// Ensure message is released for redelivery
- unacked.message.release();
+ unacked.message.release(unacked.queue);
// Mark message redelivered
unacked.message.setRedelivered(true);
@@ -503,7 +503,10 @@ public class AMQChannel
{
// Ensure message is released for redelivery
- unacked.message.release();
+ if (unacked.queue != null)
+ {
+ unacked.message.release(unacked.queue);
+ }
// Mark message redelivered
unacked.message.setRedelivered(true);
@@ -672,14 +675,14 @@ public class AMQChannel
// else
// {
//release to allow it to be delivered
- msg.release();
+ msg.release(message.queue);
// Without any details from the client about what has been processed we have to mark
// all messages in the unacked map as redelivered.
msg.setRedelivered(true);
- Subscription sub = msg.getDeliveredSubscription();
+ Subscription sub = msg.getDeliveredSubscription(message.queue);
if (sub != null)
{
@@ -753,7 +756,7 @@ public class AMQChannel
// Process Messages to Requeue at the front of the queue
for (UnacknowledgedMessage message : msgToRequeue)
{
- message.message.release();
+ message.message.release(message.queue);
message.message.setRedelivered(true);
deliveryContext.deliver(message.message, message.queue, true);
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/Main.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/Main.java
index 38a505c6c7..146d0566ce 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/Main.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/Main.java
@@ -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
@@ -36,14 +36,17 @@ import org.apache.commons.cli.Options;
import org.apache.commons.cli.ParseException;
import org.apache.commons.cli.PosixParser;
import org.apache.commons.configuration.ConfigurationException;
+
import org.apache.log4j.BasicConfigurator;
import org.apache.log4j.Logger;
import org.apache.log4j.xml.DOMConfigurator;
+
import org.apache.mina.common.ByteBuffer;
import org.apache.mina.common.IoAcceptor;
import org.apache.mina.common.SimpleByteBufferAllocator;
import org.apache.mina.transport.socket.nio.SocketAcceptorConfig;
import org.apache.mina.transport.socket.nio.SocketSessionConfig;
+
import org.apache.qpid.AMQException;
import org.apache.qpid.framing.ProtocolVersion;
import org.apache.qpid.pool.ReadWriteThreadModel;
@@ -59,7 +62,7 @@ import org.apache.qpid.url.URLSyntaxException;
* Main entry point for AMQPD.
*
*/
-@SuppressWarnings({"AccessStaticViaInstance"})
+@SuppressWarnings({ "AccessStaticViaInstance" })
public class Main
{
private static final Logger _logger = Logger.getLogger(Main.class);
@@ -74,9 +77,9 @@ public class Main
protected static class InitException extends Exception
{
- InitException(String msg)
+ InitException(String msg, Throwable cause)
{
- super(msg);
+ super(msg, cause);
}
}
@@ -97,6 +100,7 @@ public class Main
try
{
commandLine = new PosixParser().parse(options, args);
+
return true;
}
catch (ParseException e)
@@ -104,6 +108,7 @@ public class Main
System.err.println("Error: " + e.getMessage());
HelpFormatter formatter = new HelpFormatter();
formatter.printHelp("Qpid", options, true);
+
return false;
}
}
@@ -112,17 +117,26 @@ public class Main
{
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").
- withLongOpt("config").create("c");
- Option port = OptionBuilder.withArgName("port").hasArg().withDescription("listen on the specified port. Overrides any value in the config file").
- withLongOpt("port").create("p");
- Option bind = OptionBuilder.withArgName("bind").hasArg().withDescription("bind to the specified address. Overrides any value in the config file").
- withLongOpt("bind").create("b");
- Option logconfig = OptionBuilder.withArgName("logconfig").hasArg().withDescription("use the specified log4j xml configuration file. By " +
- "default looks for a file named " + DEFAULT_LOG_CONFIG_FILENAME + " in the same directory as the configuration file").
- withLongOpt("logconfig").create("l");
- Option logwatchconfig = OptionBuilder.withArgName("logwatch").hasArg().withDescription("monitor the log file configuration file for changes. Units are seconds. " +
- "Zero means do not check for changes.").withLongOpt("logwatch").create("w");
+ Option configFile =
+ OptionBuilder.withArgName("file").hasArg().withDescription("use given configuration file").withLongOpt("config")
+ .create("c");
+ Option port =
+ OptionBuilder.withArgName("port").hasArg()
+ .withDescription("listen on the specified port. Overrides any value in the config file")
+ .withLongOpt("port").create("p");
+ Option bind =
+ OptionBuilder.withArgName("bind").hasArg()
+ .withDescription("bind to the specified address. Overrides any value in the config file")
+ .withLongOpt("bind").create("b");
+ Option logconfig =
+ OptionBuilder.withArgName("logconfig").hasArg()
+ .withDescription("use the specified log4j xml configuration file. By "
+ + "default looks for a file named " + DEFAULT_LOG_CONFIG_FILENAME
+ + " in the same directory as the configuration file").withLongOpt("logconfig").create("l");
+ Option logwatchconfig =
+ OptionBuilder.withArgName("logwatch").hasArg()
+ .withDescription("monitor the log file configuration file for changes. Units are seconds. "
+ + "Zero means do not check for changes.").withLongOpt("logwatch").create("w");
options.addOption(help);
options.addOption(version);
@@ -150,7 +164,7 @@ public class Main
boolean first = true;
for (ProtocolVersion pv : ProtocolVersion.getSupportedProtocolVersions())
{
- if(first)
+ if (first)
{
first = false;
}
@@ -158,9 +172,11 @@ public class Main
{
protocol.append(", ");
}
+
protocol.append(pv.getMajorVersion()).append('-').append(pv.getMinorVersion());
}
+
System.out.println(ver + " (" + protocol + ")");
}
else
@@ -186,7 +202,6 @@ public class Main
}
}
-
protected void startup() throws InitException, ConfigurationException, Exception
{
final String QpidHome = System.getProperty("QPID_HOME");
@@ -201,7 +216,7 @@ public class Main
error = error + "\nNote: Qpid_HOME is not set.";
}
- throw new InitException(error);
+ throw new InitException(error, null);
}
else
{
@@ -226,8 +241,8 @@ public class Main
_logger.info("Starting Qpid.AMQP broker");
- ConnectorConfiguration connectorConfig = ApplicationRegistry.getInstance().
- getConfiguredObject(ConnectorConfiguration.class);
+ ConnectorConfiguration connectorConfig =
+ ApplicationRegistry.getInstance().getConfiguredObject(ConnectorConfiguration.class);
ByteBuffer.setUseDirectBuffers(connectorConfig.enableDirectBuffers);
@@ -249,7 +264,7 @@ public class Main
}
catch (NumberFormatException e)
{
- throw new InitException("Invalid port: " + portStr);
+ throw new InitException("Invalid port: " + portStr, e);
}
}
@@ -264,19 +279,21 @@ public class Main
int totalVHosts = ((Collection) virtualHosts).size();
for (int vhost = 0; vhost < totalVHosts; vhost++)
{
- setupVirtualHosts(configFile.getParent() , (String)((List)virtualHosts).get(vhost));
+ setupVirtualHosts(configFile.getParent(), (String) ((List) virtualHosts).get(vhost));
}
}
else
{
- setupVirtualHosts(configFile.getParent() , (String)virtualHosts);
+ setupVirtualHosts(configFile.getParent(), (String) virtualHosts);
}
}
+
bind(port, connectorConfig);
}
- protected void setupVirtualHosts(String configFileParent, String configFilePath) throws ConfigurationException, AMQException, URLSyntaxException
+ protected void setupVirtualHosts(String configFileParent, String configFilePath)
+ throws ConfigurationException, AMQException, URLSyntaxException
{
String configVar = "${conf}";
@@ -285,7 +302,7 @@ public class Main
configFilePath = configFileParent + configFilePath.substring(configVar.length());
}
- if (configFilePath.indexOf(".xml") != -1 )
+ if (configFilePath.indexOf(".xml") != -1)
{
VirtualHostConfiguration vHostConfig = new VirtualHostConfiguration(configFilePath);
vHostConfig.performBindings();
@@ -298,11 +315,12 @@ public class Main
String[] fileNames = virtualHostDir.list();
- for (int each=0; each < fileNames.length; each++)
+ for (int each = 0; each < fileNames.length; each++)
{
if (fileNames[each].endsWith(".xml"))
{
- VirtualHostConfiguration vHostConfig = new VirtualHostConfiguration(configFilePath+"/"+fileNames[each]);
+ VirtualHostConfiguration vHostConfig =
+ new VirtualHostConfiguration(configFilePath + "/" + fileNames[each]);
vHostConfig.performBindings();
}
}
@@ -319,7 +337,7 @@ public class Main
try
{
- //IoAcceptor acceptor = new SocketAcceptor(connectorConfig.processors);
+ // IoAcceptor acceptor = new SocketAcceptor(connectorConfig.processors);
IoAcceptor acceptor = connectorConfig.createAcceptor();
SocketAcceptorConfig sconfig = (SocketAcceptorConfig) acceptor.getDefaultConfig();
SocketSessionConfig sc = (SocketSessionConfig) sconfig.getSessionConfig();
@@ -334,7 +352,7 @@ public class Main
{
sconfig.setThreadModel(ReadWriteThreadModel.getInstance());
}
-
+
if (!connectorConfig.enableSSL || !connectorConfig.sslOnly)
{
AMQPFastProtocolHandler handler = new AMQPProtocolProvider().getHandler();
@@ -347,6 +365,7 @@ public class Main
{
bindAddress = new InetSocketAddress(InetAddress.getByAddress(parseIP(bindAddr)), port);
}
+
acceptor.bind(bindAddress, handler, sconfig);
_logger.info("Qpid.AMQP listening on non-SSL address " + bindAddress);
}
@@ -356,8 +375,7 @@ public class Main
AMQPFastProtocolHandler handler = new AMQPProtocolProvider().getHandler();
try
{
- acceptor.bind(new InetSocketAddress(connectorConfig.sslPort),
- handler, sconfig);
+ acceptor.bind(new InetSocketAddress(connectorConfig.sslPort), handler, sconfig);
_logger.info("Qpid.AMQP listening on SSL port " + connectorConfig.sslPort);
}
catch (IOException e)
@@ -415,16 +433,17 @@ public class Main
}
catch (NumberFormatException e)
{
- System.err.println("Log watch configuration value of " + logWatchConfig + " is invalid. Must be " +
- "a non-negative integer. Using default of zero (no watching configured");
+ System.err.println("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())
{
System.out.println("Configuring logger using configuration file " + logConfigFile.getAbsolutePath());
if (logWatchTime > 0)
{
- System.out.println("log file " + logConfigFile.getAbsolutePath() + " will be checked for changes every " +
- logWatchTime + " seconds");
+ System.out.println("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);
}
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/exchange/DestNameExchange.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/exchange/DestNameExchange.java
index 4d66e37628..de3905268e 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/exchange/DestNameExchange.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/exchange/DestNameExchange.java
@@ -196,6 +196,7 @@ public class DestNameExchange extends AbstractExchange
}
else
{
+ _logger.error("MESSAGE LOSS: Message should be sent on a Dead Letter Queue");
_logger.warn(msg);
}
}
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/handler/BasicRejectMethodHandler.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/handler/BasicRejectMethodHandler.java
index 14687c40ae..9052b2e81f 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/handler/BasicRejectMethodHandler.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/handler/BasicRejectMethodHandler.java
@@ -98,7 +98,7 @@ public class BasicRejectMethodHandler implements StateAwareMethodListener<BasicR
// If we haven't requested message to be resent to this consumer then reject it from ever getting it.
// if (!evt.getMethod().resend)
{
- message.message.reject(message.message.getDeliveredSubscription());
+ message.message.reject(message.message.getDeliveredSubscription(message.queue));
}
if (evt.getMethod().requeue)
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/handler/ConnectionOpenMethodHandler.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/handler/ConnectionOpenMethodHandler.java
index 2ecb39254f..30a40c5a75 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/handler/ConnectionOpenMethodHandler.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/handler/ConnectionOpenMethodHandler.java
@@ -33,6 +33,7 @@ import org.apache.qpid.server.state.AMQStateManager;
import org.apache.qpid.server.state.StateAwareMethodListener;
import org.apache.qpid.server.virtualhost.VirtualHost;
import org.apache.qpid.server.security.access.AccessResult;
+import org.apache.qpid.server.security.access.AccessRights;
import org.apache.log4j.Logger;
public class ConnectionOpenMethodHandler implements StateAwareMethodListener<ConnectionOpenBody>
@@ -75,23 +76,26 @@ public class ConnectionOpenMethodHandler implements StateAwareMethodListener<Con
if (virtualHost == null)
{
- throw body.getConnectionException(AMQConstant.NOT_FOUND, "Unknown virtual host: " + virtualHostName);
+ throw body.getConnectionException(AMQConstant.NOT_FOUND, "Unknown virtual host: '" + virtualHostName + "'");
}
else
{
session.setVirtualHost(virtualHost);
- AccessResult result = virtualHost.getAccessManager().isAuthorized(virtualHost, session.getAuthorizedID());
+ AccessResult result = virtualHost.getAccessManager().isAuthorized(virtualHost, session.getAuthorizedID(), AccessRights.Rights.ANY);
switch (result.getStatus())
{
default:
case REFUSED:
- throw body.getConnectionException(AMQConstant.ACCESS_REFUSED,
- "Access denied to vHost '" + virtualHostName + "' by "
- + result.getAuthorizer());
+ String error = "Any access denied to vHost '" + virtualHostName + "' by "
+ + result.getAuthorizer();
+
+ _logger.warn(error);
+
+ throw body.getConnectionException(AMQConstant.ACCESS_REFUSED, error);
case GRANTED:
- _logger.info("Granted access to vHost '" + virtualHostName + "' for " + session.getAuthorizedID()
+ _logger.info("Granted any access to vHost '" + virtualHostName + "' for " + session.getAuthorizedID()
+ " by '" + result.getAuthorizer() + "'");
}
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/handler/ConnectionSecureOkMethodHandler.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/handler/ConnectionSecureOkMethodHandler.java
index 6029a023e5..fef00942a0 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/handler/ConnectionSecureOkMethodHandler.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/handler/ConnectionSecureOkMethodHandler.java
@@ -37,6 +37,7 @@ import org.apache.qpid.server.protocol.HeartbeatConfig;
import org.apache.qpid.server.registry.ApplicationRegistry;
import org.apache.qpid.server.security.auth.manager.AuthenticationManager;
import org.apache.qpid.server.security.auth.AuthenticationResult;
+import org.apache.qpid.server.security.auth.sasl.UsernamePrincipal;
import org.apache.qpid.server.state.AMQState;
import org.apache.qpid.server.state.AMQStateManager;
import org.apache.qpid.server.state.StateAwareMethodListener;
@@ -106,7 +107,7 @@ public class ConnectionSecureOkMethodHandler implements StateAwareMethodListener
ConnectionStartOkMethodHandler.getConfiguredFrameSize(), // frameMax
HeartbeatConfig.getInstance().getDelay()); // heartbeat
session.writeFrame(tune);
- session.setAuthorizedID(ss.getAuthorizationID());
+ session.setAuthorizedID(new UsernamePrincipal(ss.getAuthorizationID()));
disposeSaslServer(session);
break;
case CONTINUE:
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/handler/ConnectionStartOkMethodHandler.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/handler/ConnectionStartOkMethodHandler.java
index 6c14aae7ed..4734143497 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/handler/ConnectionStartOkMethodHandler.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/handler/ConnectionStartOkMethodHandler.java
@@ -37,6 +37,7 @@ import org.apache.qpid.server.protocol.HeartbeatConfig;
import org.apache.qpid.server.registry.ApplicationRegistry;
import org.apache.qpid.server.security.auth.manager.AuthenticationManager;
import org.apache.qpid.server.security.auth.AuthenticationResult;
+import org.apache.qpid.server.security.auth.sasl.UsernamePrincipal;
import org.apache.qpid.server.state.AMQState;
import org.apache.qpid.server.state.AMQStateManager;
import org.apache.qpid.server.state.StateAwareMethodListener;
@@ -95,7 +96,7 @@ public class ConnectionStartOkMethodHandler implements StateAwareMethodListener<
throw new AMQException("Authentication failed");
case SUCCESS:
_logger.info("Connected as: " + ss.getAuthorizationID());
- session.setAuthorizedID(ss.getAuthorizationID());
+ session.setAuthorizedID(new UsernamePrincipal(ss.getAuthorizationID()));
stateManager.changeState(AMQState.CONNECTION_NOT_TUNED);
// AMQP version change: Hardwire the version to 0-8 (major=8, minor=0)
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/handler/QueueDeclareHandler.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/handler/QueueDeclareHandler.java
index 9e0a1019f2..2e697d4564 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/handler/QueueDeclareHandler.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/handler/QueueDeclareHandler.java
@@ -64,7 +64,6 @@ public class QueueDeclareHandler implements StateAwareMethodListener<QueueDeclar
private final AtomicInteger _counter = new AtomicInteger();
-
protected QueueDeclareHandler()
{
Configurator.configure(this);
@@ -92,12 +91,12 @@ public class QueueDeclareHandler implements StateAwareMethodListener<QueueDeclar
synchronized (queueRegistry)
{
- if (((queue = queueRegistry.getQueue(body.queue)) == null) )
+ if (((queue = queueRegistry.getQueue(body.queue)) == null))
{
- if(body.passive)
+ if (body.passive)
{
- String msg = "Queue: " + body.queue + " not found.";
- throw body.getChannelException(AMQConstant.NOT_FOUND,msg );
+ String msg = "Queue: " + body.queue + " not found on VirtualHost(" + virtualHost + ").";
+ throw body.getChannelException(AMQConstant.NOT_FOUND, msg);
}
else
{
@@ -112,13 +111,16 @@ public class QueueDeclareHandler implements StateAwareMethodListener<QueueDeclar
Exchange defaultExchange = exchangeRegistry.getDefaultExchange();
queue.bind(body.queue, null, defaultExchange);
- _log.info("Queue " + body.queue + " bound to default exchange");
+ _log.info("Queue " + body.queue + " bound to default exchange(" + defaultExchange.getName() + ")");
}
}
}
- else if(queue.getOwner() != null && !session.getContextKey().equals(queue.getOwner()))
+ else if (queue.getOwner() != null && !session.getContextKey().equals(queue.getOwner()))
{
- throw body.getChannelException(AMQConstant.ALREADY_EXISTS, "Cannot declare queue, as exclusive queue with same name declared on another connection");
+ throw body.getChannelException(AMQConstant.ALREADY_EXISTS, "Cannot declare queue('" + body.queue + "'),"
+ + " as exclusive queue with same name "
+ + "declared on another client ID('"
+ + queue.getOwner() + "')");
}
AMQChannel channel = session.getChannel(evt.getChannelId());
@@ -138,10 +140,10 @@ public class QueueDeclareHandler implements StateAwareMethodListener<QueueDeclar
// TODO: Connect this to the session version obtained from ProtocolInitiation for this session.
// Be aware of possible changes to parameter order as versions change.
AMQFrame response = QueueDeclareOkBody.createAMQFrame(evt.getChannelId(),
- (byte)8, (byte)0, // AMQP version (major, minor)
- queue.getConsumerCount(), // consumerCount
- queue.getMessageCount(), // messageCount
- body.queue); // queue
+ (byte) 8, (byte) 0, // AMQP version (major, minor)
+ queue.getConsumerCount(), // consumerCount
+ queue.getMessageCount(), // messageCount
+ body.queue); // queue
_log.info("Queue " + body.queue + " declared successfully");
session.writeFrame(response);
}
@@ -162,24 +164,22 @@ public class QueueDeclareHandler implements StateAwareMethodListener<QueueDeclar
{
final QueueRegistry registry = virtualHost.getQueueRegistry();
AMQShortString owner = body.exclusive ? session.getContextKey() : null;
- final AMQQueue queue = new AMQQueue(body.queue, body.durable, owner, body.autoDelete, virtualHost);
+ final AMQQueue queue = new AMQQueue(body.queue, body.durable, owner, body.autoDelete, virtualHost);
final AMQShortString queueName = queue.getName();
- if(body.exclusive && !body.durable)
+ if (body.exclusive && !body.durable)
{
final AMQProtocolSession.Task deleteQueueTask =
- new AMQProtocolSession.Task()
- {
-
- public void doTask(AMQProtocolSession session) throws AMQException
+ new AMQProtocolSession.Task()
{
- if(registry.getQueue(queueName) == queue)
+ public void doTask(AMQProtocolSession session) throws AMQException
{
- queue.delete();
+ if (registry.getQueue(queueName) == queue)
+ {
+ queue.delete();
+ }
}
-
- }
- };
+ };
session.addSessionCloseTask(deleteQueueTask);
@@ -190,16 +190,14 @@ public class QueueDeclareHandler implements StateAwareMethodListener<QueueDeclar
session.removeSessionCloseTask(deleteQueueTask);
}
});
-
-
- }
+ }// if exclusive and not durable
Configuration virtualHostDefaultQueueConfiguration = VirtualHostConfiguration.getDefaultQueueConfiguration(queue);
if (virtualHostDefaultQueueConfiguration != null)
{
Configurator.configure(queue, virtualHostDefaultQueueConfiguration);
}
-
+
return queue;
}
}
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/management/JMXManagedObjectRegistry.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/management/JMXManagedObjectRegistry.java
index c89529f2a3..38c9e4950a 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/management/JMXManagedObjectRegistry.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/management/JMXManagedObjectRegistry.java
@@ -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
@@ -20,29 +20,174 @@
*/
package org.apache.qpid.server.management;
+import java.io.IOException;
import java.lang.management.ManagementFactory;
+import java.rmi.RemoteException;
+import java.rmi.registry.LocateRegistry;
+import java.rmi.registry.Registry;
+import java.rmi.server.UnicastRemoteObject;
+import java.util.HashMap;
+import java.util.Map;
import javax.management.JMException;
import javax.management.MBeanServer;
+import javax.management.MBeanServerFactory;
+import javax.management.remote.JMXConnectorServer;
+import javax.management.remote.JMXConnectorServerFactory;
+import javax.management.remote.JMXServiceURL;
+import javax.management.remote.MBeanServerForwarder;
+import javax.security.auth.callback.Callback;
+import javax.security.auth.callback.CallbackHandler;
+import javax.security.auth.callback.NameCallback;
+import javax.security.auth.callback.PasswordCallback;
+import javax.security.auth.callback.UnsupportedCallbackException;
+import javax.security.auth.login.AccountNotFoundException;
+import javax.security.sasl.AuthorizeCallback;
import org.apache.log4j.Logger;
+import org.apache.qpid.AMQException;
+import org.apache.qpid.server.registry.ApplicationRegistry;
+import org.apache.qpid.server.registry.IApplicationRegistry;
+import org.apache.qpid.server.security.auth.database.PrincipalDatabase;
+import org.apache.qpid.server.security.auth.database.Base64MD5PasswordFilePrincipalDatabase;
+import org.apache.qpid.server.security.auth.database.PlainPasswordFilePrincipalDatabase;
+import org.apache.qpid.server.security.auth.sasl.UsernamePrincipal;
+import org.apache.qpid.server.security.auth.sasl.crammd5.CRAMMD5HashedInitialiser;
+
+/**
+ * This class starts up an MBeanserver. If out of the box agent is being used then there are no security features
+ * implemented. To use the security features like user authentication, turn off the jmx options in the "QPID_OPTS" env
+ * variable and use JMXMP connector server. If JMXMP connector is not available, then the standard JMXConnector will be
+ * used, which again doesn't have user authentication.
+ */
public class JMXManagedObjectRegistry implements ManagedObjectRegistry
{
private static final Logger _log = Logger.getLogger(JMXManagedObjectRegistry.class);
private final MBeanServer _mbeanServer;
+ private Registry _rmiRegistry;
+ private JMXServiceURL _jmxURL;
- public JMXManagedObjectRegistry()
+ public JMXManagedObjectRegistry() throws AMQException
{
_log.info("Initialising managed object registry using platform MBean server");
- // we use the platform MBean server currently but this must be changed or at least be configuurable
- _mbeanServer = ManagementFactory.getPlatformMBeanServer();
+ IApplicationRegistry appRegistry = ApplicationRegistry.getInstance();
+
+ // Retrieve the config parameters
+ boolean platformServer = appRegistry.getConfiguration().getBoolean("management.platform-mbeanserver", true);
+
+ _mbeanServer =
+ platformServer ? ManagementFactory.getPlatformMBeanServer()
+ : MBeanServerFactory.createMBeanServer(ManagedObject.DOMAIN);
+ }
+
+
+ public void start()
+ {
+ // Check if the "QPID_OPTS" is set to use Out of the Box JMXAgent
+ if (areOutOfTheBoxJMXOptionsSet())
+ {
+ _log.info("JMX: Using the out of the box JMX Agent");
+ return;
+ }
+
+ IApplicationRegistry appRegistry = ApplicationRegistry.getInstance();
+
+ boolean security = appRegistry.getConfiguration().getBoolean("management.security-enabled", true);
+ int port = appRegistry.getConfiguration().getInt("management.jmxport", 8999);
+
+ try
+ {
+ if (security)
+ {
+ // For SASL using JMXMP
+ _jmxURL = new JMXServiceURL("jmxmp", null, port);
+
+ Map env = new HashMap();
+ Map<String, PrincipalDatabase> map = appRegistry.getDatabaseManager().getDatabases();
+ PrincipalDatabase db = null;
+
+ for (Map.Entry<String, PrincipalDatabase> entry : map.entrySet())
+ {
+ if (entry.getValue() instanceof Base64MD5PasswordFilePrincipalDatabase)
+ {
+ db = entry.getValue();
+ break;
+ }
+ else if (entry.getValue() instanceof PlainPasswordFilePrincipalDatabase)
+ {
+ db = entry.getValue();
+ }
+ }
+
+ if (db instanceof Base64MD5PasswordFilePrincipalDatabase)
+ {
+ env.put("jmx.remote.profiles", "SASL/CRAM-MD5");
+ CRAMMD5HashedInitialiser initialiser = new CRAMMD5HashedInitialiser();
+ initialiser.initialise(db);
+ env.put("jmx.remote.sasl.callback.handler", initialiser.getCallbackHandler());
+ }
+ else if (db instanceof PlainPasswordFilePrincipalDatabase)
+ {
+ env.put("jmx.remote.profiles", "SASL/PLAIN");
+ env.put("jmx.remote.sasl.callback.handler", new UserCallbackHandler(db));
+ }
+
+ // Enable the SSL security and server authentication
+ /*
+ SslRMIClientSocketFactory csf = new SslRMIClientSocketFactory();
+ SslRMIServerSocketFactory ssf = new SslRMIServerSocketFactory();
+ env.put(RMIConnectorServer.RMI_CLIENT_SOCKET_FACTORY_ATTRIBUTE, csf);
+ env.put(RMIConnectorServer.RMI_SERVER_SOCKET_FACTORY_ATTRIBUTE, ssf);
+ */
+
+ try
+ {
+ JMXConnectorServer cs = JMXConnectorServerFactory.newJMXConnectorServer(_jmxURL, env, _mbeanServer);
+ MBeanServerForwarder mbsf = MBeanInvocationHandlerImpl.newProxyInstance();
+ cs.setMBeanServerForwarder(mbsf);
+ cs.start();
+ _log.info("JMX: Starting JMXConnector server with SASL");
+ }
+ catch (java.net.MalformedURLException urlException)
+ {
+ // When JMXMPConnector is not available
+ // java.net.MalformedURLException: Unsupported protocol: jmxmp
+ _log.info("JMX: Starting JMXConnector server");
+ startJMXConnectorServer(port);
+ }
+ }
+ else
+ {
+ startJMXConnectorServer(port);
+ }
+ }
+ catch (Exception ex)
+ {
+ _log.error("Error in initialising Managed Object Registry." + ex.getMessage());
+ ex.printStackTrace();
+ }
+ }
+
+ /**
+ * Starts up an RMIRegistry at configured port and attaches a JMXConnectorServer to it.
+ *
+ * @param port
+ *
+ * @throws IOException
+ */
+ private void startJMXConnectorServer(int port) throws IOException
+ {
+ startRMIRegistry(port);
+ _jmxURL = new JMXServiceURL("service:jmx:rmi:///jndi/rmi://localhost:" + port + "/jmxrmi");
+ JMXConnectorServer cs = JMXConnectorServerFactory.newJMXConnectorServer(_jmxURL, null, _mbeanServer);
+ cs.start();
}
public void registerObject(ManagedObject managedObject) throws JMException
{
- _mbeanServer.registerMBean(managedObject, managedObject.getObjectName());
+ _mbeanServer.registerMBean(managedObject, managedObject.getObjectName());
}
public void unregisterObject(ManagedObject managedObject) throws JMException
@@ -50,4 +195,105 @@ public class JMXManagedObjectRegistry implements ManagedObjectRegistry
_mbeanServer.unregisterMBean(managedObject.getObjectName());
}
+ /**
+ * Checks is the "QPID_OPTS" env variable is set to use the out of the box JMXAgent.
+ *
+ * @return
+ */
+ private boolean areOutOfTheBoxJMXOptionsSet()
+ {
+ if (System.getProperty("com.sun.management.jmxremote") != null)
+ {
+ return true;
+ }
+
+ if (System.getProperty("com.sun.management.jmxremote.port") != null)
+ {
+ return true;
+ }
+
+ return false;
+ }
+
+ /**
+ * Starts the rmi registry at given port
+ *
+ * @param port
+ *
+ * @throws RemoteException
+ */
+ private void startRMIRegistry(int port) throws RemoteException
+ {
+ System.setProperty("java.rmi.server.randomIDs", "true");
+ _rmiRegistry = LocateRegistry.createRegistry(port);
+ }
+
+ // stops the RMIRegistry, if it was running and bound to a port
+ public void close() throws RemoteException
+ {
+ if (_rmiRegistry != null)
+ {
+ // Stopping the RMI registry
+ UnicastRemoteObject.unexportObject(_rmiRegistry, true);
+ }
+ }
+
+ /** This class is used for SASL enabled JMXConnector for performing user authentication. */
+ private class UserCallbackHandler implements CallbackHandler
+ {
+ private final PrincipalDatabase _principalDatabase;
+
+ protected UserCallbackHandler(PrincipalDatabase database)
+ {
+ _principalDatabase = database;
+ }
+
+ public void handle(Callback[] callbacks) throws IOException, UnsupportedCallbackException
+ {
+ // Retrieve callbacks
+ NameCallback ncb = null;
+ PasswordCallback pcb = null;
+ for (int i = 0; i < callbacks.length; i++)
+ {
+ if (callbacks[i] instanceof NameCallback)
+ {
+ ncb = (NameCallback) callbacks[i];
+ }
+ else if (callbacks[i] instanceof PasswordCallback)
+ {
+ pcb = (PasswordCallback) callbacks[i];
+ }
+ else if (callbacks[i] instanceof AuthorizeCallback)
+ {
+ ((AuthorizeCallback) callbacks[i]).setAuthorized(true);
+ }
+ else
+ {
+ throw new UnsupportedCallbackException(callbacks[i]);
+ }
+ }
+
+ boolean authorized = false;
+ // Process retrieval of password; can get password if username is available in NameCallback
+ if ((ncb != null) && (pcb != null))
+ {
+ String username = ncb.getDefaultName();
+ try
+ {
+ authorized = _principalDatabase.verifyPassword(username, new String(pcb.getPassword()));
+ }
+ catch (AccountNotFoundException e)
+ {
+ IOException ioe = new IOException("User not authorized. " + e);
+ ioe.initCause(e);
+ throw ioe;
+ }
+ }
+
+ if (!authorized)
+ {
+ throw new IOException("User not authorized.");
+ }
+ }
+ }
}
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/management/MBeanInvocationHandlerImpl.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/management/MBeanInvocationHandlerImpl.java
new file mode 100644
index 0000000000..a79d993afc
--- /dev/null
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/management/MBeanInvocationHandlerImpl.java
@@ -0,0 +1,217 @@
+/*
+ *
+ * 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.management;
+
+import org.apache.qpid.AMQException;
+import org.apache.log4j.Logger;
+
+import javax.management.remote.MBeanServerForwarder;
+import javax.management.remote.JMXPrincipal;
+import javax.management.MBeanServer;
+import javax.management.ObjectName;
+import javax.management.MBeanInfo;
+import javax.management.MBeanOperationInfo;
+import javax.management.JMException;
+import javax.security.auth.Subject;
+import java.lang.reflect.InvocationHandler;
+import java.lang.reflect.Proxy;
+import java.lang.reflect.Method;
+import java.security.AccessController;
+import java.security.Principal;
+import java.security.AccessControlContext;
+import java.util.Set;
+import java.util.Properties;
+import java.util.concurrent.ConcurrentMap;
+import java.util.concurrent.ConcurrentHashMap;
+import java.io.File;
+import java.io.InputStream;
+import java.io.IOException;
+import java.io.FileInputStream;
+
+/**
+ * This class can be used by the JMXConnectorServer as an InvocationHandler for the mbean operations. This implements
+ * the logic for allowing the users to invoke MBean operations and implements the restrictions for readOnly, readWrite
+ * and admin users.
+ */
+public class MBeanInvocationHandlerImpl implements InvocationHandler
+{
+ private static final Logger _logger = Logger.getLogger(MBeanInvocationHandlerImpl.class);
+
+ public final static String ADMIN = "admin";
+ public final static String READWRITE = "readwrite";
+ public final static String READONLY = "readonly";
+ private final static String DELEGATE = "JMImplementation:type=MBeanServerDelegate";
+ private MBeanServer mbs;
+ private static Properties _userRoles = new Properties();
+
+ public static MBeanServerForwarder newProxyInstance()
+ {
+ final InvocationHandler handler = new MBeanInvocationHandlerImpl();
+ final Class[] interfaces = new Class[]{MBeanServerForwarder.class};
+
+ Object proxy = Proxy.newProxyInstance(MBeanServerForwarder.class.getClassLoader(), interfaces, handler);
+ return MBeanServerForwarder.class.cast(proxy);
+ }
+
+ public Object invoke(Object proxy, Method method, Object[] args) throws Throwable
+ {
+ final String methodName = method.getName();
+
+ if (methodName.equals("getMBeanServer"))
+ {
+ return mbs;
+ }
+
+ if (methodName.equals("setMBeanServer"))
+ {
+ if (args[0] == null)
+ {
+ throw new IllegalArgumentException("Null MBeanServer");
+ }
+ if (mbs != null)
+ {
+ throw new IllegalArgumentException("MBeanServer object already initialized");
+ }
+ mbs = (MBeanServer) args[0];
+ return null;
+ }
+
+ // Retrieve Subject from current AccessControlContext
+ AccessControlContext acc = AccessController.getContext();
+ Subject subject = Subject.getSubject(acc);
+
+ // Allow operations performed locally on behalf of the connector server itself
+ if (subject == null)
+ {
+ return method.invoke(mbs, args);
+ }
+
+ if (args == null || DELEGATE.equals(args[0]))
+ {
+ return method.invoke(mbs, args);
+ }
+
+ // Restrict access to "createMBean" and "unregisterMBean" to any user
+ if (methodName.equals("createMBean") || methodName.equals("unregisterMBean"))
+ {
+ throw new SecurityException("Access denied");
+ }
+
+ // Retrieve JMXPrincipal from Subject
+ Set<JMXPrincipal> principals = subject.getPrincipals(JMXPrincipal.class);
+ if (principals == null || principals.isEmpty())
+ {
+ throw new SecurityException("Access denied");
+ }
+
+ Principal principal = principals.iterator().next();
+ String identity = principal.getName();
+
+ // Following users can perform any operation other than "createMBean" and "unregisterMBean"
+ if (isAdmin(identity) || isAllowedToModify(identity))
+ {
+ return method.invoke(mbs, args);
+ }
+
+ // These users can only call "getAttribute" on the MBeanServerDelegate MBean
+ // Here we can add other fine grained permissions like specific method for a particular mbean
+ if (isReadOnlyUser(identity) && isReadOnlyMethod(method, args))
+ {
+ return method.invoke(mbs, args);
+ }
+
+ throw new SecurityException("Access denied");
+ }
+
+ // Initialises the user roles
+ public static void setAccessRights(Properties accessRights)
+ {
+ _userRoles = accessRights;
+ }
+
+ private boolean isAdmin(String userName)
+ {
+ if (ADMIN.equals(_userRoles.getProperty(userName)))
+ {
+ return true;
+ }
+ return false;
+ }
+
+ private boolean isAllowedToModify(String userName)
+ {
+ if (READWRITE.equals(_userRoles.getProperty(userName)))
+ {
+ return true;
+ }
+ return false;
+ }
+
+ private boolean isReadOnlyUser(String userName)
+ {
+ if (READONLY.equals(_userRoles.getProperty(userName)))
+ {
+ return true;
+ }
+ return false;
+ }
+
+ private boolean isReadOnlyMethod(Method method, Object[] args)
+ {
+ String methodName = method.getName();
+ if (methodName.equals("queryMBeans") ||
+ methodName.equals("getDefaultDomain") ||
+ methodName.equals("getMBeanInfo") ||
+ methodName.equals("getAttribute") ||
+ methodName.equals("getAttributes"))
+ {
+ return true;
+ }
+
+ if (args[0] instanceof ObjectName)
+ {
+ String mbeanMethod = (args.length > 1) ? (String) args[1] : null;
+ if (mbeanMethod == null)
+ {
+ return false;
+ }
+
+ try
+ {
+ MBeanInfo mbeanInfo = mbs.getMBeanInfo((ObjectName) args[0]);
+ if (mbeanInfo != null)
+ {
+ MBeanOperationInfo[] opInfos = mbeanInfo.getOperations();
+ for (MBeanOperationInfo opInfo : opInfos)
+ {
+ if (opInfo.getName().equals(mbeanMethod) && (opInfo.getImpact() == MBeanOperationInfo.INFO))
+ {
+ return true;
+ }
+ }
+ }
+ }
+ catch (JMException ex)
+ {
+ ex.printStackTrace();
+ }
+ }
+
+ return false;
+ }
+}
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/management/ManagedBroker.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/management/ManagedBroker.java
index b2f79b6410..45e2e91ed7 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/management/ManagedBroker.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/management/ManagedBroker.java
@@ -52,8 +52,7 @@ public interface ManagedBroker
@MBeanOperation(name="createNewExchange", description="Creates a new Exchange", impact= MBeanOperationInfo.ACTION)
void createNewExchange(@MBeanOperationParameter(name="name", description="Name of the new exchange")String name,
@MBeanOperationParameter(name="ExchangeType", description="Type of the exchange")String type,
- @MBeanOperationParameter(name="durable", description="true if the Exchang should be durable")boolean durable,
- @MBeanOperationParameter(name="passive", description="true of the Exchange should be passive")boolean passive)
+ @MBeanOperationParameter(name="durable", description="true if the Exchang should be durable")boolean durable)
throws IOException, JMException;
/**
@@ -81,8 +80,7 @@ public interface ManagedBroker
@MBeanOperation(name="createNewQueue", description="Create a new Queue on the Broker server", impact= MBeanOperationInfo.ACTION)
void createNewQueue(@MBeanOperationParameter(name="queue name", description="Name of the new queue")String queueName,
@MBeanOperationParameter(name="owner", description="Owner name")String owner,
- @MBeanOperationParameter(name="durable", description="true if the queue should be durable")boolean durable,
- @MBeanOperationParameter(name="autoDelete", description="true if the queue should be auto delete") boolean autoDelete)
+ @MBeanOperationParameter(name="durable", description="true if the queue should be durable")boolean durable)
throws IOException, JMException;
/**
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/management/ManagedObjectRegistry.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/management/ManagedObjectRegistry.java
index 32298f05e3..5f9bc9ddad 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/management/ManagedObjectRegistry.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/management/ManagedObjectRegistry.java
@@ -21,6 +21,7 @@
package org.apache.qpid.server.management;
import javax.management.JMException;
+import java.rmi.RemoteException;
/**
* Handles the registration (and unregistration and so on) of managed objects.
@@ -36,7 +37,11 @@ import javax.management.JMException;
*/
public interface ManagedObjectRegistry
{
+ void start();
+
void registerObject(ManagedObject managedObject) throws JMException;
void unregisterObject(ManagedObject managedObject) throws JMException;
+
+ void close() throws RemoteException;
}
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/management/NoopManagedObjectRegistry.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/management/NoopManagedObjectRegistry.java
index 5b86543ea6..b4fbed6948 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/management/NoopManagedObjectRegistry.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/management/NoopManagedObjectRegistry.java
@@ -24,6 +24,8 @@ import javax.management.JMException;
import org.apache.log4j.Logger;
+import java.rmi.RemoteException;
+
/**
* This managed object registry does not actually register MBeans. This can be used in tests when management is
* not required or when management has been disabled.
@@ -38,6 +40,11 @@ public class NoopManagedObjectRegistry implements ManagedObjectRegistry
_log.info("Management is disabled");
}
+ public void start()
+ {
+ //no-op
+ }
+
public void registerObject(ManagedObject managedObject) throws JMException
{
}
@@ -45,4 +52,9 @@ public class NoopManagedObjectRegistry implements ManagedObjectRegistry
public void unregisterObject(ManagedObject managedObject) throws JMException
{
}
+
+ public void close() throws RemoteException
+ {
+
+ }
}
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/protocol/AMQMinaProtocolSession.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/protocol/AMQMinaProtocolSession.java
index fd8fb2d5cb..2e62c2f1e4 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/protocol/AMQMinaProtocolSession.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/protocol/AMQMinaProtocolSession.java
@@ -28,6 +28,7 @@ import java.util.List;
import java.util.Map;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.CopyOnWriteArraySet;
+import java.security.Principal;
import javax.management.JMException;
import javax.security.sasl.SaslServer;
@@ -108,7 +109,7 @@ public class AMQMinaProtocolSession implements AMQProtocolSession,
private VersionSpecificRegistry _registry = MainRegistry.getVersionSpecificRegistry(_protocolVersion);
private List<Integer> _closingChannelsList = new ArrayList<Integer>();
private ProtocolOutputConverter _protocolOutputConverter;
- private String _authorizedID;
+ private Principal _authorizedID;
public ManagedObject getManagedObject()
@@ -745,12 +746,12 @@ public class AMQMinaProtocolSession implements AMQProtocolSession,
return _protocolOutputConverter;
}
- public void setAuthorizedID(String authorizedID)
+ public void setAuthorizedID(Principal authorizedID)
{
_authorizedID = authorizedID;
}
- public String getAuthorizedID()
+ public Principal getAuthorizedID()
{
return _authorizedID;
}
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/protocol/AMQProtocolSession.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/protocol/AMQProtocolSession.java
index 79421dd497..390117acf6 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/protocol/AMQProtocolSession.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/protocol/AMQProtocolSession.java
@@ -31,6 +31,8 @@ import org.apache.qpid.server.AMQChannel;
import org.apache.qpid.server.output.ProtocolOutputConverter;
import org.apache.qpid.server.virtualhost.VirtualHost;
+import java.security.Principal;
+
public interface AMQProtocolSession extends AMQVersionAwareProtocolSession
{
@@ -165,9 +167,9 @@ public interface AMQProtocolSession extends AMQVersionAwareProtocolSession
public ProtocolOutputConverter getProtocolOutputConverter();
- void setAuthorizedID(String authorizedID);
+ void setAuthorizedID(Principal authorizedID);
- /** @return a username string that was used to authorized this session */
- String getAuthorizedID();
+ /** @return a Principal that was used to authorized this session */
+ Principal getAuthorizedID();
}
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/protocol/AMQProtocolSessionMBean.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/protocol/AMQProtocolSessionMBean.java
index 5eebd4c524..66f928a70e 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/protocol/AMQProtocolSessionMBean.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/protocol/AMQProtocolSessionMBean.java
@@ -1,5 +1,25 @@
/*
*
+ * 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.
+ *
+ */
+/*
+ *
* Copyright (c) 2006 The Apache Software Foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
@@ -17,14 +37,15 @@
*/
package org.apache.qpid.server.protocol;
+import java.security.Principal;
import java.util.Date;
import java.util.List;
import javax.management.JMException;
import javax.management.MBeanException;
import javax.management.MBeanNotificationInfo;
-import javax.management.Notification;
import javax.management.NotCompliantMBeanException;
+import javax.management.Notification;
import javax.management.monitor.MonitorNotification;
import javax.management.openmbean.CompositeData;
import javax.management.openmbean.CompositeDataSupport;
@@ -56,15 +77,17 @@ public class AMQProtocolSessionMBean extends AMQManagedObject implements Managed
{
private AMQMinaProtocolSession _session = null;
private String _name = null;
-
- //openmbean data types for representing the channel attributes
- private final static String[] _channelAtttibuteNames = {"Channel Id", "Transactional", "Default Queue", "Unacknowledged Message Count"};
- private final static String[] _indexNames = {_channelAtttibuteNames[0]};
- private final static OpenType[] _channelAttributeTypes = {SimpleType.INTEGER, SimpleType.BOOLEAN, SimpleType.STRING, SimpleType.INTEGER};
- private static CompositeType _channelType = null; // represents the data type for channel data
- private static TabularType _channelsType = null; // Data type for list of channels type
+
+ // openmbean data types for representing the channel attributes
+ private static final String[] _channelAtttibuteNames =
+ { "Channel Id", "Transactional", "Default Queue", "Unacknowledged Message Count" };
+ private static final String[] _indexNames = { _channelAtttibuteNames[0] };
+ private static final OpenType[] _channelAttributeTypes =
+ { SimpleType.INTEGER, SimpleType.BOOLEAN, SimpleType.STRING, SimpleType.INTEGER };
+ private static CompositeType _channelType = null; // represents the data type for channel data
+ private static TabularType _channelsType = null; // Data type for list of channels type
private static final AMQShortString BROKER_MANAGEMENT_CONSOLE_HAS_CLOSED_THE_CONNECTION =
- new AMQShortString("Broker Management Console has closed the connection.");
+ new AMQShortString("Broker Management Console has closed the connection.");
@MBeanConstructor("Creates an MBean exposing an AMQ Broker Connection")
public AMQProtocolSessionMBean(AMQMinaProtocolSession session) throws NotCompliantMBeanException, OpenDataException
@@ -72,22 +95,21 @@ public class AMQProtocolSessionMBean extends AMQManagedObject implements Managed
super(ManagedConnection.class, ManagedConnection.TYPE);
_session = session;
String remote = getRemoteAddress();
- remote = "anonymous".equals(remote) ? remote + hashCode() : remote;
+ remote = "anonymous".equals(remote) ? (remote + hashCode()) : remote;
_name = jmxEncode(new StringBuffer(remote), 0).toString();
init();
}
-
static
{
try
{
init();
}
- catch(JMException ex)
+ catch (JMException ex)
{
- // It should never occur
- System.out.println(ex.getMessage());
+ // This is not expected to ever occur.
+ throw new RuntimeException("Got JMException in static initializer.", ex);
}
}
@@ -96,26 +118,27 @@ public class AMQProtocolSessionMBean extends AMQManagedObject implements Managed
*/
private static void init() throws OpenDataException
{
- _channelType = new CompositeType("Channel", "Channel Details", _channelAtttibuteNames,
- _channelAtttibuteNames, _channelAttributeTypes);
+ _channelType =
+ new CompositeType("Channel", "Channel Details", _channelAtttibuteNames, _channelAtttibuteNames,
+ _channelAttributeTypes);
_channelsType = new TabularType("Channels", "Channels", _channelType, _indexNames);
}
public String getClientId()
{
- return _session.getContextKey() == null ? null : _session.getContextKey().toString();
+ return (_session.getContextKey() == null) ? null : _session.getContextKey().toString();
}
public String getAuthorizedId()
{
- return _session.getAuthorizedID();
+ return (_session.getAuthorizedID() != null ) ? _session.getAuthorizedID().getName() : null;
}
public String getVersion()
{
- return _session.getClientVersion() == null ? null : _session.getClientVersion().toString();
+ return (_session.getClientVersion() == null) ? null : _session.getClientVersion().toString();
}
-
+
public Date getLastIoTime()
{
return new Date(_session.getIOSession().getLastIoTime());
@@ -171,6 +194,7 @@ public class AMQProtocolSessionMBean extends AMQManagedObject implements Managed
{
throw new JMException("The channel (channel Id = " + channelId + ") does not exist");
}
+
_session.commitTransactions(channel);
}
catch (AMQException ex)
@@ -194,6 +218,7 @@ public class AMQProtocolSessionMBean extends AMQManagedObject implements Managed
{
throw new JMException("The channel (channel Id = " + channelId + ") does not exist");
}
+
_session.rollbackTransactions(channel);
}
catch (AMQException ex)
@@ -215,9 +240,12 @@ public class AMQProtocolSessionMBean extends AMQManagedObject implements Managed
for (AMQChannel channel : list)
{
- Object[] itemValues = {channel.getChannelId(), channel.isTransactional(),
+ Object[] itemValues =
+ {
+ channel.getChannelId(), channel.isTransactional(),
(channel.getDefaultQueue() != null) ? channel.getDefaultQueue().getName().asString() : null,
- channel.getUnacknowledgedMessageMap().size()};
+ channel.getUnacknowledgedMessageMap().size()
+ };
CompositeData channelData = new CompositeDataSupport(_channelType, _channelAtttibuteNames, itemValues);
channelsList.put(channelData);
@@ -232,17 +260,16 @@ public class AMQProtocolSessionMBean extends AMQManagedObject implements Managed
* @throws JMException
*/
public void closeConnection() throws JMException
- {
+ {
// AMQP version change: Hardwire the version to 0-8 (major=8, minor=0)
// TODO: Connect this to the session version obtained from ProtocolInitiation for this session.
// Be aware of possible changes to parameter order as versions change.
- final AMQFrame response = ConnectionCloseBody.createAMQFrame(0,
- _session.getProtocolMajorVersion(),
- _session.getProtocolMinorVersion(), // AMQP version (major, minor)
- 0, // classId
- 0, // methodId
- AMQConstant.REPLY_SUCCESS.getCode(), // replyCode
- BROKER_MANAGEMENT_CONSOLE_HAS_CLOSED_THE_CONNECTION // replyText
+ final AMQFrame response =
+ ConnectionCloseBody.createAMQFrame(0, _session.getProtocolMajorVersion(), _session.getProtocolMinorVersion(), // AMQP version (major, minor)
+ 0, // classId
+ 0, // methodId
+ AMQConstant.REPLY_SUCCESS.getCode(), // replyCode
+ BROKER_MANAGEMENT_CONSOLE_HAS_CLOSED_THE_CONNECTION // replyText
);
_session.writeFrame(response);
@@ -259,18 +286,19 @@ public class AMQProtocolSessionMBean extends AMQManagedObject implements Managed
@Override
public MBeanNotificationInfo[] getNotificationInfo()
{
- String[] notificationTypes = new String[]{MonitorNotification.THRESHOLD_VALUE_EXCEEDED};
+ String[] notificationTypes = new String[] { MonitorNotification.THRESHOLD_VALUE_EXCEEDED };
String name = MonitorNotification.class.getName();
String description = "Channel count has reached threshold value";
MBeanNotificationInfo info1 = new MBeanNotificationInfo(notificationTypes, name, description);
- return new MBeanNotificationInfo[]{info1};
+ return new MBeanNotificationInfo[] { info1 };
}
public void notifyClients(String notificationMsg)
{
- Notification n = new Notification(MonitorNotification.THRESHOLD_VALUE_EXCEEDED, this,
- ++_notificationSequenceNumber, System.currentTimeMillis(), notificationMsg);
+ Notification n =
+ new Notification(MonitorNotification.THRESHOLD_VALUE_EXCEEDED, this, ++_notificationSequenceNumber,
+ System.currentTimeMillis(), notificationMsg);
_broadcaster.sendNotification(n);
}
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/protocol/ManagedConnection.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/protocol/ManagedConnection.java
index 990c4c0794..e6e713ac6d 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/protocol/ManagedConnection.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/protocol/ManagedConnection.java
@@ -23,6 +23,7 @@ package org.apache.qpid.server.protocol;
import java.io.IOException;
import java.util.Date;
+import java.security.Principal;
import javax.management.JMException;
import javax.management.MBeanOperationInfo;
@@ -67,16 +68,17 @@ public interface ManagedConnection
/**
* Tells the total number of bytes written till now.
* @return number of bytes written.
- */
+ *
@MBeanAttribute(name="WrittenBytes", description="The total number of bytes written till now")
Long getWrittenBytes();
-
+ */
/**
* Tells the total number of bytes read till now.
* @return number of bytes read.
- */
+ *
@MBeanAttribute(name="ReadBytes", description="The total number of bytes read till now")
Long getReadBytes();
+ */
/**
* Threshold high value for no of channels. This is useful in setting notifications or
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/AMQMessage.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/AMQMessage.java
index d6962d28cd..b2046efee3 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/AMQMessage.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/AMQMessage.java
@@ -25,6 +25,7 @@ import org.apache.qpid.framing.AMQBody;
import org.apache.qpid.framing.AMQDataBlock;
import org.apache.qpid.framing.AMQFrame;
import org.apache.qpid.framing.ContentHeaderBody;
+import org.apache.qpid.framing.FieldTable;
import org.apache.qpid.framing.abstraction.ContentChunk;
import org.apache.qpid.framing.abstraction.MessagePublishInfo;
import org.apache.qpid.framing.abstraction.ProtocolVersionMethodConverter;
@@ -42,6 +43,8 @@ import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
+import java.util.HashMap;
+import java.util.Map;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicInteger;
@@ -78,19 +81,20 @@ public class AMQMessage
private boolean _immediate;
private AtomicBoolean _taken = new AtomicBoolean(false);
-
private TransientMessageData _transientMessageData = new TransientMessageData();
private Subscription _takenBySubcription;
-
private Set<Subscription> _rejectedBy = null;
+ private Map<AMQQueue, AtomicBoolean> _takenMap = new HashMap<AMQQueue, AtomicBoolean>();
+ private Map<AMQQueue, Subscription> _takenBySubcriptionMap = new HashMap<AMQQueue, Subscription>();
- public boolean isTaken()
+ public boolean isTaken(AMQQueue queue)
{
return _taken.get();
}
private final int hashcode = System.identityHashCode(this);
+
public String debugIdentity()
{
return "(HC:" + hashcode + " ID:" + _messageId + " Ref:" + _referenceCount.get() + ")";
@@ -203,9 +207,10 @@ public class AMQMessage
_transientMessageData.setMessagePublishInfo(info);
_taken = new AtomicBoolean(false);
+
if (_log.isDebugEnabled())
{
- _log.debug("Message(" + System.identityHashCode(this) + ") created (" + debugIdentity()+")");
+ _log.debug("Message(" + System.identityHashCode(this) + ") created (" + debugIdentity() + ")");
}
}
@@ -318,8 +323,10 @@ public class AMQMessage
// enqueuing the messages ensure that if required the destinations are recorded to a
// persistent store
+
for (AMQQueue q : _transientMessageData.getDestinationQueues())
{
+ _takenMap.put(q, new AtomicBoolean(false));
_messageHandle.enqueue(storeContext, _messageId, q);
}
@@ -356,12 +363,13 @@ public class AMQMessage
}
/**
- * Creates a long-lived reference to this message, and increments the count of such references, as an atomic operation.
+ * Creates a long-lived reference to this message, and increments the count of such references, as an atomic
+ * operation.
*/
public AMQMessage takeReference()
{
_referenceCount.incrementAndGet();
- return this;
+ return this;
}
/** Threadsafe. Increment the reference count on the message. */
@@ -378,9 +386,10 @@ public class AMQMessage
* Threadsafe. This will decrement the reference count and when it reaches zero will remove the message from the
* message store.
*
+ * @param storeContext
+ *
* @throws MessageCleanupException when an attempt was made to remove the message from the message store and that
* failed
- * @param storeContext
*/
public void decrementReference(StoreContext storeContext) throws MessageCleanupException
{
@@ -451,7 +460,7 @@ public class AMQMessage
}
- public boolean taken(Subscription sub)
+ public boolean taken(AMQQueue queue, Subscription sub)
{
if (_taken.getAndSet(true))
{
@@ -464,7 +473,7 @@ public class AMQMessage
}
}
- public void release()
+ public void release(AMQQueue queue)
{
if (_log.isTraceEnabled())
{
@@ -600,7 +609,7 @@ public class AMQMessage
for (AMQQueue q : destinationQueues)
{
//Increment the references to this message for each queue delivery.
- incrementReference();
+ incrementReference();
//normal deliver so add this message at the end.
_txnContext.deliver(this, q, false);
}
@@ -824,11 +833,14 @@ public class AMQMessage
public String toString()
{
- return "Message[" + debugIdentity() + "]: " + _messageId + "; ref count: " + _referenceCount + "; taken: " +
- _taken + " by:" + _takenBySubcription;
+ return "Message[" + debugIdentity() + "]: " + _messageId + "; ref count: " + _referenceCount + "; taken : " +
+ _taken + " by :" + _takenBySubcription;
+
+// return "Message[" + debugIdentity() + "]: " + _messageId + "; ref count: " + _referenceCount + "; taken for queues: " +
+// _takenMap.toString() + " by Subs:" + _takenBySubcriptionMap.toString();
}
- public Subscription getDeliveredSubscription()
+ public Subscription getDeliveredSubscription(AMQQueue queue)
{
return _takenBySubcription;
}
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/AMQQueueMBean.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/AMQQueueMBean.java
index 7a32848c44..bbaa7379f6 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/AMQQueueMBean.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/AMQQueueMBean.java
@@ -1,5 +1,25 @@
/*
*
+ * 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.
+ *
+ */
+/*
+ *
* Copyright (c) 2006 The Apache Software Foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
@@ -17,11 +37,11 @@
*/
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 java.util.Date;
-import java.text.SimpleDateFormat;
import javax.management.JMException;
import javax.management.MBeanException;
@@ -41,12 +61,14 @@ 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.CommonContentHeaderProperties;
-import org.apache.qpid.framing.ContentHeaderBody;
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;
@@ -73,15 +95,15 @@ public class AMQQueueMBean extends AMQManagedObject implements ManagedQueue, Que
private AMQQueue _queue = null;
private String _queueName = null;
// OpenMBean data types for viewMessages method
- private final static String[] _msgAttributeNames = {"AMQ MessageId", "Header", "Size(bytes)", "Redelivered"};
- private static String[] _msgAttributeIndex = {_msgAttributeNames[0]};
+ private static final String[] _msgAttributeNames = { "AMQ MessageId", "Header", "Size(bytes)", "Redelivered" };
+ private static String[] _msgAttributeIndex = { _msgAttributeNames[0] };
private static OpenType[] _msgAttributeTypes = new OpenType[4]; // AMQ message attribute types.
- private static CompositeType _messageDataType = null; // Composite type for representing AMQ Message data.
- private static TabularType _messagelistDataType = null; // Datatype for representing AMQ messages list.
+ private static CompositeType _messageDataType = null; // Composite type for representing AMQ Message data.
+ private static TabularType _messagelistDataType = null; // Datatype for representing AMQ messages list.
// OpenMBean data types for viewMessageContent method
private static CompositeType _msgContentType = null;
- private final static String[] _msgContentAttributes = {"AMQ MessageId", "MimeType", "Encoding", "Content"};
+ private static final String[] _msgContentAttributes = { "AMQ MessageId", "MimeType", "Encoding", "Content" };
private static OpenType[] _msgContentAttributeTypes = new OpenType[4];
private final long[] _lastNotificationTimes = new long[NotificationCheck.values().length];
@@ -95,7 +117,6 @@ public class AMQQueueMBean extends AMQManagedObject implements ManagedQueue, Que
_queueName = jmxEncode(new StringBuffer(queue.getName()), 0).toString();
}
-
public ManagedObject getParentObject()
{
return _queue.getVirtualHost().getManagedObject();
@@ -107,10 +128,10 @@ public class AMQQueueMBean extends AMQManagedObject implements ManagedQueue, Que
{
init();
}
- catch(JMException ex)
+ catch (JMException ex)
{
- // It should never occur
- System.out.println(ex.getMessage());
+ // This is not expected to ever occur.
+ throw new RuntimeException("Got JMException in static initializer.", ex);
}
}
@@ -119,19 +140,21 @@ public class AMQQueueMBean extends AMQManagedObject implements ManagedQueue, Que
*/
private static void init() throws OpenDataException
{
- _msgContentAttributeTypes[0] = SimpleType.LONG; // For message id
- _msgContentAttributeTypes[1] = SimpleType.STRING; // For MimeType
- _msgContentAttributeTypes[2] = SimpleType.STRING; // For Encoding
- _msgContentAttributeTypes[3] = new ArrayType(1, SimpleType.BYTE); // For message content
- _msgContentType = new CompositeType("Message Content", "AMQ Message Content", _msgContentAttributes,
- _msgContentAttributes, _msgContentAttributeTypes);
-
- _msgAttributeTypes[0] = SimpleType.LONG; // For message id
- _msgAttributeTypes[1] = new ArrayType(1, SimpleType.STRING); // For header attributes
- _msgAttributeTypes[2] = SimpleType.LONG; // For size
- _msgAttributeTypes[3] = SimpleType.BOOLEAN; // For redelivered
-
- _messageDataType = new CompositeType("Message", "AMQ Message", _msgAttributeNames, _msgAttributeNames, _msgAttributeTypes);
+ _msgContentAttributeTypes[0] = SimpleType.LONG; // For message id
+ _msgContentAttributeTypes[1] = SimpleType.STRING; // For MimeType
+ _msgContentAttributeTypes[2] = SimpleType.STRING; // For Encoding
+ _msgContentAttributeTypes[3] = new ArrayType(1, SimpleType.BYTE); // For message content
+ _msgContentType =
+ new CompositeType("Message Content", "AMQ Message Content", _msgContentAttributes, _msgContentAttributes,
+ _msgContentAttributeTypes);
+
+ _msgAttributeTypes[0] = SimpleType.LONG; // For message id
+ _msgAttributeTypes[1] = new ArrayType(1, SimpleType.STRING); // For header attributes
+ _msgAttributeTypes[2] = SimpleType.LONG; // For size
+ _msgAttributeTypes[3] = SimpleType.BOOLEAN; // For redelivered
+
+ _messageDataType =
+ new CompositeType("Message", "AMQ Message", _msgAttributeNames, _msgAttributeNames, _msgAttributeTypes);
_messagelistDataType = new TabularType("Messages", "List of messages", _messageDataType, _msgAttributeIndex);
}
@@ -213,7 +236,8 @@ public class AMQQueueMBean extends AMQManagedObject implements ManagedQueue, Que
public Long getMaximumQueueDepth()
{
long queueDepthInBytes = _queue.getMaximumQueueDepth();
- return queueDepthInBytes >> 10 ;
+
+ return queueDepthInBytes >> 10;
}
public void setMaximumQueueDepth(Long value)
@@ -227,7 +251,8 @@ public class AMQQueueMBean extends AMQManagedObject implements ManagedQueue, Que
public Long getQueueDepth() throws JMException
{
long queueBytesSize = _queue.getQueueDepth();
- return queueBytesSize >> 10 ;
+
+ return queueBytesSize >> 10;
}
/**
@@ -237,13 +262,13 @@ public class AMQQueueMBean extends AMQManagedObject implements ManagedQueue, Que
{
final long currentTime = System.currentTimeMillis();
- final long thresholdTime = currentTime - _queue.getMinimumAlertRepeatGap();
+ final long thresholdTime = currentTime - _queue.getMinimumAlertRepeatGap();
- for(NotificationCheck check : NotificationCheck.values())
+ for (NotificationCheck check : NotificationCheck.values())
{
- if(check.isMessageSpecific() || _lastNotificationTimes[check.ordinal()]<thresholdTime)
+ if (check.isMessageSpecific() || (_lastNotificationTimes[check.ordinal()] < thresholdTime))
{
- if(check.notifyIfNecessary(msg, _queue, this))
+ if (check.notifyIfNecessary(msg, _queue, this))
{
_lastNotificationTimes[check.ordinal()] = currentTime;
}
@@ -260,9 +285,10 @@ public class AMQQueueMBean extends AMQManagedObject implements ManagedQueue, Que
// important : add log to the log file - monitoring tools may be looking for this
_logger.info(notification.name() + " On Queue " + queue.getName() + " - " + notificationMsg);
notificationMsg = notification.name() + " " + notificationMsg;
-
- _lastNotification = new Notification(MonitorNotification.THRESHOLD_VALUE_EXCEEDED, this,
- ++_notificationSequenceNumber, System.currentTimeMillis(), notificationMsg);
+
+ _lastNotification =
+ new Notification(MonitorNotification.THRESHOLD_VALUE_EXCEEDED, this, ++_notificationSequenceNumber,
+ System.currentTimeMillis(), notificationMsg);
_broadcaster.sendNotification(_lastNotification);
}
@@ -334,20 +360,25 @@ public class AMQQueueMBean extends AMQManagedObject implements ManagedQueue, Que
try
{
// Create header attributes list
- CommonContentHeaderProperties headerProperties = (CommonContentHeaderProperties) msg.getContentHeaderBody().properties;
+ CommonContentHeaderProperties headerProperties =
+ (CommonContentHeaderProperties) msg.getContentHeaderBody().properties;
String mimeType = null, encoding = null;
if (headerProperties != null)
{
AMQShortString mimeTypeShortSting = headerProperties.getContentType();
- mimeType = mimeTypeShortSting == null ? null : mimeTypeShortSting.toString();
- encoding = headerProperties.getEncoding() == null ? "" : headerProperties.getEncoding().toString();
+ mimeType = (mimeTypeShortSting == null) ? null : mimeTypeShortSting.toString();
+ encoding = (headerProperties.getEncoding() == null) ? "" : headerProperties.getEncoding().toString();
}
- Object[] itemValues = {msgId, mimeType, encoding, msgContent.toArray(new Byte[0])};
+
+ Object[] itemValues = { msgId, mimeType, encoding, msgContent.toArray(new Byte[0]) };
+
return new CompositeDataSupport(_msgContentType, _msgContentAttributes, itemValues);
}
catch (AMQException e)
{
- throw new JMException("Error creating header attributes list: " + e);
+ JMException jme = new JMException("Error creating header attributes list: " + e);
+ jme.initCause(e);
+ throw jme;
}
}
@@ -358,8 +389,8 @@ public class AMQQueueMBean extends AMQManagedObject implements ManagedQueue, Que
{
if ((beginIndex > endIndex) || (beginIndex < 1))
{
- throw new OperationsException("From Index = " + beginIndex + ", To Index = " + endIndex +
- "\n\"From Index\" should be greater than 0 and less than \"To Index\"");
+ throw new OperationsException("From Index = " + beginIndex + ", To Index = " + endIndex
+ + "\n\"From Index\" should be greater than 0 and less than \"To Index\"");
}
List<AMQMessage> list = _queue.getMessagesOnTheQueue();
@@ -368,20 +399,22 @@ public class AMQQueueMBean extends AMQManagedObject implements ManagedQueue, Que
try
{
// Create the tabular list of message header contents
- for (int i = beginIndex; i <= endIndex && i <= list.size(); i++)
+ for (int i = beginIndex; (i <= endIndex) && (i <= list.size()); i++)
{
AMQMessage msg = list.get(i - 1);
ContentHeaderBody headerBody = msg.getContentHeaderBody();
// Create header attributes list
String[] headerAttributes = getMessageHeaderProperties(headerBody);
- Object[] itemValues = {msg.getMessageId(), headerAttributes, headerBody.bodySize, msg.isRedelivered()};
+ Object[] itemValues = { msg.getMessageId(), headerAttributes, headerBody.bodySize, msg.isRedelivered() };
CompositeData messageData = new CompositeDataSupport(_messageDataType, _msgAttributeNames, itemValues);
_messageList.put(messageData);
}
}
catch (AMQException e)
{
- throw new JMException("Error creating message contents: " + e);
+ JMException jme = new JMException("Error creating message contents: " + e);
+ jme.initCause(e);
+ throw jme;
}
return _messageList;
@@ -400,11 +433,11 @@ public class AMQQueueMBean extends AMQManagedObject implements ManagedQueue, Que
list.add("JMSCorrelationID = " + headerProperties.getCorrelationIdAsString());
int delMode = headerProperties.getDeliveryMode();
- list.add("JMSDeliveryMode = " + (delMode == 1 ? "Persistent" : "Non_Persistent"));
+ list.add("JMSDeliveryMode = " + ((delMode == 1) ? "Persistent" : "Non_Persistent"));
list.add("JMSPriority = " + headerProperties.getPriority());
list.add("JMSType = " + headerProperties.getType());
-
+
long longDate = headerProperties.getExpiration();
String strDate = (longDate != 0) ? _dateFormat.format(new Date(longDate)) : null;
list.add("JMSExpiration = " + strDate);
@@ -425,27 +458,26 @@ public class AMQQueueMBean extends AMQManagedObject implements ManagedQueue, Que
*/
public void moveMessages(long fromMessageId, long toMessageId, String toQueueName) throws JMException
{
- if (fromMessageId > toMessageId || (fromMessageId < 1))
+ if ((fromMessageId > toMessageId) || (fromMessageId < 1))
{
- throw new OperationsException("\"From MessageId\" should be greater then 0 and less then \"To MessageId\"");
+ throw new OperationsException("\"From MessageId\" should be greater then 0 and less then \"To MessageId\"");
}
_queue.moveMessagesToAnotherQueue(fromMessageId, toMessageId, toQueueName, _storeContext);
}
-
/**
* returns Notifications sent by this MBean.
*/
@Override
public MBeanNotificationInfo[] getNotificationInfo()
{
- String[] notificationTypes = new String[]{MonitorNotification.THRESHOLD_VALUE_EXCEEDED};
+ String[] notificationTypes = new String[] { MonitorNotification.THRESHOLD_VALUE_EXCEEDED };
String name = MonitorNotification.class.getName();
String description = "Either Message count or Queue depth or Message size has reached threshold high value";
MBeanNotificationInfo info1 = new MBeanNotificationInfo(notificationTypes, name, description);
- return new MBeanNotificationInfo[]{info1};
+ return new MBeanNotificationInfo[] { info1 };
}
} // End of AMQQueueMBean class
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/ConcurrentSelectorDeliveryManager.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/ConcurrentSelectorDeliveryManager.java
index cfa13c87fd..979f692361 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/ConcurrentSelectorDeliveryManager.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/ConcurrentSelectorDeliveryManager.java
@@ -210,6 +210,7 @@ public class ConcurrentSelectorDeliveryManager implements DeliveryManager
/**
* Returns all the messages in the Queue
+ *
* @return List of messages
*/
public List<AMQMessage> getMessages()
@@ -222,14 +223,16 @@ public class ConcurrentSelectorDeliveryManager implements DeliveryManager
list.add(message);
}
_lock.unlock();
-
+
return list;
}
/**
* Returns messages within the range of given messageIds
+ *
* @param fromMessageId
* @param toMessageId
+ *
* @return
*/
public List<AMQMessage> getMessages(long fromMessageId, long toMessageId)
@@ -242,7 +245,7 @@ public class ConcurrentSelectorDeliveryManager implements DeliveryManager
long maxMessageCount = toMessageId - fromMessageId + 1;
_lock.lock();
-
+
List<AMQMessage> foundMessagesList = new ArrayList<AMQMessage>();
for (AMQMessage message : _messages)
@@ -399,7 +402,7 @@ public class ConcurrentSelectorDeliveryManager implements DeliveryManager
public void removeAMessageFromTop(StoreContext storeContext) throws AMQException
{
_lock.lock();
-
+
AMQMessage message = _messages.poll();
if (message != null)
{
@@ -432,9 +435,7 @@ public class ConcurrentSelectorDeliveryManager implements DeliveryManager
return count;
}
- /**
- This can only be used to clear the _messages queue. Any subscriber resend queue will not be purged.
- */
+ /** This can only be used to clear the _messages queue. Any subscriber resend queue will not be purged. */
private AMQMessage getNextMessage() throws AMQException
{
return getNextMessage(_messages, null);
@@ -444,8 +445,12 @@ public class ConcurrentSelectorDeliveryManager implements DeliveryManager
{
AMQMessage message = messages.peek();
- //while (we have a message) && (The subscriber is not a browser or we are clearing) && (Check message is taken.)
- while (message != null && (sub != null && !sub.isBrowser() || sub == null) && message.taken(sub))
+ //while (we have a message) && ((The subscriber is not a browser or message is taken ) or we are clearing) && (Check message is taken.)
+ while (message != null
+ && (
+ ((sub != null && !sub.isBrowser()) || message.isTaken(_queue))
+ || sub == null)
+ && message.taken(_queue, sub))
{
//remove the already taken message
AMQMessage removed = messages.poll();
@@ -506,7 +511,7 @@ public class ConcurrentSelectorDeliveryManager implements DeliveryManager
}
if (_log.isDebugEnabled())
{
- _log.debug(debugIdentity() + "Async Delivery Message " + message.getMessageId() + "(" + System.identityHashCode(message) +
+ _log.debug(debugIdentity() + "Async Delivery Message :" + message + "(" + System.identityHashCode(message) +
") by :" + System.identityHashCode(this) +
") to :" + System.identityHashCode(sub));
}
@@ -526,7 +531,7 @@ public class ConcurrentSelectorDeliveryManager implements DeliveryManager
if (_log.isDebugEnabled())
{
- _log.debug(debugIdentity() + "Async Delivered Message r:" + removed.debugIdentity() + "d:" + message.debugIdentity() +
+ _log.debug(debugIdentity() + "Async Delivered Message r:" + removed.debugIdentity() + "d:" + message +
") by :" + System.identityHashCode(this) +
") to :" + System.identityHashCode(sub));
}
@@ -562,7 +567,7 @@ public class ConcurrentSelectorDeliveryManager implements DeliveryManager
}
catch (AMQException e)
{
- message.release();
+ message.release(_queue);
_log.error(debugIdentity() + "Unable to deliver message as dequeue failed: " + e, e);
}
}
@@ -723,7 +728,7 @@ public class ConcurrentSelectorDeliveryManager implements DeliveryManager
_log.trace(debugIdentity() + "Delivering Message:" + msg.debugIdentity() + " to(" +
System.identityHashCode(s) + ") :" + s);
}
- msg.taken(s);
+ msg.taken(_queue, s);
//Deliver the message
s.send(msg, _queue);
}
@@ -737,7 +742,7 @@ public class ConcurrentSelectorDeliveryManager implements DeliveryManager
}
}
- if (!msg.isTaken())
+ if (!msg.isTaken(_queue))
{
if (_log.isInfoEnabled())
{
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/SubscriptionImpl.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/SubscriptionImpl.java
index d3578d39e8..e3944954f3 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/SubscriptionImpl.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/SubscriptionImpl.java
@@ -558,7 +558,7 @@ public class SubscriptionImpl implements Subscription
_logger.trace("Removed for resending:" + resent.debugIdentity());
}
- resent.release();
+ resent.release(_queue);
_queue.subscriberHasPendingResend(false, this, resent);
try
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/registry/ApplicationRegistry.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/registry/ApplicationRegistry.java
index 14a8063aee..89f0b7b39d 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/registry/ApplicationRegistry.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/registry/ApplicationRegistry.java
@@ -153,7 +153,7 @@ public abstract class ApplicationRegistry implements IApplicationRegistry
{
_logger.error("Error configuring application: " + e, e);
//throw new AMQBrokerCreationException(instanceID, "Unable to create Application Registry instance " + instanceID);
- throw new RuntimeException("Unable to create Application Registry");
+ throw new RuntimeException("Unable to create Application Registry", e);
}
}
else
@@ -168,6 +168,12 @@ public abstract class ApplicationRegistry implements IApplicationRegistry
{
virtualHost.close();
}
+
+ // close the rmi registry(if any) started for management
+ if (getInstance().getManagedObjectRegistry() != null)
+ {
+ getInstance().getManagedObjectRegistry().close();
+ }
}
public Configuration getConfiguration()
@@ -187,7 +193,7 @@ public abstract class ApplicationRegistry implements IApplicationRegistry
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");
+ throw new IllegalArgumentException("Unable to instantiate configuration class " + instanceType + " - ensure it has a public default constructor", e);
}
Configurator.configure(instance);
_configuredObjects.put(instanceType, instance);
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/registry/ConfigurationFileApplicationRegistry.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/registry/ConfigurationFileApplicationRegistry.java
index 739ed9db42..1cca259a8d 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/registry/ConfigurationFileApplicationRegistry.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/registry/ConfigurationFileApplicationRegistry.java
@@ -42,6 +42,7 @@ import org.apache.qpid.server.security.access.AccessManager;
import org.apache.qpid.server.security.access.AccessManagerImpl;
import org.apache.qpid.server.virtualhost.VirtualHost;
import org.apache.qpid.server.virtualhost.VirtualHostRegistry;
+import org.apache.qpid.AMQException;
public class ConfigurationFileApplicationRegistry extends ApplicationRegistry
{
@@ -103,6 +104,7 @@ public class ConfigurationFileApplicationRegistry extends ApplicationRegistry
public void initialise() throws Exception
{
initialiseManagedObjectRegistry();
+
_virtualHostRegistry = new VirtualHostRegistry();
_accessManager = new AccessManagerImpl("default", _configuration);
@@ -111,7 +113,12 @@ public class ConfigurationFileApplicationRegistry extends ApplicationRegistry
_authenticationManager = new PrincipalDatabaseAuthenticationManager(null, null);
+ _databaseManager.initialiseManagement(_configuration);
+
+ _managedObjectRegistry.start();
+
initialiseVirtualHosts();
+
}
private void initialiseVirtualHosts() throws Exception
@@ -123,7 +130,7 @@ public class ConfigurationFileApplicationRegistry extends ApplicationRegistry
}
}
- private void initialiseManagedObjectRegistry()
+ private void initialiseManagedObjectRegistry() throws AMQException
{
ManagementConfiguration config = getConfiguredObject(ManagementConfiguration.class);
if (config.enabled)
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/Passwd.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/Passwd.java
new file mode 100644
index 0000000000..f9e093dba7
--- /dev/null
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/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.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 <username> <password>");
+ 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/qpid/java/broker/src/main/java/org/apache/qpid/server/security/access/AMQUserManagementMBean.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/access/AMQUserManagementMBean.java
new file mode 100644
index 0000000000..a43474559d
--- /dev/null
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/access/AMQUserManagementMBean.java
@@ -0,0 +1,457 @@
+/*
+ * 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.access;
+
+import org.apache.qpid.server.management.MBeanDescription;
+import org.apache.qpid.server.management.AMQManagedObject;
+import org.apache.qpid.server.management.MBeanOperationParameter;
+import org.apache.qpid.server.management.MBeanOperation;
+import org.apache.qpid.server.management.MBeanInvocationHandlerImpl;
+import org.apache.qpid.server.security.auth.database.PrincipalDatabase;
+import org.apache.qpid.server.security.auth.sasl.UsernamePrincipal;
+import org.apache.log4j.Logger;
+import org.apache.commons.configuration.ConfigurationException;
+
+import javax.management.JMException;
+import javax.management.openmbean.TabularData;
+import javax.management.openmbean.TabularDataSupport;
+import javax.management.openmbean.TabularType;
+import javax.management.openmbean.SimpleType;
+import javax.management.openmbean.CompositeType;
+import javax.management.openmbean.OpenType;
+import javax.management.openmbean.OpenDataException;
+import javax.management.openmbean.CompositeData;
+import javax.management.openmbean.CompositeDataSupport;
+import javax.security.auth.login.AccountNotFoundException;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.FileOutputStream;
+import java.util.Properties;
+import java.util.List;
+import java.util.Enumeration;
+import java.util.concurrent.locks.ReentrantLock;
+import java.security.Principal;
+
+/** MBean class for AMQUserManagementMBean. It implements all the management features exposed for managing users. */
+@MBeanDescription("User Management Interface")
+public class AMQUserManagementMBean extends AMQManagedObject implements UserManagement
+{
+
+ private static final Logger _logger = Logger.getLogger(AMQUserManagementMBean.class);
+
+ private PrincipalDatabase _principalDatabase;
+ private String _accessFileName;
+ private Properties _accessRights;
+ // private File _accessFile;
+ private ReentrantLock _accessRightsUpdate = new ReentrantLock();
+
+ // Setup for the TabularType
+ static TabularType _userlistDataType; // Datatype for representing User Lists
+
+ static CompositeType _userDataType; // Composite type for representing User
+ static String[] _userItemNames = {"Username", "Read", "Write", "Admin"};
+
+ static
+ {
+ String[] userItemDesc = {"Broker Login username", "Management Console Read Permission",
+ "Management Console Write Permission", "Management Console Admin Permission"};
+
+ OpenType[] userItemTypes = new OpenType[4]; // User item types.
+ userItemTypes[0] = SimpleType.STRING; // For Username
+ userItemTypes[1] = SimpleType.BOOLEAN; // For Rights - Read
+ userItemTypes[2] = SimpleType.BOOLEAN; // For Rights - Write
+ userItemTypes[3] = SimpleType.BOOLEAN; // For Rights - Admin
+ String[] userDataIndex = {_userItemNames[0]};
+
+ try
+ {
+ _userDataType =
+ new CompositeType("User", "User Data", _userItemNames, userItemDesc, userItemTypes);
+
+ _userlistDataType = new TabularType("Users", "List of users", _userDataType, userDataIndex);
+ }
+ catch (OpenDataException e)
+ {
+ _logger.error("Tabular data setup for viewing users incorrect.");
+ _userlistDataType = null;
+ }
+ }
+
+
+ public AMQUserManagementMBean() throws JMException
+ {
+ super(UserManagement.class, UserManagement.TYPE);
+ }
+
+ public String getObjectInstanceName()
+ {
+ return UserManagement.TYPE;
+ }
+
+ public boolean setPassword(@MBeanOperationParameter(name = "username", description = "Username")String username,
+ @MBeanOperationParameter(name = "password", description = "Password")String password)
+ {
+ try
+ {
+ //delegate password changes to the Principal Database
+ return _principalDatabase.updatePassword(new UsernamePrincipal(username), password);
+ }
+ catch (AccountNotFoundException e)
+ {
+ _logger.warn("Attempt to set password of non-existant user'" + username + "'");
+ return false;
+ }
+ }
+
+ public boolean setRights(@MBeanOperationParameter(name = "username", description = "Username")String username,
+ @MBeanOperationParameter(name = "read", description = "Administration read")boolean read,
+ @MBeanOperationParameter(name = "write", description = "Administration write")boolean write,
+ @MBeanOperationParameter(name = "admin", description = "Administration rights")boolean admin)
+ {
+
+ if (_accessRights.get(username) == null)
+ {
+ // If the user doesn't exist in the user rights file check that they at least have an account.
+ if (_principalDatabase.getUser(username) == null)
+ {
+ return false;
+ }
+ }
+
+ try
+ {
+
+ _accessRightsUpdate.lock();
+
+ // Update the access rights
+ if (admin)
+ {
+ _accessRights.put(username, MBeanInvocationHandlerImpl.ADMIN);
+ }
+ else
+ {
+ if (read | write)
+ {
+ if (read)
+ {
+ _accessRights.put(username, MBeanInvocationHandlerImpl.READONLY);
+ }
+ if (write)
+ {
+ _accessRights.put(username, MBeanInvocationHandlerImpl.READWRITE);
+ }
+ }
+ else
+ {
+ _accessRights.remove(username);
+ }
+ }
+
+ saveAccessFile();
+ }
+ finally
+ {
+ if (_accessRightsUpdate.isHeldByCurrentThread())
+ {
+ _accessRightsUpdate.unlock();
+ }
+ }
+
+ return true;
+ }
+
+ public boolean createUser(@MBeanOperationParameter(name = "username", description = "Username")String username,
+ @MBeanOperationParameter(name = "password", description = "Password")String password,
+ @MBeanOperationParameter(name = "read", description = "Administration read")boolean read,
+ @MBeanOperationParameter(name = "write", description = "Administration write")boolean write,
+ @MBeanOperationParameter(name = "admin", description = "Administration rights")boolean admin)
+ {
+ if (_principalDatabase.createPrincipal(new UsernamePrincipal(username), password))
+ {
+ _accessRights.put(username, "");
+
+ return setRights(username, read, write, admin);
+ }
+
+ return false;
+ }
+
+ public boolean deleteUser(@MBeanOperationParameter(name = "username", description = "Username")String username)
+ {
+
+ try
+ {
+ if (_principalDatabase.deletePrincipal(new UsernamePrincipal(username)))
+ {
+ try
+ {
+ _accessRightsUpdate.lock();
+
+ _accessRights.remove(username);
+ saveAccessFile();
+ }
+ finally
+ {
+ if (_accessRightsUpdate.isHeldByCurrentThread())
+ {
+ _accessRightsUpdate.unlock();
+ }
+ }
+ return true;
+ }
+ }
+ catch (AccountNotFoundException e)
+ {
+ _logger.warn("Attempt to delete user (" + username + ") that doesn't exist");
+ }
+
+ return false;
+ }
+
+ public boolean reloadData()
+ {
+ try
+ {
+ try
+ {
+ loadAccessFile();
+ }
+ catch (ConfigurationException e)
+ {
+ _logger.info("Reload failed due to:" + e);
+ return false;
+ }
+
+ // Reload successful
+ return true;
+ }
+ catch (IOException e)
+ {
+ _logger.info("Reload failed due to:" + e);
+ // Reload unsuccessful
+ return false;
+ }
+ }
+
+
+ @MBeanOperation(name = "viewUsers", description = "All users with access rights to the system.")
+ public TabularData viewUsers()
+ {
+ // Table of users
+ // Username(string), Access rights Read,Write,Admin(bool,bool,bool)
+
+ reloadData();
+
+ if (_userlistDataType == null)
+ {
+ _logger.warn("TabluarData not setup correctly");
+ return null;
+ }
+
+ List<Principal> users = _principalDatabase.getUsers();
+
+ TabularDataSupport userList = new TabularDataSupport(_userlistDataType);
+
+ try
+ {
+ // Create the tabular list of message header contents
+ for (Principal user : users)
+ {
+ // Create header attributes list
+
+ String rights = (String) _accessRights.get(user.getName());
+
+ Boolean read = false;
+ Boolean write = false;
+ Boolean admin = false;
+
+ if (rights != null)
+ {
+ read = rights.equals(MBeanInvocationHandlerImpl.READONLY)
+ || rights.equals(MBeanInvocationHandlerImpl.READWRITE);
+ write = rights.equals(MBeanInvocationHandlerImpl.READWRITE);
+ admin = rights.equals(MBeanInvocationHandlerImpl.ADMIN);
+ }
+
+ Object[] itemData = {user.getName(), read, write, admin};
+ CompositeData messageData = new CompositeDataSupport(_userDataType, _userItemNames, itemData);
+ userList.put(messageData);
+ }
+ }
+ catch (OpenDataException e)
+ {
+ _logger.warn("Unable to create user list due to :" + e);
+ return null;
+ }
+
+ return userList;
+ }
+
+ /*** Broker Methods **/
+
+ /**
+ * setPrincipalDatabase
+ *
+ * @param database set The Database to use for user lookup
+ */
+ public void setPrincipalDatabase(PrincipalDatabase database)
+ {
+ _principalDatabase = database;
+ }
+
+ /**
+ * setAccessFile
+ *
+ * @param accessFile the file to use for updating.
+ *
+ * @throws java.io.IOException If the file cannot be accessed
+ * @throws org.apache.commons.configuration.ConfigurationException
+ * if checks on the file fail.
+ */
+ public void setAccessFile(String accessFile) throws IOException, ConfigurationException
+ {
+ _accessFileName = accessFile;
+
+ if (_accessFileName != null)
+ {
+ loadAccessFile();
+ }
+ else
+ {
+ _logger.warn("Access rights file specified is null. Access rights not changed.");
+ }
+ }
+
+ private void loadAccessFile() throws IOException, ConfigurationException
+ {
+ try
+ {
+ _accessRightsUpdate.lock();
+
+ Properties accessRights = new Properties();
+
+ File accessFile = new File(_accessFileName);
+
+ if (!accessFile.exists())
+ {
+ throw new ConfigurationException("'" + _accessFileName + "' does not exist");
+ }
+
+ if (!accessFile.canRead())
+ {
+ throw new ConfigurationException("Cannot read '" + _accessFileName + "'.");
+ }
+
+ if (!accessFile.canWrite())
+ {
+ _logger.warn("Unable to write to access file '" + _accessFileName + "' changes will not be preserved.");
+ }
+
+ accessRights.load(new FileInputStream(accessFile));
+ checkAccessRights(accessRights);
+ setAccessRights(accessRights);
+ }
+ finally
+ {
+ if (_accessRightsUpdate.isHeldByCurrentThread())
+ {
+ _accessRightsUpdate.unlock();
+ }
+ }
+ }
+
+ private void checkAccessRights(Properties accessRights)
+ {
+ Enumeration values = accessRights.propertyNames();
+
+ while (values.hasMoreElements())
+ {
+ String user = (String) values.nextElement();
+
+ if (_principalDatabase.getUser(user) == null)
+ {
+ _logger.warn("Access rights contains user '" + user + "' but there is no authentication data for that user");
+ }
+ }
+ }
+
+ private void saveAccessFile()
+ {
+ try
+ {
+ _accessRightsUpdate.lock();
+ try
+ {
+ // remove old temporary file
+ File tmp = new File(_accessFileName + ".tmp");
+ if (tmp.exists())
+ {
+ tmp.delete();
+ }
+
+ //remove old backup
+ File old = new File(_accessFileName + ".old");
+ if (old.exists())
+ {
+ old.delete();
+ }
+
+ // Rename current file
+ File rights = new File(_accessFileName);
+ rights.renameTo(old);
+
+ FileOutputStream output = new FileOutputStream(tmp);
+ _accessRights.store(output, "");
+ output.close();
+
+ // Rename new file to main file
+ tmp.renameTo(rights);
+
+ // delete tmp
+ tmp.delete();
+ }
+ catch (IOException e)
+ {
+ _logger.warn("Problem occured saving '" + _accessFileName + "' changes may not be preserved. :" + e);
+ }
+ }
+ finally
+ {
+ if (_accessRightsUpdate.isHeldByCurrentThread())
+ {
+ _accessRightsUpdate.unlock();
+ }
+ }
+ }
+
+ /**
+ * user=read user=write user=readwrite user=admin
+ *
+ * @param accessRights The properties list of access rights to process
+ */
+ private void setAccessRights(Properties accessRights)
+ {
+ _logger.debug("Setting Access Rights:" + accessRights);
+ _accessRights = accessRights;
+ MBeanInvocationHandlerImpl.setAccessRights(_accessRights);
+ }
+}
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/access/AccessManager.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/access/AccessManager.java
index 0c0de88182..d70a6dc8f4 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/access/AccessManager.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/access/AccessManager.java
@@ -20,8 +20,13 @@
*/
package org.apache.qpid.server.security.access;
+import java.security.Principal;
+
public interface AccessManager
{
+ AccessResult isAuthorized(Accessable accessObject, Principal username, AccessRights.Rights rights);
+
+ @Deprecated
AccessResult isAuthorized(Accessable accessObject, String username);
String getName();
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/access/AccessManagerImpl.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/access/AccessManagerImpl.java
index 0feb2791da..35d036d20f 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/access/AccessManagerImpl.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/access/AccessManagerImpl.java
@@ -23,13 +23,13 @@ package org.apache.qpid.server.security.access;
import org.apache.commons.configuration.Configuration;
import org.apache.commons.configuration.ConfigurationException;
import org.apache.qpid.server.registry.ApplicationRegistry;
+import org.apache.qpid.server.security.auth.sasl.UsernamePrincipal;
import org.apache.qpid.configuration.PropertyUtils;
-import org.apache.qpid.configuration.PropertyException;
import org.apache.log4j.Logger;
import java.util.List;
import java.lang.reflect.Method;
-import java.lang.reflect.InvocationTargetException;
+import java.security.Principal;
public class AccessManagerImpl implements AccessManager
{
@@ -39,8 +39,13 @@ public class AccessManagerImpl implements AccessManager
public AccessManagerImpl(String name, Configuration hostConfig) throws ConfigurationException
{
- String accessClass = hostConfig.getString("security.access.class");
+ if (hostConfig == null)
+ {
+ _logger.warn("No Configuration specified. Using default access controls for VirtualHost:'" + name + "'");
+ return;
+ }
+ String accessClass = hostConfig.getString("security.access.class");
if (accessClass == null)
{
_logger.warn("No access control specified. Using default access controls for VirtualHost:'" + name + "'");
@@ -111,21 +116,35 @@ public class AccessManagerImpl implements AccessManager
}
catch (Exception e)
{
- throw new ConfigurationException(e.getCause());
+ ConfigurationException ce = new ConfigurationException(e.getMessage(), e.getCause());
+ ce.initCause(e);
+ throw ce;
}
}
}
-
public AccessResult isAuthorized(Accessable accessObject, String username)
{
+ return isAuthorized(accessObject, new UsernamePrincipal(username), AccessRights.Rights.READ);
+ }
+
+ public AccessResult isAuthorized(Accessable accessObject, Principal user, AccessRights.Rights rights)
+ {
if (_accessManager == null)
{
- return ApplicationRegistry.getInstance().getAccessManager().isAuthorized(accessObject, username);
+ if (ApplicationRegistry.getInstance().getAccessManager() == this)
+ {
+ _logger.warn("No Default access manager specified DENYING ALL ACCESS");
+ return new AccessResult(this, AccessResult.AccessStatus.REFUSED);
+ }
+ else
+ {
+ return ApplicationRegistry.getInstance().getAccessManager().isAuthorized(accessObject, user, rights);
+ }
}
else
{
- return _accessManager.isAuthorized(accessObject, username);
+ return _accessManager.isAuthorized(accessObject, user, rights);
}
}
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/access/AccessRights.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/access/AccessRights.java
new file mode 100644
index 0000000000..1b79a5a0e0
--- /dev/null
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/access/AccessRights.java
@@ -0,0 +1,63 @@
+/*
+ * 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.access;
+
+public class AccessRights
+{
+ public enum Rights
+ {
+ ANY,
+ READ,
+ WRITE,
+ READWRITE
+ }
+
+ Rights _right;
+
+ public AccessRights(Rights right)
+ {
+ _right = right;
+ }
+
+ public boolean allows(Rights rights)
+ {
+ switch (_right)
+ {
+ case ANY:
+ return (rights.equals(Rights.WRITE)
+ || rights.equals(Rights.READ)
+ || rights.equals(Rights.READWRITE)
+ || rights.equals(Rights.ANY));
+ case READ:
+ return rights.equals(Rights.READ) || rights.equals(Rights.ANY);
+ case WRITE:
+ return rights.equals(Rights.WRITE) || rights.equals(Rights.ANY);
+ case READWRITE:
+ return true;
+ }
+ return false;
+ }
+
+ public Rights getRights()
+ {
+ return _right;
+ }
+}
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/access/AllowAll.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/access/AllowAll.java
index b2e4094edd..1ddca3a64e 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/access/AllowAll.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/access/AllowAll.java
@@ -20,9 +20,16 @@
*/
package org.apache.qpid.server.security.access;
+import java.security.Principal;
+
public class AllowAll implements AccessManager
{
+ public AccessResult isAuthorized(Accessable accessObject, Principal username, AccessRights.Rights rights)
+ {
+ return new AccessResult(this, AccessResult.AccessStatus.GRANTED);
+ }
+
public AccessResult isAuthorized(Accessable accessObject, String username)
{
return new AccessResult(this, AccessResult.AccessStatus.GRANTED);
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/access/DenyAll.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/access/DenyAll.java
index 0e62d2657f..bf40eeba4e 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/access/DenyAll.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/access/DenyAll.java
@@ -20,8 +20,15 @@
*/
package org.apache.qpid.server.security.access;
+import java.security.Principal;
+
public class DenyAll implements AccessManager
{
+ public AccessResult isAuthorized(Accessable accessObject, Principal username, AccessRights.Rights rights)
+ {
+ return new AccessResult(this, AccessResult.AccessStatus.REFUSED);
+ }
+
public AccessResult isAuthorized(Accessable accessObject, String username)
{
return new AccessResult(this, AccessResult.AccessStatus.REFUSED);
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/access/FileAccessManager.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/access/FileAccessManager.java
new file mode 100644
index 0000000000..291bc714ed
--- /dev/null
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/access/FileAccessManager.java
@@ -0,0 +1,183 @@
+/*
+ * 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.access;
+
+import org.apache.qpid.server.virtualhost.VirtualHost;
+import org.apache.qpid.server.security.auth.sasl.UsernamePrincipal;
+import org.apache.log4j.Logger;
+
+import java.io.IOException;
+import java.io.BufferedReader;
+import java.io.FileReader;
+import java.io.FileNotFoundException;
+import java.io.File;
+import java.util.regex.Pattern;
+import java.security.Principal;
+
+/**
+ * Represents a user database where the account information is stored in a simple flat file.
+ *
+ * The file is expected to be in the form: username:password username1:password1 ... usernamen:passwordn
+ *
+ * where a carriage return separates each username/password pair. Passwords are assumed to be in plain text.
+ */
+public class FileAccessManager implements AccessManager
+{
+ private static final Logger _logger = Logger.getLogger(FileAccessManager.class);
+
+ protected File _accessFile;
+
+ protected Pattern _regexp = Pattern.compile(":");
+
+ private static final short USER_INDEX = 0;
+ private static final short VIRTUALHOST_INDEX = 1;
+
+ public void setAccessFile(String accessFile) throws FileNotFoundException
+ {
+ File f = new File(accessFile);
+ _logger.info("FileAccessManager using file " + f.getAbsolutePath());
+ _accessFile = f;
+ if (!f.exists())
+ {
+ throw new FileNotFoundException("Cannot find access file " + f);
+ }
+ if (!f.canRead())
+ {
+ throw new FileNotFoundException("Cannot read access file " + f +
+ ". Check permissions.");
+ }
+ }
+
+ /**
+ * Looks up the virtual hosts for a specified user in the access file.
+ *
+ * @param user The user to lookup
+ *
+ * @return a list of virtualhosts
+ */
+ private VirtualHostAccess[] lookupVirtualHost(String user)
+ {
+ String[] results = lookup(user, VIRTUALHOST_INDEX);
+ VirtualHostAccess vhosts[] = new VirtualHostAccess[results.length];
+
+ for (int index = 0; index < results.length; index++)
+ {
+ vhosts[index] = new VirtualHostAccess(results[index]);
+ }
+
+ return vhosts;
+ }
+
+
+ private String[] lookup(String user, int index)
+ {
+ try
+ {
+ BufferedReader reader = null;
+ try
+ {
+ reader = new BufferedReader(new FileReader(_accessFile));
+ String line;
+
+ while ((line = reader.readLine()) != null)
+ {
+ String[] result = _regexp.split(line);
+ if (result == null || result.length < (index + 1))
+ {
+ continue;
+ }
+
+ if (user.equals(result[USER_INDEX]))
+ {
+ return result[index].split(",");
+ }
+ }
+ return null;
+ }
+ finally
+ {
+ if (reader != null)
+ {
+ reader.close();
+ }
+ }
+ }
+ catch (IOException ioe)
+ {
+ //ignore
+ }
+ return null;
+ }
+
+ public AccessResult isAuthorized(Accessable accessObject, String username)
+ {
+ return isAuthorized(accessObject, new UsernamePrincipal(username), AccessRights.Rights.READ);
+ }
+
+ public AccessResult isAuthorized(Accessable accessObject, Principal user, AccessRights.Rights rights)
+ {
+ if (accessObject instanceof VirtualHost)
+ {
+ VirtualHostAccess[] hosts = lookupVirtualHost(user.getName());
+
+ if (hosts != null)
+ {
+ for (VirtualHostAccess host : hosts)
+ {
+ if (accessObject.getAccessableName().equals(host.getVirtualHost()))
+ {
+ if (host.getAccessRights().allows(rights))
+ {
+ return new AccessResult(this, AccessResult.AccessStatus.GRANTED);
+ }
+ else
+ {
+ return new AccessResult(this, AccessResult.AccessStatus.REFUSED);
+ }
+ }
+ }
+ }
+ }
+// else if (accessObject instanceof AMQQueue)
+// {
+// String[] queues = lookupQueue(username, ((AMQQueue) accessObject).getVirtualHost());
+//
+// if (queues != null)
+// {
+// for (String queue : queues)
+// {
+// if (accessObject.getAccessableName().equals(queue))
+// {
+// return new AccessResult(this, AccessResult.AccessStatus.GRANTED);
+// }
+// }
+// }
+// }
+
+ return new AccessResult(this, AccessResult.AccessStatus.REFUSED);
+ }
+
+ public String getName()
+ {
+ return "FileAccessManager";
+ }
+
+}
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/access/PrincipalDatabaseAccessManager.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/access/PrincipalDatabaseAccessManager.java
index 0e447b5744..6ccadb2e7d 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/access/PrincipalDatabaseAccessManager.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/access/PrincipalDatabaseAccessManager.java
@@ -22,8 +22,11 @@ package org.apache.qpid.server.security.access;
import org.apache.qpid.server.registry.ApplicationRegistry;
import org.apache.qpid.server.security.auth.database.PrincipalDatabase;
+import org.apache.qpid.server.security.auth.sasl.UsernamePrincipal;
import org.apache.log4j.Logger;
+import java.security.Principal;
+
public class PrincipalDatabaseAccessManager implements AccessManager
{
private static final Logger _logger = Logger.getLogger(PrincipalDatabaseAccessManager.class);
@@ -58,15 +61,21 @@ public class PrincipalDatabaseAccessManager implements AccessManager
}
}
+
public AccessResult isAuthorized(Accessable accessObject, String username)
{
+ return isAuthorized(accessObject, new UsernamePrincipal(username), AccessRights.Rights.READ);
+ }
+
+ public AccessResult isAuthorized(Accessable accessObject, Principal username, AccessRights.Rights rights)
+ {
AccessResult result;
if (_database == null)
{
if (_default != null)
{
- result = _default.isAuthorized(accessObject, username);
+ result = _default.isAuthorized(accessObject, username, rights);
}
else
{
@@ -75,7 +84,15 @@ public class PrincipalDatabaseAccessManager implements AccessManager
}
else
{
- result = ((AccessManager) _database).isAuthorized(accessObject, username);
+ if (!(_database instanceof AccessManager))
+ {
+ _logger.warn("Specified PrincipalDatabase is not an AccessManager so using default AccessManager");
+ result = _default.isAuthorized(accessObject, username, rights);
+ }
+ else
+ {
+ result = ((AccessManager) _database).isAuthorized(accessObject, username, rights);
+ }
}
result.addAuthorizer(this);
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/access/UserManagement.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/access/UserManagement.java
new file mode 100644
index 0000000000..6381213398
--- /dev/null
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/access/UserManagement.java
@@ -0,0 +1,111 @@
+/*
+ * 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.access;
+
+import org.apache.qpid.server.management.MBeanOperation;
+import org.apache.qpid.server.management.MBeanOperationParameter;
+import org.apache.qpid.server.management.MBeanAttribute;
+import org.apache.qpid.AMQException;
+
+import javax.management.openmbean.TabularData;
+import javax.management.openmbean.CompositeData;
+import javax.management.JMException;
+import java.io.IOException;
+
+public interface UserManagement
+{
+ String TYPE = "UserManagement";
+
+ //********** Operations *****************//
+ /**
+ * set password for user
+ *
+ * @param username The username to create
+ * @param password The password for the user
+ *
+ * @return The result of the operation
+ */
+ @MBeanOperation(name = "setPassword", description = "Set password for user.")
+ boolean setPassword(@MBeanOperationParameter(name = "username", description = "Username")String username,
+ @MBeanOperationParameter(name = "password", description = "Password")String password);
+
+ /**
+ * set rights for users with given details
+ *
+ * @param username The username to create
+ * @param read The set of permission to give the new user
+ * @param write The set of permission to give the new user
+ * @param admin The set of permission to give the new user
+ *
+ * @return The result of the operation
+ */
+ @MBeanOperation(name = "setRights", description = "Set access rights for user.")
+ boolean setRights(@MBeanOperationParameter(name = "username", description = "Username")String username,
+ @MBeanOperationParameter(name = "read", description = "Administration read")boolean read,
+ @MBeanOperationParameter(name = "write", description = "Administration write")boolean write,
+ @MBeanOperationParameter(name = "admin", description = "Administration rights")boolean admin);
+
+ /**
+ * Create users with given details
+ *
+ * @param username The username to create
+ * @param password The password for the user
+ * @param read The set of permission to give the new user
+ * @param write The set of permission to give the new user
+ * @param admin The set of permission to give the new user
+ *
+ * @return The result of the operation
+ */
+ @MBeanOperation(name = "createUser", description = "Create new user from system.")
+ boolean createUser(@MBeanOperationParameter(name = "username", description = "Username")String username,
+ @MBeanOperationParameter(name = "password", description = "Password")String password,
+ @MBeanOperationParameter(name = "read", description = "Administration read")boolean read,
+ @MBeanOperationParameter(name = "write", description = "Administration write")boolean write,
+ @MBeanOperationParameter(name = "admin", description = "Administration rights")boolean admin);
+
+ /**
+ * View users returns all the users that are currently available to the system.
+ *
+ * @param username The user to delete
+ *
+ * @return The result of the operation
+ */
+ @MBeanOperation(name = "deleteUser", description = "Delete user from system.")
+ boolean deleteUser(@MBeanOperationParameter(name = "username", description = "Username")String username);
+
+
+ /**
+ * Reload the date from disk
+ *
+ * @return The result of the operation
+ */
+// @MBeanOperation(name = "reloadData", description = "Reload the authentication file from disk.")
+// boolean reloadData();
+
+ /**
+ * View users returns all the users that are currently available to the system.
+ *
+ * @return a table of users data (Username, read, write, admin)
+ */
+ @MBeanOperation(name = "viewUsers", description = "All users with access rights to the system.")
+ TabularData viewUsers();
+
+}
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/access/VirtualHostAccess.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/access/VirtualHostAccess.java
new file mode 100644
index 0000000000..13151a66b8
--- /dev/null
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/access/VirtualHostAccess.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.server.security.access;
+
+public class VirtualHostAccess
+{
+ private String _vhost;
+ private AccessRights _rights;
+
+ public VirtualHostAccess(String vhostaccess)
+ {
+ //format <vhost>(<rights>)
+ int hostend = vhostaccess.indexOf('(');
+
+ if (hostend == -1)
+ {
+ throw new IllegalArgumentException("VirtualHostAccess format string contains no access _rights");
+ }
+
+ _vhost = vhostaccess.substring(0, hostend);
+
+ String rights = vhostaccess.substring(hostend);
+
+ if (rights.indexOf('r') != -1)
+ {
+ if (rights.indexOf('w') != -1)
+ {
+ _rights = new AccessRights(AccessRights.Rights.READWRITE);
+ }
+ else
+ {
+ _rights = new AccessRights(AccessRights.Rights.READ);
+ }
+ }
+ else if (rights.indexOf('w') != -1)
+ {
+ _rights = new AccessRights(AccessRights.Rights.WRITE);
+ }
+ }
+
+ public AccessRights getAccessRights()
+ {
+ return _rights;
+ }
+
+ public String getVirtualHost()
+ {
+ return _vhost;
+ }
+}
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/database/Base64MD5PasswordFilePrincipalDatabase.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/database/Base64MD5PasswordFilePrincipalDatabase.java
new file mode 100644
index 0000000000..956db64d90
--- /dev/null
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/database/Base64MD5PasswordFilePrincipalDatabase.java
@@ -0,0 +1,626 @@
+/*
+ * 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.auth.database;
+
+import org.apache.log4j.Logger;
+import org.apache.qpid.server.security.auth.sasl.AuthenticationProviderInitialiser;
+import org.apache.qpid.server.security.auth.sasl.UsernamePrincipal;
+import org.apache.qpid.server.security.auth.sasl.crammd5.CRAMMD5HashedInitialiser;
+import org.apache.qpid.server.security.access.AMQUserManagementMBean;
+import org.apache.commons.codec.binary.Base64;
+import org.apache.commons.codec.EncoderException;
+
+import javax.security.auth.callback.PasswordCallback;
+import javax.security.auth.login.AccountNotFoundException;
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.BufferedReader;
+import java.io.FileReader;
+import java.io.UnsupportedEncodingException;
+import java.io.PrintStream;
+import java.util.regex.Pattern;
+import java.util.Map;
+import java.util.HashMap;
+import java.util.List;
+import java.util.LinkedList;
+import java.util.concurrent.locks.ReentrantLock;
+import java.security.Principal;
+import java.security.NoSuchAlgorithmException;
+import java.security.MessageDigest;
+
+/**
+ * Represents a user database where the account information is stored in a simple flat file.
+ *
+ * The file is expected to be in the form: username:password username1:password1 ... usernamen:passwordn
+ *
+ * where a carriage return separates each username/password pair. Passwords are assumed to be in plain text.
+ */
+public class Base64MD5PasswordFilePrincipalDatabase implements PrincipalDatabase
+{
+ private static final Logger _logger = Logger.getLogger(Base64MD5PasswordFilePrincipalDatabase.class);
+
+ private File _passwordFile;
+
+ private Pattern _regexp = Pattern.compile(":");
+
+ private Map<String, AuthenticationProviderInitialiser> _saslServers;
+
+ AMQUserManagementMBean _mbean;
+ private static final String DEFAULT_ENCODING = "utf-8";
+ private Map<String, User> _users = new HashMap<String, User>();
+ private ReentrantLock _userUpdate = new ReentrantLock();
+
+ public Base64MD5PasswordFilePrincipalDatabase()
+ {
+ _saslServers = new HashMap<String, AuthenticationProviderInitialiser>();
+
+ /**
+ * Create Authenticators for MD5 Password file.
+ */
+
+ // Accept Plain incomming and hash it for comparison to the file.
+ CRAMMD5HashedInitialiser cram = new CRAMMD5HashedInitialiser();
+ cram.initialise(this);
+ _saslServers.put(cram.getMechanismName(), cram);
+
+ //fixme The PDs should setup a PD Mangement MBean
+// try
+// {
+// _mbean = new AMQUserManagementMBean();
+// _mbean.setPrincipalDatabase(this);
+// }
+// catch (JMException e)
+// {
+// _logger.warn("User management disabled as unable to create MBean:" + e);
+// }
+ }
+
+ public void setPasswordFile(String passwordFile) throws IOException
+ {
+ File f = new File(passwordFile);
+ _logger.info("PasswordFilePrincipalDatabase using file " + f.getAbsolutePath());
+ _passwordFile = f;
+ if (!f.exists())
+ {
+ throw new FileNotFoundException("Cannot find password file " + f);
+ }
+ if (!f.canRead())
+ {
+ throw new FileNotFoundException("Cannot read password file " + f +
+ ". Check permissions.");
+ }
+
+ loadPasswordFile();
+ }
+
+ /**
+ * SASL Callback Mechanism - sets the Password in the PasswordCallback based on the value in the PasswordFile
+ *
+ * @param principal The Principal to set the password for
+ * @param callback The PasswordCallback to call setPassword on
+ *
+ * @throws AccountNotFoundException If the Principal cannont be found in this Database
+ */
+ public void setPassword(Principal principal, PasswordCallback callback) throws AccountNotFoundException
+ {
+ if (_passwordFile == null)
+ {
+ throw new AccountNotFoundException("Unable to locate principal since no password file was specified during initialisation");
+ }
+ if (principal == null)
+ {
+ throw new IllegalArgumentException("principal must not be null");
+ }
+
+ char[] pwd = lookupPassword(principal.getName());
+
+ if (pwd != null)
+ {
+ callback.setPassword(pwd);
+ }
+ else
+ {
+ throw new AccountNotFoundException("No account found for principal " + principal);
+ }
+ }
+
+ /**
+ * Used to verify that the presented Password is correct. Currently only used by Management Console
+ *
+ * @param principal The principal to authenticate
+ * @param password The password to check
+ *
+ * @return true if password is correct
+ *
+ * @throws AccountNotFoundException if the principal cannot be found
+ */
+ public boolean verifyPassword(String principal, String password) throws AccountNotFoundException
+ {
+ try
+ {
+ char[] pwd = lookupPassword(principal);
+ byte[] passwordBytes = password.getBytes(DEFAULT_ENCODING);
+
+ int index = 0;
+ boolean verified = true;
+
+ while (verified & index < passwordBytes.length)
+ {
+ verified = (pwd[index] == (char) passwordBytes[index]);
+ index++;
+ }
+ return verified;
+ }
+ catch (UnsupportedEncodingException e)
+ {
+ return false;
+ }
+ }
+
+ public boolean updatePassword(Principal principal, String password) throws AccountNotFoundException
+ {
+ User user = _users.get(principal.getName());
+
+ if (user == null)
+ {
+ throw new AccountNotFoundException(principal.getName());
+ }
+
+ try
+ {
+
+ char[] passwd = convertPassword(password);
+
+ try
+ {
+ _userUpdate.lock();
+ user.setPassword(passwd);
+
+ try
+ {
+ savePasswordFile();
+ }
+ catch (IOException e)
+ {
+ _logger.error("Unable to save password file, password change for user'"
+ + principal + "' will revert at restart");
+ return false;
+ }
+ return true;
+ }
+ finally
+ {
+ if (_userUpdate.isHeldByCurrentThread())
+ {
+ _userUpdate.unlock();
+ }
+ }
+ }
+ catch (UnsupportedEncodingException e)
+ {
+ return false;
+ }
+ }
+
+ private char[] convertPassword(String password) throws UnsupportedEncodingException
+ {
+ byte[] passwdBytes = password.getBytes(DEFAULT_ENCODING);
+
+ char[] passwd = new char[passwdBytes.length];
+
+ int index = 0;
+
+ for (byte b : passwdBytes)
+ {
+ passwd[index++] = (char) b;
+ }
+
+ return passwd;
+ }
+
+ public boolean createPrincipal(Principal principal, String password)
+ {
+ if (_users.get(principal.getName()) != null)
+ {
+ return false;
+ }
+
+ User user;
+ try
+ {
+ user = new User(principal.getName(), convertPassword(password));
+ }
+ catch (UnsupportedEncodingException e)
+ {
+ _logger.warn("Unable to encode password:" + e);
+ return false;
+ }
+
+ try
+ {
+ _userUpdate.lock();
+ _users.put(user.getName(), user);
+
+ try
+ {
+ savePasswordFile();
+ return true;
+ }
+ catch (IOException e)
+ {
+ return false;
+ }
+
+ }
+ finally
+ {
+ if (_userUpdate.isHeldByCurrentThread())
+ {
+ _userUpdate.unlock();
+ }
+ }
+ }
+
+ public boolean deletePrincipal(Principal principal) throws AccountNotFoundException
+ {
+ User user = _users.get(principal.getName());
+
+ if (user == null)
+ {
+ throw new AccountNotFoundException(principal.getName());
+ }
+
+ try
+ {
+ _userUpdate.lock();
+ user.delete();
+
+ try
+ {
+ savePasswordFile();
+ }
+ catch (IOException e)
+ {
+ _logger.warn("Unable to remove user '" + user.getName() + "' from password file.");
+ return false;
+ }
+
+ _users.remove(user.getName());
+ }
+ finally
+ {
+ if (_userUpdate.isHeldByCurrentThread())
+ {
+ _userUpdate.unlock();
+ }
+ }
+
+ return true;
+ }
+
+
+ public Map<String, AuthenticationProviderInitialiser> getMechanisms()
+ {
+ return _saslServers;
+ }
+
+ public List<Principal> getUsers()
+ {
+ return new LinkedList<Principal>(_users.values());
+ }
+
+ public Principal getUser(String username)
+ {
+ if (_users.containsKey(username))
+ {
+ return new UsernamePrincipal(username);
+ }
+ return null;
+ }
+
+ /**
+ * Looks up the password for a specified user in the password file. Note this code is <b>not</b> secure since it
+ * creates strings of passwords. It should be modified to create only char arrays which get nulled out.
+ *
+ * @param name The principal name to lookup
+ *
+ * @return a char[] for use in SASL.
+ */
+ private char[] lookupPassword(String name)
+ {
+ User user = _users.get(name);
+ if (user == null)
+ {
+ return null;
+ }
+ else
+ {
+ return user.getPassword();
+ }
+ }
+
+
+ private void loadPasswordFile() throws IOException
+ {
+ try
+ {
+ _userUpdate.lock();
+ _users.clear();
+
+ BufferedReader reader = null;
+ try
+ {
+ reader = new BufferedReader(new FileReader(_passwordFile));
+ String line;
+
+ while ((line = reader.readLine()) != null)
+ {
+ String[] result = _regexp.split(line);
+ if (result == null || result.length < 2 || result[0].startsWith("#"))
+ {
+ continue;
+ }
+
+ User user = new User(result);
+ _logger.info("Created user:" + user);
+ _users.put(user.getName(), user);
+ }
+ }
+ finally
+ {
+ if (reader != null)
+ {
+ reader.close();
+ }
+ }
+ }
+ finally
+ {
+ if (_userUpdate.isHeldByCurrentThread())
+ {
+ _userUpdate.unlock();
+ }
+ }
+ }
+
+ private void savePasswordFile() throws IOException
+ {
+ try
+ {
+ _userUpdate.lock();
+
+ BufferedReader reader = null;
+ PrintStream writer = null;
+ File tmp = new File(_passwordFile.getAbsolutePath() + ".tmp");
+ if (tmp.exists())
+ {
+ tmp.delete();
+ }
+ try
+ {
+ writer = new PrintStream(tmp);
+ reader = new BufferedReader(new FileReader(_passwordFile));
+ String line;
+
+ while ((line = reader.readLine()) != null)
+ {
+ String[] result = _regexp.split(line);
+ if (result == null || result.length < 2 || result[0].startsWith("#"))
+ {
+ writer.write(line.getBytes(DEFAULT_ENCODING));
+ continue;
+ }
+
+ User user = _users.get(result[0]);
+
+ if (user == null)
+ {
+ writer.write(line.getBytes(DEFAULT_ENCODING));
+ writer.println();
+ }
+ else if (!user.isDeleted())
+ {
+ if (!user.isModified())
+ {
+ writer.write(line.getBytes(DEFAULT_ENCODING));
+ writer.println();
+ }
+ else
+ {
+ try
+ {
+ byte[] encodedPassword = user.getEncodePassword();
+
+ writer.write((user.getName() + ":").getBytes(DEFAULT_ENCODING));
+ writer.write(encodedPassword);
+ writer.println();
+
+ user.saved();
+ }
+ catch (Exception e)
+ {
+ _logger.warn("Unable to encode new password reverting to old password.");
+ writer.write(line.getBytes(DEFAULT_ENCODING));
+ writer.println();
+ }
+ }
+ }
+ }
+
+ for (User user : _users.values())
+ {
+ if (user.isModified())
+ {
+ byte[] encodedPassword;
+ try
+ {
+ encodedPassword = user.getEncodePassword();
+ writer.write((user.getName() + ":").getBytes(DEFAULT_ENCODING));
+ writer.write(encodedPassword);
+ writer.println();
+ user.saved();
+ }
+ catch (Exception e)
+ {
+ _logger.warn("Unable to get Encoded password for user'" + user.getName() + "' password not saved");
+ }
+ }
+ }
+ }
+ finally
+ {
+ if (reader != null)
+ {
+ reader.close();
+ }
+
+ if (writer != null)
+ {
+ writer.close();
+ }
+
+ // Swap temp file to main password file.
+ File old = new File(_passwordFile.getAbsoluteFile() + ".old");
+ if (old.exists())
+ {
+ old.delete();
+ }
+ _passwordFile.renameTo(old);
+ tmp.renameTo(_passwordFile);
+ tmp.delete();
+ }
+ }
+ finally
+ {
+ if (_userUpdate.isHeldByCurrentThread())
+ {
+ _userUpdate.unlock();
+ }
+ }
+ }
+
+ private class User implements Principal
+ {
+ String _name;
+ char[] _password;
+ byte[] _encodedPassword = null;
+ private boolean _modified = false;
+ private boolean _deleted = false;
+
+ User(String[] data) throws UnsupportedEncodingException
+ {
+ if (data.length != 2)
+ {
+ throw new IllegalArgumentException("User Data should be lenght 2, username, password");
+ }
+
+ _name = data[0];
+
+ byte[] encoded_password = data[1].getBytes(DEFAULT_ENCODING);
+
+ Base64 b64 = new Base64();
+ byte[] decoded = b64.decode(encoded_password);
+
+ _encodedPassword = encoded_password;
+
+ _password = new char[decoded.length];
+
+ int index = 0;
+ for (byte c : decoded)
+ {
+ _password[index++] = (char) c;
+ }
+ }
+
+ public User(String name, char[] password)
+ {
+ _name = name;
+ setPassword(password);
+ }
+
+ public String getName()
+ {
+ return _name;
+ }
+
+ public String toString()
+ {
+ if (_logger.isDebugEnabled())
+ {
+ return getName() + ((_encodedPassword == null) ? "" : ":" + new String(_encodedPassword));
+ }
+ else
+ {
+ return _name;
+ }
+ }
+
+ char[] getPassword()
+ {
+ return _password;
+ }
+
+ void setPassword(char[] password)
+ {
+ _password = password;
+ _modified = true;
+ _encodedPassword = null;
+ }
+
+
+ byte[] getEncodePassword() throws EncoderException, UnsupportedEncodingException, NoSuchAlgorithmException
+ {
+ if (_encodedPassword == null)
+ {
+ encodePassword();
+ }
+ return _encodedPassword;
+ }
+
+ private void encodePassword() throws EncoderException, UnsupportedEncodingException, NoSuchAlgorithmException
+ {
+ Base64 b64 = new Base64();
+ _encodedPassword = b64.encode(new String(_password).getBytes(DEFAULT_ENCODING));
+ }
+
+ public boolean isModified()
+ {
+ return _modified;
+ }
+
+ public boolean isDeleted()
+ {
+ return _deleted;
+ }
+
+ public void delete()
+ {
+ _deleted = true;
+ }
+
+ public void saved()
+ {
+ _modified = false;
+ }
+
+ }
+}
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/database/ConfigurationFilePrincipalDatabaseManager.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/database/ConfigurationFilePrincipalDatabaseManager.java
index 0c35206dd3..2d3f5e5131 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/database/ConfigurationFilePrincipalDatabaseManager.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/database/ConfigurationFilePrincipalDatabaseManager.java
@@ -1,38 +1,46 @@
/*
- * 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
+ * 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
*
- * 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.
+ * 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.auth.database;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.lang.reflect.Method;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
import org.apache.commons.configuration.Configuration;
import org.apache.commons.configuration.ConfigurationException;
+
+import org.apache.log4j.Logger;
+
+import org.apache.qpid.configuration.PropertyUtils;
+import org.apache.qpid.configuration.PropertyException;
import org.apache.qpid.server.registry.ApplicationRegistry;
-import org.apache.qpid.server.security.auth.database.PrincipalDatabaseManager;
import org.apache.qpid.server.security.auth.database.PrincipalDatabase;
-import org.apache.qpid.configuration.PropertyUtils;
-import org.apache.log4j.Logger;
+import org.apache.qpid.server.security.auth.database.PrincipalDatabaseManager;
+import org.apache.qpid.server.security.access.AMQUserManagementMBean;
+import org.apache.qpid.AMQException;
-import java.util.Map;
-import java.util.List;
-import java.util.HashMap;
-import java.lang.reflect.Method;
-import java.io.FileNotFoundException;
+import javax.management.JMException;
public class ConfigurationFilePrincipalDatabaseManager implements PrincipalDatabaseManager
{
@@ -80,18 +88,21 @@ public class ConfigurationFilePrincipalDatabaseManager implements PrincipalDatab
initialisePrincipalDatabase((PrincipalDatabase) o, config, i);
String name = databaseNames.get(i);
- if (name == null || name.length() == 0)
+ if ((name == null) || (name.length() == 0))
{
throw new Exception("Principal database names must have length greater than or equal to one character");
}
+
PrincipalDatabase pd = databases.get(name);
if (pd != null)
{
throw new Exception("Duplicate principal database name not provided");
}
+
_logger.info("Initialised principal database '" + name + "' successfully");
databases.put(name, (PrincipalDatabase) o);
}
+
return databases;
}
@@ -104,14 +115,16 @@ public class ConfigurationFilePrincipalDatabaseManager implements PrincipalDatab
for (int i = 0; i < argumentNames.size(); i++)
{
String argName = argumentNames.get(i);
- if (argName == null || argName.length() == 0)
+ if ((argName == null) || (argName.length() == 0))
{
throw new ConfigurationException("Argument names must have length >= 1 character");
}
+
if (Character.isLowerCase(argName.charAt(0)))
{
argName = Character.toUpperCase(argName.charAt(0)) + argName.substring(1);
}
+
String methodName = "set" + argName;
Method method = null;
try
@@ -125,9 +138,10 @@ public class ConfigurationFilePrincipalDatabaseManager implements PrincipalDatab
if (method == null)
{
- throw new ConfigurationException("No method " + methodName + " found in class " + principalDatabase.getClass() +
- " hence unable to configure principal database. The method must be public and " +
- "have a single String argument with a void return type");
+ throw new ConfigurationException("No method " + methodName + " found in class "
+ + principalDatabase.getClass()
+ + " hence unable to configure principal database. The method must be public and "
+ + "have a single String argument with a void return type");
}
try
@@ -136,7 +150,14 @@ public class ConfigurationFilePrincipalDatabaseManager implements PrincipalDatab
}
catch (Exception ite)
{
- throw new ConfigurationException(ite.getCause());
+ if (ite instanceof ConfigurationException)
+ {
+ throw(ConfigurationException) ite;
+ }
+ else
+ {
+ throw new ConfigurationException(ite.getMessage(), ite);
+ }
}
}
}
@@ -145,4 +166,71 @@ public class ConfigurationFilePrincipalDatabaseManager implements PrincipalDatab
{
return _databases;
}
+
+ public void initialiseManagement(Configuration config) throws ConfigurationException
+ {
+ try
+ {
+ AMQUserManagementMBean _mbean = new AMQUserManagementMBean();
+
+ String baseSecurity = "security.jmx";
+ List<String> principalDBs = config.getList(baseSecurity + ".principal-database");
+
+ if (principalDBs.size() == 0)
+ {
+ throw new ConfigurationException("No principal-database specified for jmx security(" + baseSecurity + ".principal-database)");
+ }
+
+ String databaseName = principalDBs.get(0);
+
+ PrincipalDatabase database = getDatabases().get(databaseName);
+
+ if (database == null)
+ {
+ throw new ConfigurationException("Principal-database '" + databaseName + "' not found");
+ }
+
+ _mbean.setPrincipalDatabase(database);
+
+ List<String> jmxaccesslist = config.getList(baseSecurity + ".access");
+
+ if (jmxaccesslist.size() == 0)
+ {
+ throw new ConfigurationException("No access control files specified for jmx security(" + baseSecurity + ".access)");
+ }
+
+ String jmxaccesssFile = null;
+
+ try
+ {
+ jmxaccesssFile = PropertyUtils.replaceProperties(jmxaccesslist.get(0));
+ }
+ catch (PropertyException e)
+ {
+ throw new ConfigurationException("Unable to parse access control filename '" + jmxaccesssFile + "'");
+ }
+
+ try
+ {
+ _mbean.setAccessFile(jmxaccesssFile);
+ }
+ catch (IOException e)
+ {
+ _logger.warn("Unable to load access file:" + jmxaccesssFile);
+ }
+
+ try
+ {
+ _mbean.register();
+ }
+ catch (AMQException e)
+ {
+ _logger.warn("Unable to register user management MBean");
+ }
+ }
+ catch (JMException e)
+ {
+ _logger.warn("User management disabled as unable to create MBean:" + e);
+ }
+ }
}
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/database/MD5PasswordFilePrincipalDatabase.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/database/MD5PasswordFilePrincipalDatabase.java
deleted file mode 100644
index c24a5f21e9..0000000000
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/database/MD5PasswordFilePrincipalDatabase.java
+++ /dev/null
@@ -1,160 +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.auth.database;
-
-import org.apache.log4j.Logger;
-import org.apache.qpid.server.security.auth.sasl.AuthenticationProviderInitialiser;
-import org.apache.qpid.server.security.auth.sasl.crammd5.CRAMMD5Initialiser;
-import org.apache.qpid.server.security.auth.sasl.plain.PlainInitialiser;
-
-import javax.security.auth.callback.PasswordCallback;
-import javax.security.auth.login.AccountNotFoundException;
-import java.io.File;
-import java.io.FileNotFoundException;
-import java.io.IOException;
-import java.io.BufferedReader;
-import java.io.FileReader;
-import java.util.regex.Pattern;
-import java.util.Map;
-import java.util.HashMap;
-import java.security.Principal;
-
-/**
- * Represents a user database where the account information is stored in a simple flat file.
- *
- * The file is expected to be in the form: username:password username1:password1 ... usernamen:passwordn
- *
- * where a carriage return separates each username/password pair. Passwords are assumed to be in plain text.
- */
-public class MD5PasswordFilePrincipalDatabase implements PrincipalDatabase
-{
- private static final Logger _logger = Logger.getLogger(MD5PasswordFilePrincipalDatabase.class);
-
- private File _passwordFile;
-
- private Pattern _regexp = Pattern.compile(":");
-
- private Map<String, AuthenticationProviderInitialiser> _saslServers;
-
- public MD5PasswordFilePrincipalDatabase()
- {
- _saslServers = new HashMap<String, AuthenticationProviderInitialiser>();
-
- /**
- * Create Authenticators for MD5 Password file.
- */
-
- // Accept MD5 incomming and use plain comparison with the file
- PlainInitialiser cram = new PlainInitialiser();
- cram.initialise(this);
- // Accept Plain incomming and hash it for comparison to the file.
- CRAMMD5Initialiser plain = new CRAMMD5Initialiser();
- plain.initialise(this,CRAMMD5Initialiser.HashDirection.INCOMMING);
-
- _saslServers.put(plain.getMechanismName(), cram);
- _saslServers.put(cram.getMechanismName(), plain);
- }
-
- public void setPasswordFile(String passwordFile) throws FileNotFoundException
- {
- File f = new File(passwordFile);
- _logger.info("PasswordFilePrincipalDatabase using file " + f.getAbsolutePath());
- _passwordFile = f;
- if (!f.exists())
- {
- throw new FileNotFoundException("Cannot find password file " + f);
- }
- if (!f.canRead())
- {
- throw new FileNotFoundException("Cannot read password file " + f +
- ". Check permissions.");
- }
- }
-
- public void setPassword(Principal principal, PasswordCallback callback) throws IOException,
- AccountNotFoundException
- {
- if (_passwordFile == null)
- {
- throw new AccountNotFoundException("Unable to locate principal since no password file was specified during initialisation");
- }
- if (principal == null)
- {
- throw new IllegalArgumentException("principal must not be null");
- }
- char[] pwd = lookupPassword(principal.getName());
- if (pwd != null)
- {
- callback.setPassword(pwd);
- }
- else
- {
- throw new AccountNotFoundException("No account found for principal " + principal);
- }
- }
-
- public Map<String, AuthenticationProviderInitialiser> getMechanisms()
- {
- return _saslServers;
- }
-
- /**
- * Looks up the password for a specified user in the password file. Note this code is <b>not</b> secure since it
- * creates strings of passwords. It should be modified to create only char arrays which get nulled out.
- *
- * @param name
- *
- * @return
- *
- * @throws java.io.IOException
- */
- private char[] lookupPassword(String name) throws IOException
- {
- BufferedReader reader = null;
- try
- {
- reader = new BufferedReader(new FileReader(_passwordFile));
- String line;
-
- while ((line = reader.readLine()) != null)
- {
- String[] result = _regexp.split(line);
- if (result == null || result.length < 2)
- {
- continue;
- }
-
- if (name.equals(result[0]))
- {
- return result[1].toCharArray();
- }
- }
- return null;
- }
- finally
- {
- if (reader != null)
- {
- reader.close();
- }
- }
- }
-}
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/database/PlainPasswordFilePrincipalDatabase.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/database/PlainPasswordFilePrincipalDatabase.java
index 3abdd9a7ff..3f6794aaaf 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/database/PlainPasswordFilePrincipalDatabase.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/database/PlainPasswordFilePrincipalDatabase.java
@@ -21,8 +21,8 @@
package org.apache.qpid.server.security.auth.database;
import org.apache.log4j.Logger;
-import org.apache.qpid.server.security.auth.database.PrincipalDatabase;
import org.apache.qpid.server.security.auth.sasl.AuthenticationProviderInitialiser;
+import org.apache.qpid.server.security.auth.sasl.UsernamePrincipal;
import org.apache.qpid.server.security.auth.sasl.amqplain.AmqPlainInitialiser;
import org.apache.qpid.server.security.auth.sasl.crammd5.CRAMMD5Initialiser;
import org.apache.qpid.server.security.auth.sasl.plain.PlainInitialiser;
@@ -34,9 +34,11 @@ import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.BufferedReader;
import java.io.FileReader;
+import java.io.UnsupportedEncodingException;
import java.util.regex.Pattern;
import java.util.Map;
import java.util.HashMap;
+import java.util.List;
import java.security.Principal;
/**
@@ -119,21 +121,103 @@ public class PlainPasswordFilePrincipalDatabase implements PrincipalDatabase
}
}
+ public boolean verifyPassword(String principal, String password) throws AccountNotFoundException
+ {
+ try
+ {
+ char[] pwd = lookupPassword(principal);
+
+ return compareCharArray(pwd, convertPassword(password));
+ }
+ catch (IOException e)
+ {
+ return false;
+ }
+ }
+
+ private char[] convertPassword(String password) throws UnsupportedEncodingException
+ {
+ byte[] passwdBytes = password.getBytes("utf-8");
+
+ char[] passwd = new char[passwdBytes.length];
+
+ int index = 0;
+
+ for (byte b : passwdBytes)
+ {
+ passwd[index++] = (char) b;
+ }
+
+ return passwd;
+ }
+
+ public boolean updatePassword(Principal principal, String password) throws AccountNotFoundException
+ {
+ return false; // updates denied
+ }
+
+ public boolean createPrincipal(Principal principal, String password)
+ {
+ return false; // updates denied
+ }
+
+ public boolean deletePrincipal(Principal principal) throws AccountNotFoundException
+ {
+ return false; // updates denied
+ }
+
public Map<String, AuthenticationProviderInitialiser> getMechanisms()
{
return _saslServers;
}
+ public List<Principal> getUsers()
+ {
+ return null; //todo
+ }
+
+ public Principal getUser(String username)
+ {
+ try
+ {
+ if (lookupPassword(username) != null)
+ {
+ return new UsernamePrincipal(username);
+ }
+ }
+ catch (IOException e)
+ {
+ //fall through to null return
+ }
+ return null;
+ }
+
+ private boolean compareCharArray(char[] a, char[] b)
+ {
+ boolean equal = false;
+ if (a.length == b.length)
+ {
+ equal = true;
+ int index = 0;
+ while (equal && index < a.length)
+ {
+ equal = a[index] == b[index];
+ index++;
+ }
+ }
+ return equal;
+ }
+
/**
* Looks up the password for a specified user in the password file. Note this code is <b>not</b> secure since it
* creates strings of passwords. It should be modified to create only char arrays which get nulled out.
*
- * @param name
+ * @param name the name of the principal to lookup
*
- * @return
+ * @return char[] of the password
*
- * @throws java.io.IOException
+ * @throws java.io.IOException whilst accessing the file
*/
private char[] lookupPassword(String name) throws IOException
{
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/database/PlainPasswordVhostFilePrincipalDatabase.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/database/PlainPasswordVhostFilePrincipalDatabase.java
index c8318d6e64..598f8f8b4c 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/database/PlainPasswordVhostFilePrincipalDatabase.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/database/PlainPasswordVhostFilePrincipalDatabase.java
@@ -20,26 +20,17 @@
*/
package org.apache.qpid.server.security.auth.database;
-import org.apache.qpid.server.security.auth.database.PrincipalDatabase;
-import org.apache.qpid.server.security.auth.sasl.AuthenticationProviderInitialiser;
-import org.apache.qpid.server.security.auth.sasl.crammd5.CRAMMD5Initialiser;
-import org.apache.qpid.server.security.auth.sasl.plain.PlainInitialiser;
import org.apache.qpid.server.security.access.AccessManager;
import org.apache.qpid.server.security.access.AccessResult;
import org.apache.qpid.server.security.access.Accessable;
+import org.apache.qpid.server.security.access.AccessRights;
+import org.apache.qpid.server.security.auth.sasl.UsernamePrincipal;
import org.apache.qpid.server.virtualhost.VirtualHost;
import org.apache.log4j.Logger;
-import javax.security.auth.callback.PasswordCallback;
-import javax.security.auth.login.AccountNotFoundException;
-import java.io.File;
-import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.BufferedReader;
import java.io.FileReader;
-import java.util.regex.Pattern;
-import java.util.Map;
-import java.util.HashMap;
import java.security.Principal;
/**
@@ -103,9 +94,15 @@ public class PlainPasswordVhostFilePrincipalDatabase extends PlainPasswordFilePr
public AccessResult isAuthorized(Accessable accessObject, String username)
{
+ return isAuthorized(accessObject, new UsernamePrincipal(username), AccessRights.Rights.READ);
+ }
+
+ public AccessResult isAuthorized(Accessable accessObject, Principal user, AccessRights.Rights rights)
+ {
+
if (accessObject instanceof VirtualHost)
{
- String[] hosts = lookupVirtualHost(username);
+ String[] hosts = lookupVirtualHost(user.getName());
if (hosts != null)
{
@@ -126,4 +123,5 @@ public class PlainPasswordVhostFilePrincipalDatabase extends PlainPasswordFilePr
{
return "PlainPasswordVhostFile";
}
+
}
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/database/PrincipalDatabase.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/database/PrincipalDatabase.java
index 6c5a2a44ee..8073fcc3c6 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/database/PrincipalDatabase.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/database/PrincipalDatabase.java
@@ -23,8 +23,10 @@ package org.apache.qpid.server.security.auth.database;
import org.apache.qpid.server.security.auth.sasl.AuthenticationProviderInitialiser;
import java.io.IOException;
+import java.io.UnsupportedEncodingException;
import java.security.Principal;
import java.util.Map;
+import java.util.List;
import javax.security.auth.callback.PasswordCallback;
import javax.security.auth.login.AccountNotFoundException;
@@ -46,5 +48,53 @@ public interface PrincipalDatabase
void setPassword(Principal principal, PasswordCallback callback)
throws IOException, AccountNotFoundException;
+ /**
+ * Used to verify that the presented Password is correct. Currently only used by Management Console
+ * @param principal The principal to authenticate
+ * @param password The password to check
+ * @return true if password is correct
+ * @throws AccountNotFoundException if the principal cannot be found
+ */
+ boolean verifyPassword(String principal, String password)
+ throws AccountNotFoundException;
+
+ /**
+ * Update(Change) the password for the given principal
+ * @param principal Who's password is to be changed
+ * @param password The new password to use
+ * @return True if change was successful
+ * @throws AccountNotFoundException If the given principal doesn't exist in the Database
+ */
+ boolean updatePassword(Principal principal, String password)
+ throws AccountNotFoundException;
+
+ /**
+ * Create a new principal in the database
+ * @param principal The principal to create
+ * @param password The password to set for the principal
+ * @return True on a successful creation
+ */
+ boolean createPrincipal(Principal principal, String password);
+
+ /**
+ * Delete a principal
+ * @param principal The principal to delete
+ * @return True on a successful creation
+ * @throws AccountNotFoundException If the given principal doesn't exist in the Database
+ */
+ boolean deletePrincipal(Principal principal)
+ throws AccountNotFoundException;
+
+ /**
+ * Get the principal from the database with the given username
+ * @param username of the principal to lookup
+ * @return The Principal object for the given username or null if not found.
+ */
+ Principal getUser(String username);
+
+
public Map<String, AuthenticationProviderInitialiser> getMechanisms();
+
+
+ List<Principal> getUsers();
}
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/database/PrincipalDatabaseManager.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/database/PrincipalDatabaseManager.java
index 83f1201bd8..2c553ae76a 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/database/PrincipalDatabaseManager.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/database/PrincipalDatabaseManager.java
@@ -21,10 +21,14 @@
package org.apache.qpid.server.security.auth.database;
import org.apache.qpid.server.security.auth.database.PrincipalDatabase;
+import org.apache.commons.configuration.Configuration;
+import org.apache.commons.configuration.ConfigurationException;
import java.util.Map;
public interface PrincipalDatabaseManager
{
public Map<String, PrincipalDatabase> getDatabases();
+
+ public void initialiseManagement(Configuration config) throws ConfigurationException;
}
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/database/PropertiesPrincipalDatabase.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/database/PropertiesPrincipalDatabase.java
index 9a58acd98c..b1ac0e1f00 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/database/PropertiesPrincipalDatabase.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/database/PropertiesPrincipalDatabase.java
@@ -21,6 +21,7 @@
package org.apache.qpid.server.security.auth.database;
import org.apache.qpid.server.security.auth.sasl.AuthenticationProviderInitialiser;
+import org.apache.qpid.server.security.auth.sasl.UsernamePrincipal;
import org.apache.qpid.server.security.auth.sasl.crammd5.CRAMMD5Initialiser;
import org.apache.qpid.server.security.auth.sasl.plain.PlainInitialiser;
@@ -29,8 +30,10 @@ import javax.security.auth.login.AccountNotFoundException;
import java.util.Properties;
import java.util.Map;
import java.util.HashMap;
+import java.util.List;
import java.security.Principal;
import java.io.IOException;
+import java.io.UnsupportedEncodingException;
public class PropertiesPrincipalDatabase implements PrincipalDatabase
{
@@ -76,8 +79,87 @@ public class PropertiesPrincipalDatabase implements PrincipalDatabase
}
}
+ public boolean verifyPassword(String principal, String password) throws AccountNotFoundException
+ {
+ char[] pwd = _users.getProperty(principal).toCharArray();
+
+ try
+ {
+ return compareCharArray(pwd, convertPassword(password));
+ }
+ catch (UnsupportedEncodingException e)
+ {
+ return false;
+ }
+ }
+
+ public boolean updatePassword(Principal principal, String password) throws AccountNotFoundException
+ {
+ return false; // updates denied
+ }
+
+ public boolean createPrincipal(Principal principal, String password)
+ {
+ return false; // updates denied
+ }
+
+ public boolean deletePrincipal(Principal principal) throws AccountNotFoundException
+ {
+ return false; // updates denied
+ }
+
+ private boolean compareCharArray(char[] a, char[] b)
+ {
+ boolean equal = false;
+ if (a.length == b.length)
+ {
+ equal = true;
+ int index = 0;
+ while (equal && index < a.length)
+ {
+ equal = a[index] == b[index];
+ index++;
+ }
+ }
+ return equal;
+ }
+
+ private char[] convertPassword(String password) throws UnsupportedEncodingException
+ {
+ byte[] passwdBytes = password.getBytes("utf-8");
+
+ char[] passwd = new char[passwdBytes.length];
+
+ int index = 0;
+
+ for (byte b : passwdBytes)
+ {
+ passwd[index++] = (char) b;
+ }
+
+ return passwd;
+ }
+
+
public Map<String, AuthenticationProviderInitialiser> getMechanisms()
{
return _saslServers;
}
+
+ public List<Principal> getUsers()
+ {
+ return null; //todo
+ }
+
+ public Principal getUser(String username)
+ {
+ if (_users.getProperty(username) != null)
+ {
+ return new UsernamePrincipal(username);
+ }
+ else
+ {
+ return null;
+ }
+ }
}
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/database/PropertiesPrincipalDatabaseManager.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/database/PropertiesPrincipalDatabaseManager.java
index 89c84e8130..6b86a46bd2 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/database/PropertiesPrincipalDatabaseManager.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/database/PropertiesPrincipalDatabaseManager.java
@@ -20,6 +20,8 @@
*/
package org.apache.qpid.server.security.auth.database;
+import org.apache.commons.configuration.Configuration;
+
import java.util.Map;
import java.util.Properties;
import java.util.HashMap;
@@ -38,4 +40,9 @@ public class PropertiesPrincipalDatabaseManager implements PrincipalDatabaseMana
{
return _databases;
}
+
+ public void initialiseManagement(Configuration config)
+ {
+ //todo
+ }
}
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/PrincipalDatabaseAuthenticationManager.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/PrincipalDatabaseAuthenticationManager.java
index 0546bbb81e..ce5e0cd748 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/PrincipalDatabaseAuthenticationManager.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/PrincipalDatabaseAuthenticationManager.java
@@ -71,7 +71,7 @@ public class PrincipalDatabaseAuthenticationManager implements AuthenticationMan
Map<String, Class<? extends SaslServerFactory>> providerMap = new TreeMap<String, Class<? extends SaslServerFactory>>();
- if (name == null)
+ if (name == null || hostConfig == null)
{
initialiseAuthenticationMechanisms(providerMap, ApplicationRegistry.getInstance().getDatabaseManager().getDatabases());
}
@@ -108,11 +108,15 @@ public class PrincipalDatabaseAuthenticationManager implements AuthenticationMan
if (providerMap.size() > 0)
{
- Security.addProvider(new JCAProvider(providerMap));
+ // Ensure we are used before the defaults
+ if (Security.insertProviderAt(new JCAProvider(providerMap), 1) == -1)
+ {
+ _logger.warn("Unable to set order of providers.");
+ }
}
else
{
- _logger.warn("No SASL providers availble.");
+ _logger.warn("No additional SASL providers registered.");
}
}
@@ -148,21 +152,20 @@ public class PrincipalDatabaseAuthenticationManager implements AuthenticationMan
{
if (database == null || database.getMechanisms().size() == 0)
{
- _logger.warn("");
+ _logger.warn("No Database or no mechanisms to initialise authentication");
return;
}
- for (AuthenticationProviderInitialiser mechanism : database.getMechanisms().values())
+ for (Map.Entry<String, AuthenticationProviderInitialiser> mechanism : database.getMechanisms().entrySet())
{
- initialiseAuthenticationMechanism(mechanism, providerMap);
+ initialiseAuthenticationMechanism(mechanism.getKey(), mechanism.getValue(), providerMap);
}
}
- private void initialiseAuthenticationMechanism(AuthenticationProviderInitialiser initialiser,
+ private void initialiseAuthenticationMechanism(String mechanism, AuthenticationProviderInitialiser initialiser,
Map<String, Class<? extends SaslServerFactory>> providerMap)
throws Exception
{
- String mechanism = initialiser.getMechanismName();
if (_mechanisms == null)
{
_mechanisms = mechanism;
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/JCAProvider.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/JCAProvider.java
index 8ffcdc4e36..fd4ad86055 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/JCAProvider.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/JCAProvider.java
@@ -33,7 +33,7 @@ public final class JCAProvider extends Provider
super("AMQSASLProvider", 1.0, "A JCA provider that registers all " +
"AMQ SASL providers that want to be registered");
register(providerMap);
- Security.addProvider(this);
+ //Security.addProvider(this);
}
private void register(Map<String, Class<? extends SaslServerFactory>> providerMap)
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/UsernamePasswordInitialiser.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/UsernamePasswordInitialiser.java
index 68095de3a0..dd0bd096c3 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/UsernamePasswordInitialiser.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/UsernamePasswordInitialiser.java
@@ -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
@@ -33,14 +33,16 @@ import javax.security.auth.login.AccountNotFoundException;
import javax.security.sasl.AuthorizeCallback;
import org.apache.commons.configuration.Configuration;
+
import org.apache.log4j.Logger;
+
import org.apache.qpid.server.security.auth.database.PrincipalDatabase;
import org.apache.qpid.server.security.auth.sasl.AuthenticationProviderInitialiser;
import org.apache.qpid.server.security.auth.sasl.UsernamePrincipal;
public abstract class UsernamePasswordInitialiser implements AuthenticationProviderInitialiser
{
- protected static final Logger _logger = Logger.getLogger(UsernamePasswordInitialiser.class);
+ protected static final Logger _logger = Logger.getLogger(UsernamePasswordInitialiser.class);
private ServerCallbackHandler _callbackHandler;
@@ -72,7 +74,9 @@ public abstract class UsernamePasswordInitialiser implements AuthenticationProvi
{
// very annoyingly the callback handler does not throw anything more appropriate than
// IOException
- throw new IOException("Error looking up user " + e);
+ IOException ioe = new IOException("Error looking up user " + e);
+ ioe.initCause(e);
+ throw ioe;
}
}
else if (callback instanceof AuthorizeCallback)
@@ -88,7 +92,7 @@ public abstract class UsernamePasswordInitialiser implements AuthenticationProvi
}
public void initialise(String baseConfigPath, Configuration configuration,
- Map<String, PrincipalDatabase> principalDatabases) throws Exception
+ Map<String, PrincipalDatabase> principalDatabases) throws Exception
{
String principalDatabaseName = configuration.getString(baseConfigPath + ".principal-database");
PrincipalDatabase db = principalDatabases.get(principalDatabaseName);
@@ -102,6 +106,7 @@ public abstract class UsernamePasswordInitialiser implements AuthenticationProvi
{
throw new NullPointerException("Cannot initialise with a null Principal database.");
}
+
_callbackHandler = new ServerCallbackHandler(db);
}
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/UsernamePrincipal.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/UsernamePrincipal.java
index f9aaabd15a..d7c8383690 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/UsernamePrincipal.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/UsernamePrincipal.java
@@ -22,10 +22,7 @@ package org.apache.qpid.server.security.auth.sasl;
import java.security.Principal;
-/**
- * A principal that is just a wrapper for a simple username.
- *
- */
+/** A principal that is just a wrapper for a simple username. */
public class UsernamePrincipal implements Principal
{
private String _name;
@@ -39,4 +36,9 @@ public class UsernamePrincipal implements Principal
{
return _name;
}
+
+ public String toString()
+ {
+ return _name;
+ }
}
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/crammd5/CRAMMD5HashedInitialiser.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/crammd5/CRAMMD5HashedInitialiser.java
new file mode 100644
index 0000000000..97f9a4e91a
--- /dev/null
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/crammd5/CRAMMD5HashedInitialiser.java
@@ -0,0 +1,50 @@
+/*
+ *
+ * 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.auth.sasl.crammd5;
+
+import org.apache.qpid.server.security.auth.sasl.UsernamePasswordInitialiser;
+import org.apache.qpid.server.security.auth.database.PrincipalDatabase;
+
+import javax.security.sasl.SaslServerFactory;
+import java.util.Map;
+
+public class CRAMMD5HashedInitialiser extends UsernamePasswordInitialiser
+{
+ public String getMechanismName()
+ {
+ return CRAMMD5HashedSaslServer.MECHANISM;
+ }
+
+ public Class<? extends SaslServerFactory> getServerFactoryClassForJCARegistration()
+ {
+ return CRAMMD5HashedServerFactory.class;
+ }
+
+ public void initialise(PrincipalDatabase passwordFile)
+ {
+ super.initialise(passwordFile);
+ }
+
+ public Map<String, ?> getProperties()
+ {
+ return null;
+ }
+}
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/crammd5/CRAMMD5HashedSaslServer.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/crammd5/CRAMMD5HashedSaslServer.java
new file mode 100644
index 0000000000..f6cab084ea
--- /dev/null
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/crammd5/CRAMMD5HashedSaslServer.java
@@ -0,0 +1,105 @@
+/*
+ * 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.auth.sasl.crammd5;
+
+import javax.security.sasl.SaslServer;
+import javax.security.sasl.SaslException;
+import javax.security.sasl.Sasl;
+import javax.security.sasl.SaslServerFactory;
+import javax.security.auth.callback.CallbackHandler;
+import java.util.Enumeration;
+import java.util.Map;
+
+public class CRAMMD5HashedSaslServer implements SaslServer
+{
+ public static final String MECHANISM = "CRAM-MD5-HASHED";
+
+ private SaslServer _realServer;
+
+ public CRAMMD5HashedSaslServer(String mechanism, String protocol, String serverName, Map<String, ?> props,
+ CallbackHandler cbh) throws SaslException
+ {
+ Enumeration factories = Sasl.getSaslServerFactories();
+
+ while (factories.hasMoreElements())
+ {
+ SaslServerFactory factory = (SaslServerFactory) factories.nextElement();
+
+ if (factory instanceof CRAMMD5HashedServerFactory)
+ {
+ continue;
+ }
+
+ String[] mechs = factory.getMechanismNames(props);
+
+ for (String mech : mechs)
+ {
+ if (mech.equals("CRAM-MD5"))
+ {
+ _realServer = factory.createSaslServer("CRAM-MD5", protocol, serverName, props, cbh);
+ return;
+ }
+ }
+ }
+
+ throw new RuntimeException("No default SaslServer found for mechanism:" + "CRAM-MD5");
+ }
+
+ public String getMechanismName()
+ {
+ return MECHANISM;
+ }
+
+ public byte[] evaluateResponse(byte[] response) throws SaslException
+ {
+ return _realServer.evaluateResponse(response);
+ }
+
+ public boolean isComplete()
+ {
+ return _realServer.isComplete();
+ }
+
+ public String getAuthorizationID()
+ {
+ return _realServer.getAuthorizationID();
+ }
+
+ public byte[] unwrap(byte[] incoming, int offset, int len) throws SaslException
+ {
+ return _realServer.unwrap(incoming, offset, len);
+ }
+
+ public byte[] wrap(byte[] outgoing, int offset, int len) throws SaslException
+ {
+ return _realServer.wrap(outgoing, offset, len);
+ }
+
+ public Object getNegotiatedProperty(String propName)
+ {
+ return _realServer.getNegotiatedProperty(propName);
+ }
+
+ public void dispose() throws SaslException
+ {
+ _realServer.dispose();
+ }
+}
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/crammd5/CRAMMD5HashedServerFactory.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/crammd5/CRAMMD5HashedServerFactory.java
new file mode 100644
index 0000000000..5298b5cc63
--- /dev/null
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/crammd5/CRAMMD5HashedServerFactory.java
@@ -0,0 +1,61 @@
+/*
+ *
+ * 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.auth.sasl.crammd5;
+
+import java.util.Map;
+
+import javax.security.auth.callback.CallbackHandler;
+import javax.security.sasl.Sasl;
+import javax.security.sasl.SaslException;
+import javax.security.sasl.SaslServer;
+import javax.security.sasl.SaslServerFactory;
+
+public class CRAMMD5HashedServerFactory implements SaslServerFactory
+{
+ public SaslServer createSaslServer(String mechanism, String protocol, String serverName, Map<String, ?> props,
+ CallbackHandler cbh) throws SaslException
+ {
+ if (mechanism.equals(CRAMMD5HashedSaslServer.MECHANISM))
+ {
+ return new CRAMMD5HashedSaslServer(mechanism, protocol, serverName, props, cbh);
+ }
+ else
+ {
+ return null;
+ }
+ }
+
+ public String[] getMechanismNames(Map props)
+ {
+ if (props != null)
+ {
+ if (props.containsKey(Sasl.POLICY_NOPLAINTEXT) ||
+ props.containsKey(Sasl.POLICY_NODICTIONARY) ||
+ props.containsKey(Sasl.POLICY_NOACTIVE))
+ {
+ // returned array must be non null according to interface documentation
+ return new String[0];
+ }
+ }
+
+ return new String[]{CRAMMD5HashedSaslServer.MECHANISM};
+ }
+}
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/plain/PlainSaslServerFactory.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/plain/PlainSaslServerFactory.java
index ff3e87e3a0..f0dd9eeb6d 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/plain/PlainSaslServerFactory.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/plain/PlainSaslServerFactory.java
@@ -29,7 +29,7 @@ import javax.security.sasl.SaslServer;
import javax.security.sasl.SaslServerFactory;
public class PlainSaslServerFactory implements SaslServerFactory
-{
+{
public SaslServer createSaslServer(String mechanism, String protocol, String serverName, Map props,
CallbackHandler cbh) throws SaslException
{
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/txn/CleanupMessageOperation.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/txn/CleanupMessageOperation.java
index 05d1cd5291..609a85c22f 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/txn/CleanupMessageOperation.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/txn/CleanupMessageOperation.java
@@ -56,18 +56,7 @@ public class CleanupMessageOperation implements TxnOp
public void commit(StoreContext context)
{
- //The routers reference can now be released. This is done
- //here to ensure that it happens after the queues that
- //enqueue it have incremented their counts (which as a
- //memory only operation is done in the commit phase).
- try
- {
- _msg.decrementReference(context);
- }
- catch (AMQException e)
- {
- _log.error("On commiting transaction, failed to cleanup unused message: " + e, e);
- }
+
try
{
_msg.checkDeliveredToConsumer();
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/txn/LocalTransactionalContext.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/txn/LocalTransactionalContext.java
index cf0da55f2a..6d776eec0f 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/txn/LocalTransactionalContext.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/txn/LocalTransactionalContext.java
@@ -89,6 +89,12 @@ public class LocalTransactionalContext implements TransactionalContext
public void rollback() throws AMQException
{
_txnBuffer.rollback(_storeContext);
+ // Hack to deal with uncommitted non-transactional writes
+ if(_messageStore.inTran(_storeContext))
+ {
+ _messageStore.abortTran(_storeContext);
+ _inTran = false;
+ }
_postCommitDeliveryList.clear();
}
@@ -103,6 +109,7 @@ public class LocalTransactionalContext implements TransactionalContext
// message.incrementReference();
_postCommitDeliveryList.add(new DeliveryDetails(message, queue, deliverFirst));
_messageDelivered = true;
+ _txnBuffer.enlist(new CleanupMessageOperation(message, _returnMessages));
/*_txnBuffer.enlist(new DeliverMessageOperation(message, queue));
if (_log.isDebugEnabled())
{
@@ -111,7 +118,7 @@ public class LocalTransactionalContext implements TransactionalContext
}
message.incrementReference();
_messageDelivered = true;
- _txnBuffer.enlist(new CleanupMessageOperation(message, _returnMessages));
+
*/
}
@@ -195,6 +202,7 @@ public class LocalTransactionalContext implements TransactionalContext
{
_txnBuffer.enlist(new StoreMessageOperation(_messageStore));
}
+ //fixme fail commit here ... QPID-440
try
{
_txnBuffer.commit(_storeContext);
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/txn/TxnBuffer.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/txn/TxnBuffer.java
index 339ca8ae1a..405c233552 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/txn/TxnBuffer.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/txn/TxnBuffer.java
@@ -41,7 +41,7 @@ public class TxnBuffer
{
if (_log.isDebugEnabled())
{
- _log.debug("Committing " + _ops.size() + " ops to commit.:" + _ops.toArray());
+ _log.debug("Committing " + _ops.size() + " ops to commit.:" + _ops);
}
if (prepare(context))
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/virtualhost/VirtualHost.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/virtualhost/VirtualHost.java
index c24d1aa23a..b5c59dbbb7 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/virtualhost/VirtualHost.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/virtualhost/VirtualHost.java
@@ -181,7 +181,7 @@ public class VirtualHost implements Accessable
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");
+ throw new IllegalArgumentException("Unable to instantiate configuration class " + instanceType + " - ensure it has a public default constructor", e);
}
Configurator.configure(instance);
diff --git a/qpid/java/broker/src/test/java/org/apache/qpid/server/queue/AMQQueueAlertTest.java b/qpid/java/broker/src/test/java/org/apache/qpid/server/queue/AMQQueueAlertTest.java
index 236291968f..0c1da5c278 100644
--- a/qpid/java/broker/src/test/java/org/apache/qpid/server/queue/AMQQueueAlertTest.java
+++ b/qpid/java/broker/src/test/java/org/apache/qpid/server/queue/AMQQueueAlertTest.java
@@ -106,6 +106,8 @@ public class AMQQueueAlertTest extends TestCase
/**
* Tests if Queue Depth alert is thrown when queue depth reaches the threshold value
*
+ * Based on FT402 subbmitted by client
+ *
* @throws Exception
*/
public void testQueueDepthAlertNoSubscriber() throws Exception
diff --git a/qpid/java/client/example/src/main/java/org/apache/qpid/example/publisher/FileMessageDispatcher.java b/qpid/java/client/example/src/main/java/org/apache/qpid/example/publisher/FileMessageDispatcher.java
index b199d41432..6a7626c51d 100644
--- a/qpid/java/client/example/src/main/java/org/apache/qpid/example/publisher/FileMessageDispatcher.java
+++ b/qpid/java/client/example/src/main/java/org/apache/qpid/example/publisher/FileMessageDispatcher.java
@@ -1,4 +1,5 @@
/*
+ *
* 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
@@ -6,33 +7,35 @@
* 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.publisher;
-import org.apache.log4j.Logger;
-
import java.io.File;
+import javax.jms.JMSException;
+
+import org.apache.log4j.Logger;
+
import org.apache.qpid.example.shared.FileUtils;
import org.apache.qpid.example.shared.Statics;
-import javax.jms.JMSException;
-
/**
* Class that sends message files to the Publisher to distribute
* using files as input
* Must set properties for host in properties file or uses in vm broker
*/
-public class FileMessageDispatcher {
+public class FileMessageDispatcher
+{
protected static final Logger _logger = Logger.getLogger(FileMessageDispatcher.class);
@@ -48,30 +51,30 @@ public class FileMessageDispatcher {
public static void main(String[] args)
{
- //Check command line args ok - must provide a path or file for us to dispatch
+ // Check command line args ok - must provide a path or file for us to dispatch
if (args.length == 0)
{
- System.err.println("Usage: FileMessageDispatcher <filesToDispatch>" + "");
+ System.out.println("Usage: FileMessageDispatcher <filesToDispatch>" + "");
}
else
{
try
{
- //publish message(s) from file(s) to configured queue
+ // publish message(s) from file(s) to configured queue
publish(args[0]);
- //Move payload file(s) to archive location as no error
+ // Move payload file(s) to archive location as no error
FileUtils.moveFileToNewDir(args[0], System.getProperties().getProperty(Statics.ARCHIVE_PATH));
}
- catch(Exception e)
+ catch (Exception e)
{
- //log error and exit
+ // log error and exit
_logger.error("Error trying to dispatch message: " + e);
System.exit(1);
}
finally
{
- //clean up before exiting
+ // clean up before exiting
if (getPublisher() != null)
{
getPublisher().cleanup();
@@ -98,10 +101,10 @@ public class FileMessageDispatcher {
File tempFile = new File(path);
if (tempFile.isDirectory())
{
- //while more files in dir publish them
+ // while more files in dir publish them
File[] files = tempFile.listFiles();
- if (files == null || files.length == 0)
+ if ((files == null) || (files.length == 0))
{
_logger.info("FileMessageDispatcher - No files to publish in input directory: " + tempFile);
}
@@ -109,10 +112,10 @@ public class FileMessageDispatcher {
{
for (File file : files)
{
- //Create message factory passing in payload path
+ // Create message factory passing in payload path
FileMessageFactory factory = new FileMessageFactory(getPublisher().getSession(), file.toString());
- //Send the message generated from the payload using the _publisher
+ // Send the message generated from the payload using the _publisher
getPublisher().sendMessage(factory.createEventMessage());
}
@@ -120,11 +123,11 @@ public class FileMessageDispatcher {
}
else
{
- //handle a single file
- //Create message factory passing in payload path
- FileMessageFactory factory = new FileMessageFactory(getPublisher().getSession(),tempFile.toString());
+ // handle a single file
+ // Create message factory passing in payload path
+ FileMessageFactory factory = new FileMessageFactory(getPublisher().getSession(), tempFile.toString());
- //Send the message generated from the payload using the _publisher
+ // Send the message generated from the payload using the _publisher
getPublisher().sendMessage(factory.createEventMessage());
}
}
@@ -145,15 +148,15 @@ public class FileMessageDispatcher {
*/
private static Publisher getPublisher()
{
- if (_publisher != null)
- {
- return _publisher;
- }
+ if (_publisher != null)
+ {
+ return _publisher;
+ }
- //Create a _publisher
- _publisher = new Publisher();
+ // Create a _publisher
+ _publisher = new Publisher();
- return _publisher;
+ return _publisher;
}
}
diff --git a/qpid/java/client/example/src/main/java/org/apache/qpid/example/publisher/FileMessageFactory.java b/qpid/java/client/example/src/main/java/org/apache/qpid/example/publisher/FileMessageFactory.java
index 88bcbbbccb..f3b21e3c64 100644
--- a/qpid/java/client/example/src/main/java/org/apache/qpid/example/publisher/FileMessageFactory.java
+++ b/qpid/java/client/example/src/main/java/org/apache/qpid/example/publisher/FileMessageFactory.java
@@ -47,7 +47,9 @@ public class FileMessageFactory
}
catch (IOException e)
{
- throw new MessageFactoryException(e.toString());
+ MessageFactoryException mfe = new MessageFactoryException(e.toString());
+ mfe.initCause(e);
+ throw mfe;
}
}
diff --git a/qpid/java/client/example/src/main/java/org/apache/qpid/example/shared/InitialContextHelper.java b/qpid/java/client/example/src/main/java/org/apache/qpid/example/shared/InitialContextHelper.java
index 8505d1d457..98a2c0d497 100644
--- a/qpid/java/client/example/src/main/java/org/apache/qpid/example/shared/InitialContextHelper.java
+++ b/qpid/java/client/example/src/main/java/org/apache/qpid/example/shared/InitialContextHelper.java
@@ -59,11 +59,11 @@ public class InitialContextHelper
}
catch (IOException e)
{
- throw new ContextException(e.toString());
+ throw new ContextException(e.toString(), e);
}
catch (NamingException n)
{
- throw new ContextException(n.toString());
+ throw new ContextException(n.toString(), n);
}
}
diff --git a/qpid/java/client/src/main/java/org/apache/qpid/client/AMQConnection.java b/qpid/java/client/src/main/java/org/apache/qpid/client/AMQConnection.java
index 413524b6d8..0e3d99eeba 100644
--- a/qpid/java/client/src/main/java/org/apache/qpid/client/AMQConnection.java
+++ b/qpid/java/client/src/main/java/org/apache/qpid/client/AMQConnection.java
@@ -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
@@ -20,6 +20,29 @@
*/
package org.apache.qpid.client;
+import java.io.IOException;
+import java.net.ConnectException;
+import java.nio.channels.UnresolvedAddressException;
+import java.text.MessageFormat;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.LinkedHashMap;
+import java.util.LinkedList;
+import java.util.Map;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicInteger;
+
+import javax.jms.*;
+import javax.jms.IllegalStateException;
+import javax.naming.NamingException;
+import javax.naming.Reference;
+import javax.naming.Referenceable;
+import javax.naming.StringRefAddr;
+
+import org.apache.log4j.Logger;
+
import org.apache.qpid.AMQConnectionFailureException;
import org.apache.qpid.AMQException;
import org.apache.qpid.AMQUndeliveredException;
@@ -44,28 +67,6 @@ import org.apache.qpid.jms.ConnectionURL;
import org.apache.qpid.jms.FailoverPolicy;
import org.apache.qpid.url.URLSyntaxException;
-import org.apache.log4j.Logger;
-
-import javax.jms.*;
-import javax.jms.IllegalStateException;
-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;
-import java.text.MessageFormat;
-import java.util.ArrayList;
-import java.util.Iterator;
-import java.util.LinkedHashMap;
-import java.util.LinkedList;
-import java.util.Map;
-import java.util.concurrent.atomic.AtomicInteger;
-import java.util.concurrent.Executors;
-import java.util.concurrent.ExecutorService;
-import java.util.concurrent.TimeUnit;
-
public class AMQConnection extends Closeable implements Connection, QueueConnection, TopicConnection, Referenceable
{
private static final Logger _logger = Logger.getLogger(AMQConnection.class);
@@ -95,7 +96,7 @@ public class AMQConnection extends Closeable implements Connection, QueueConnect
private AMQProtocolHandler _protocolHandler;
/** Maps from session id (Integer) to AMQSession instance */
- private final Map _sessions = new LinkedHashMap(); //fixme this is map is replicated in amqprotocolsession as _channelId2SessionMap
+ private final Map _sessions = new LinkedHashMap(); // fixme this is map is replicated in amqprotocolsession as _channelId2SessionMap
private String _clientName;
@@ -125,15 +126,14 @@ public class AMQConnection extends Closeable implements Connection, QueueConnect
/*
* _Connected should be refactored with a suitable wait object.
- */
+ */
private boolean _connected;
/*
* The last error code that occured on the connection. Used to return the correct exception to the client
- */
+ */
private AMQException _lastAMQException = null;
-
/*
* The connection meta data
*/
@@ -149,6 +149,7 @@ public class AMQConnection extends Closeable implements Connection, QueueConnect
/** Thread Pool for executing connection level processes. Such as returning bounced messages. */
private final ExecutorService _taskPool = Executors.newCachedThreadPool();
+ private static final long DEFAULT_TIMEOUT = 1000 * 30;
/**
* @param broker brokerdetails
@@ -160,13 +161,13 @@ public class AMQConnection extends Closeable implements Connection, QueueConnect
* @throws AMQException
* @throws URLSyntaxException
*/
- public AMQConnection(String broker, String username, String password,
- String clientName, String virtualHost) throws AMQException, URLSyntaxException
+ public AMQConnection(String broker, String username, String password, String clientName, String virtualHost)
+ throws AMQException, URLSyntaxException
{
- this(new AMQConnectionURL(ConnectionURL.AMQ_PROTOCOL + "://" +
- username + ":" + password + "@" +
- (clientName == null ? "" : clientName) + "/" +
- virtualHost + "?brokerlist='" + AMQBrokerDetails.checkTransport(broker) + "'"), null);
+ this(new AMQConnectionURL(
+ ConnectionURL.AMQ_PROTOCOL + "://" + username + ":" + password + "@"
+ + ((clientName == null) ? "" : clientName) + "/" + virtualHost + "?brokerlist='"
+ + AMQBrokerDetails.checkTransport(broker) + "'"), null);
}
/**
@@ -179,44 +180,38 @@ public class AMQConnection extends Closeable implements Connection, QueueConnect
* @throws AMQException
* @throws URLSyntaxException
*/
- public AMQConnection(String broker, String username, String password,
- String clientName, String virtualHost, SSLConfiguration sslConfig) throws AMQException, URLSyntaxException
+ public AMQConnection(String broker, String username, String password, String clientName, String virtualHost,
+ SSLConfiguration sslConfig) throws AMQException, URLSyntaxException
{
- this(new AMQConnectionURL(ConnectionURL.AMQ_PROTOCOL + "://" +
- username + ":" + password + "@" +
- (clientName == null ? "" : clientName) + "/" +
- virtualHost + "?brokerlist='" + AMQBrokerDetails.checkTransport(broker) + "'"), sslConfig);
+ this(new AMQConnectionURL(
+ ConnectionURL.AMQ_PROTOCOL + "://" + username + ":" + password + "@"
+ + ((clientName == null) ? "" : clientName) + "/" + virtualHost + "?brokerlist='"
+ + AMQBrokerDetails.checkTransport(broker) + "'"), sslConfig);
}
-
- public AMQConnection(String host, int port, String username, String password,
- String clientName, String virtualHost) throws AMQException, URLSyntaxException
+ public AMQConnection(String host, int port, String username, String password, String clientName, String virtualHost)
+ throws AMQException, URLSyntaxException
{
this(host, port, false, username, password, clientName, virtualHost, null);
}
- public AMQConnection(String host, int port, String username, String password,
- String clientName, String virtualHost, SSLConfiguration sslConfig) throws AMQException, URLSyntaxException
+ public AMQConnection(String host, int port, String username, String password, String clientName, String virtualHost,
+ SSLConfiguration sslConfig) throws AMQException, URLSyntaxException
{
this(host, port, false, username, password, clientName, virtualHost, sslConfig);
}
-
- public AMQConnection(String host, int port, boolean useSSL, String username, String password,
- String clientName, String virtualHost, SSLConfiguration sslConfig) throws AMQException, URLSyntaxException
+ public AMQConnection(String host, int port, boolean useSSL, String username, String password, String clientName,
+ String virtualHost, SSLConfiguration sslConfig) throws AMQException, URLSyntaxException
{
- this(new AMQConnectionURL(useSSL ?
- ConnectionURL.AMQ_PROTOCOL + "://" +
- username + ":" + password + "@" +
- (clientName == null ? "" : clientName) +
- virtualHost + "?brokerlist='tcp://" + host + ":" + port + "'"
- + "," + ConnectionURL.OPTIONS_SSL + "='true'" :
- ConnectionURL.AMQ_PROTOCOL + "://" +
- username + ":" + password + "@" +
- (clientName == null ? "" : clientName) +
- virtualHost + "?brokerlist='tcp://" + host + ":" + port + "'"
- + "," + ConnectionURL.OPTIONS_SSL + "='false'"
- ), sslConfig);
+ this(new AMQConnectionURL(
+ useSSL
+ ? (ConnectionURL.AMQ_PROTOCOL + "://" + username + ":" + password + "@"
+ + ((clientName == null) ? "" : clientName) + virtualHost + "?brokerlist='tcp://" + host + ":" + port
+ + "'" + "," + ConnectionURL.OPTIONS_SSL + "='true'")
+ : (ConnectionURL.AMQ_PROTOCOL + "://" + username + ":" + password + "@"
+ + ((clientName == null) ? "" : clientName) + virtualHost + "?brokerlist='tcp://" + host + ":" + port
+ + "'" + "," + ConnectionURL.OPTIONS_SSL + "='false'")), sslConfig);
}
public AMQConnection(String connection) throws AMQException, URLSyntaxException
@@ -229,13 +224,13 @@ public class AMQConnection extends Closeable implements Connection, QueueConnect
this(new AMQConnectionURL(connection), sslConfig);
}
-
public AMQConnection(ConnectionURL connectionURL, SSLConfiguration sslConfig) throws AMQException
{
if (_logger.isInfoEnabled())
{
_logger.info("Connection:" + connectionURL);
}
+
_sslConfiguration = sslConfig;
if (connectionURL == null)
{
@@ -249,7 +244,6 @@ public class AMQConnection extends Closeable implements Connection, QueueConnect
_password = connectionURL.getPassword();
setVirtualHost(connectionURL.getVirtualHost());
-
if (connectionURL.getDefaultQueueExchangeName() != null)
{
_defaultQueueExchangeName = connectionURL.getDefaultQueueExchangeName();
@@ -270,7 +264,6 @@ public class AMQConnection extends Closeable implements Connection, QueueConnect
_temporaryTopicExchangeName = connectionURL.getTemporaryTopicExchangeName();
}
-
_failoverPolicy = new FailoverPolicy(connectionURL);
_protocolHandler = new AMQProtocolHandler(this);
@@ -278,7 +271,6 @@ public class AMQConnection extends Closeable implements Connection, QueueConnect
// We are not currently connected
_connected = false;
-
Exception lastException = new Exception();
lastException.initCause(new ConnectException());
@@ -296,7 +288,8 @@ public class AMQConnection extends Closeable implements Connection, QueueConnect
if (_logger.isInfoEnabled())
{
- _logger.info("Unable to connect to broker at " + _failoverPolicy.getCurrentBrokerDetails(), e.getCause());
+ _logger.info("Unable to connect to broker at " + _failoverPolicy.getCurrentBrokerDetails(),
+ e.getCause());
}
}
}
@@ -322,7 +315,7 @@ public class AMQConnection extends Closeable implements Connection, QueueConnect
}
}
- if (message == null || message.equals(""))
+ if ((message == null) || message.equals(""))
{
message = "Unable to Connect";
}
@@ -335,11 +328,13 @@ public class AMQConnection extends Closeable implements Connection, QueueConnect
{
e = new AMQUnresolvedAddressException(message, _failoverPolicy.getCurrentBrokerDetails().toString());
}
+
e.initCause(lastException);
}
throw e;
}
+
_connectionMetaData = new QpidConnectionMetaData(this);
}
@@ -369,6 +364,7 @@ public class AMQConnection extends Closeable implements Connection, QueueConnect
{
virtualHost = virtualHost.substring(1);
}
+
_virtualHost = virtualHost;
}
@@ -382,7 +378,7 @@ public class AMQConnection extends Closeable implements Connection, QueueConnect
_protocolHandler.attainState(AMQState.CONNECTION_OPEN);
_failoverPolicy.attainedConnection();
- //Again this should be changed to a suitable notify
+ // Again this should be changed to a suitable notify
_connected = true;
}
catch (AMQException e)
@@ -401,6 +397,7 @@ public class AMQConnection extends Closeable implements Connection, QueueConnect
try
{
makeBrokerConnection(bd);
+
return true;
}
catch (Exception e)
@@ -409,8 +406,10 @@ public class AMQConnection extends Closeable implements Connection, QueueConnect
{
_logger.info("Unable to connect to broker at " + bd);
}
+
attemptReconnection();
}
+
return false;
}
@@ -421,6 +420,7 @@ public class AMQConnection extends Closeable implements Connection, QueueConnect
try
{
makeBrokerConnection(_failoverPolicy.getNextBrokerDetails());
+
return true;
}
catch (Exception e)
@@ -436,13 +436,14 @@ public class AMQConnection extends Closeable implements Connection, QueueConnect
{
if (_logger.isInfoEnabled())
{
- _logger.info(e.getMessage() + ":Unable to connect to broker at " + _failoverPolicy.getCurrentBrokerDetails());
+ _logger.info(e.getMessage() + ":Unable to connect to broker at "
+ + _failoverPolicy.getCurrentBrokerDetails());
}
}
}
}
- //connection unsuccessful
+ // connection unsuccessful
return false;
}
@@ -474,14 +475,14 @@ public class AMQConnection extends Closeable implements Connection, QueueConnect
return createSession(transacted, acknowledgeMode, AMQSession.DEFAULT_PREFETCH_HIGH_MARK);
}
- public org.apache.qpid.jms.Session createSession(final boolean transacted, final int acknowledgeMode,
- final int prefetch) throws JMSException
+ public org.apache.qpid.jms.Session createSession(final boolean transacted, final int acknowledgeMode, final int prefetch)
+ throws JMSException
{
return createSession(transacted, acknowledgeMode, prefetch, prefetch);
}
public org.apache.qpid.jms.Session createSession(final boolean transacted, final int acknowledgeMode,
- final int prefetchHigh, final int prefetchLow) throws JMSException
+ final int prefetchHigh, final int prefetchLow) throws JMSException
{
checkNotClosed();
if (channelLimitReached())
@@ -491,85 +492,81 @@ public class AMQConnection extends Closeable implements Connection, QueueConnect
else
{
return (org.apache.qpid.jms.Session) new FailoverSupport()
- {
- public Object operation() throws JMSException
- {
- int channelId = _idFactory.incrementAndGet();
-
- if (_logger.isDebugEnabled())
- {
- _logger.debug("Write channel open frame for channel id " + channelId);
- }
-
- // We must create the session and register it before actually sending the frame to the server to
- // open it, so that there is no window where we could receive data on the channel and not be set
- // up to handle it appropriately.
- AMQSession session = new AMQSession(AMQConnection.this, channelId, transacted, acknowledgeMode,
- prefetchHigh, prefetchLow);
- _protocolHandler.addSessionByChannel(channelId, session);
- registerSession(channelId, session);
-
- boolean success = false;
- try
- {
- createChannelOverWire(channelId, prefetchHigh, prefetchLow, transacted);
- success = true;
- }
- catch (AMQException e)
- {
- JMSException jmse = new JMSException("Error creating session: " + e);
- jmse.setLinkedException(e);
- throw jmse;
- }
- finally
- {
- if (!success)
- {
- _protocolHandler.removeSessionByChannel(channelId);
- deregisterSession(channelId);
- }
- }
-
- if (_started)
{
- try
- {
- session.start();
- }
- catch (AMQException e)
+ public Object operation() throws JMSException
{
- throw new JMSAMQException(e);
+ int channelId = _idFactory.incrementAndGet();
+
+ if (_logger.isDebugEnabled())
+ {
+ _logger.debug("Write channel open frame for channel id " + channelId);
+ }
+
+ // We must create the session and register it before actually sending the frame to the server to
+ // open it, so that there is no window where we could receive data on the channel and not be set
+ // up to handle it appropriately.
+ AMQSession session =
+ new AMQSession(AMQConnection.this, channelId, transacted, acknowledgeMode, prefetchHigh,
+ prefetchLow);
+ _protocolHandler.addSessionByChannel(channelId, session);
+ registerSession(channelId, session);
+
+ boolean success = false;
+ try
+ {
+ createChannelOverWire(channelId, prefetchHigh, prefetchLow, transacted);
+ success = true;
+ }
+ catch (AMQException e)
+ {
+ JMSException jmse = new JMSException("Error creating session: " + e);
+ jmse.setLinkedException(e);
+ throw jmse;
+ }
+ finally
+ {
+ if (!success)
+ {
+ _protocolHandler.removeSessionByChannel(channelId);
+ deregisterSession(channelId);
+ }
+ }
+
+ if (_started)
+ {
+ try
+ {
+ session.start();
+ }
+ catch (AMQException e)
+ {
+ throw new JMSAMQException(e);
+ }
+ }
+
+ return session;
}
- }
- return session;
- }
- }.execute(this);
+ }.execute(this);
}
}
private void createChannelOverWire(int channelId, int prefetchHigh, int prefetchLow, boolean transacted)
- throws AMQException
+ throws AMQException
{
// TODO: Be aware of possible changes to parameter order as versions change.
- _protocolHandler.syncWrite(
- ChannelOpenBody.createAMQFrame(channelId,
- _protocolHandler.getProtocolMajorVersion(),
- _protocolHandler.getProtocolMinorVersion(),
- null), // outOfBand
- ChannelOpenOkBody.class);
-
- //todo send low water mark when protocol allows.
- //todo Be aware of possible changes to parameter order as versions change.
- _protocolHandler.syncWrite(
- BasicQosBody.createAMQFrame(channelId,
- _protocolHandler.getProtocolMajorVersion(),
- _protocolHandler.getProtocolMinorVersion(),
- false, // global
- prefetchHigh, // prefetchCount
- 0), // prefetchSize
- BasicQosOkBody.class);
+ _protocolHandler.syncWrite(ChannelOpenBody.createAMQFrame(channelId, _protocolHandler.getProtocolMajorVersion(),
+ _protocolHandler.getProtocolMinorVersion(), null), // outOfBand
+ ChannelOpenOkBody.class);
+
+ // todo send low water mark when protocol allows.
+ // todo Be aware of possible changes to parameter order as versions change.
+ _protocolHandler.syncWrite(BasicQosBody.createAMQFrame(channelId, _protocolHandler.getProtocolMajorVersion(),
+ _protocolHandler.getProtocolMinorVersion(), false, // global
+ prefetchHigh, // prefetchCount
+ 0), // prefetchSize
+ BasicQosOkBody.class);
if (transacted)
{
@@ -579,10 +576,8 @@ public class AMQConnection extends Closeable implements Connection, QueueConnect
}
// TODO: Be aware of possible changes to parameter order as versions change.
- _protocolHandler.syncWrite(TxSelectBody.createAMQFrame(channelId,
- _protocolHandler.getProtocolMajorVersion(),
- _protocolHandler.getProtocolMinorVersion()),
- TxSelectOkBody.class);
+ _protocolHandler.syncWrite(TxSelectBody.createAMQFrame(channelId, _protocolHandler.getProtocolMajorVersion(),
+ _protocolHandler.getProtocolMinorVersion()), TxSelectOkBody.class);
}
}
@@ -596,11 +591,10 @@ public class AMQConnection extends Closeable implements Connection, QueueConnect
{
_protocolHandler.removeSessionByChannel(channelId);
deregisterSession(channelId);
- throw new AMQException("Error reopening channel " + channelId + " after failover: " + e);
+ throw new AMQException("Error reopening channel " + channelId + " after failover: " + e, e);
}
}
-
public void setFailoverPolicy(FailoverPolicy policy)
{
_failoverPolicy = policy;
@@ -645,12 +639,13 @@ public class AMQConnection extends Closeable implements Connection, QueueConnect
private boolean channelLimitReached()
{
- return _maximumChannelCount != 0 && _sessions.size() == _maximumChannelCount;
+ return (_maximumChannelCount != 0) && (_sessions.size() == _maximumChannelCount);
}
public String getClientID() throws JMSException
{
checkNotClosed();
+
return _clientName;
}
@@ -666,6 +661,7 @@ public class AMQConnection extends Closeable implements Connection, QueueConnect
public ConnectionMetaData getMetaData() throws JMSException
{
checkNotClosed();
+
return _connectionMetaData;
}
@@ -673,6 +669,7 @@ public class AMQConnection extends Closeable implements Connection, QueueConnect
public ExceptionListener getExceptionListener() throws JMSException
{
checkNotClosed();
+
return _exceptionListener;
}
@@ -706,6 +703,7 @@ public class AMQConnection extends Closeable implements Connection, QueueConnect
throw new JMSAMQException(e);
}
}
+
_started = true;
}
}
@@ -726,13 +724,14 @@ public class AMQConnection extends Closeable implements Connection, QueueConnect
throw new JMSAMQException(e);
}
}
+
_started = false;
}
}
public void close() throws JMSException
{
- close(-1);
+ close(DEFAULT_TIMEOUT);
}
public void close(long timeout) throws JMSException
@@ -752,7 +751,7 @@ public class AMQConnection extends Closeable implements Connection, QueueConnect
{
try
{
- //adjust timeout
+ // adjust timeout
long taskPoolTimeout = adjustTimeout(timeout, startCloseTime);
_taskPool.awaitTermination(taskPoolTimeout, TimeUnit.MILLISECONDS);
@@ -763,7 +762,7 @@ public class AMQConnection extends Closeable implements Connection, QueueConnect
}
}
- //adjust timeout
+ // adjust timeout
timeout = adjustTimeout(timeout, startCloseTime);
_protocolHandler.closeConnection(timeout);
@@ -771,7 +770,9 @@ public class AMQConnection extends Closeable implements Connection, QueueConnect
}
catch (AMQException e)
{
- throw new JMSException("Error closing connection: " + e);
+ JMSException jmse = new JMSException("Error closing connection: " + e);
+ jmse.setLinkedException(e);
+ throw jmse;
}
}
}
@@ -785,6 +786,7 @@ public class AMQConnection extends Closeable implements Connection, QueueConnect
{
timeout = 0;
}
+
return timeout;
}
@@ -803,6 +805,7 @@ public class AMQConnection extends Closeable implements Connection, QueueConnect
session.markClosed();
}
+
_sessions.clear();
}
@@ -842,6 +845,7 @@ public class AMQConnection extends Closeable implements Connection, QueueConnect
}
}
}
+
_sessions.clear();
if (sessionException != null)
{
@@ -850,42 +854,42 @@ public class AMQConnection extends Closeable implements Connection, QueueConnect
}
public ConnectionConsumer createConnectionConsumer(Destination destination, String messageSelector,
- ServerSessionPool sessionPool,
- int maxMessages) throws JMSException
+ ServerSessionPool sessionPool, int maxMessages) throws JMSException
{
checkNotClosed();
+
return null;
}
- public ConnectionConsumer createConnectionConsumer(Queue queue, String messageSelector,
- ServerSessionPool sessionPool,
- int maxMessages) throws JMSException
+ public ConnectionConsumer createConnectionConsumer(Queue queue, String messageSelector, ServerSessionPool sessionPool,
+ int maxMessages) throws JMSException
{
checkNotClosed();
+
return null;
}
- public ConnectionConsumer createConnectionConsumer(Topic topic, String messageSelector,
- ServerSessionPool sessionPool,
- int maxMessages) throws JMSException
+ public ConnectionConsumer createConnectionConsumer(Topic topic, String messageSelector, ServerSessionPool sessionPool,
+ int maxMessages) throws JMSException
{
checkNotClosed();
+
return null;
}
- public ConnectionConsumer createDurableConnectionConsumer(Topic topic, String subscriptionName,
- String messageSelector, ServerSessionPool sessionPool,
- int maxMessages)
- throws JMSException
+ public ConnectionConsumer createDurableConnectionConsumer(Topic topic, String subscriptionName, String messageSelector,
+ ServerSessionPool sessionPool, int maxMessages) throws JMSException
{
// TODO Auto-generated method stub
checkNotClosed();
+
return null;
}
public long getMaximumChannelCount() throws JMSException
{
checkNotClosed();
+
return _maximumChannelCount;
}
@@ -974,6 +978,7 @@ public class AMQConnection extends Closeable implements Connection, QueueConnect
{
proceed = _connectionListener.preFailover(redirect);
}
+
return proceed;
}
@@ -994,6 +999,7 @@ public class AMQConnection extends Closeable implements Connection, QueueConnect
{
markAllSessionsClosed();
}
+
return resubscribe;
}
else
@@ -1057,12 +1063,15 @@ public class AMQConnection extends Closeable implements Connection, QueueConnect
{
if (cause instanceof AMQException)
{
- je = new JMSException(Integer.toString(((AMQException) cause).getErrorCode().getCode()), "Exception thrown against " + toString() + ": " + cause);
+ je =
+ new JMSException(Integer.toString(((AMQException) cause).getErrorCode().getCode()),
+ "Exception thrown against " + toString() + ": " + cause);
}
else
{
je = new JMSException("Exception thrown against " + toString() + ": " + cause);
}
+
if (cause instanceof Exception)
{
je.setLinkedException((Exception) cause);
@@ -1090,6 +1099,7 @@ public class AMQConnection extends Closeable implements Connection, QueueConnect
{
_logger.info("Closing AMQConnection due to :" + cause.getMessage());
}
+
_closed.set(true);
closeAllSessions(cause, -1, -1); // FIXME: when doing this end up with RejectedExecutionException from executor.
}
@@ -1145,9 +1155,11 @@ public class AMQConnection extends Closeable implements Connection, QueueConnect
buf.append("Host: ").append(String.valueOf(bd.getHost()));
buf.append("\nPort: ").append(String.valueOf(bd.getPort()));
}
+
buf.append("\nVirtual Host: ").append(String.valueOf(_virtualHost));
buf.append("\nClient ID: ").append(String.valueOf(_clientName));
- buf.append("\nActive session count: ").append(_sessions == null ? 0 : _sessions.size());
+ buf.append("\nActive session count: ").append((_sessions == null) ? 0 : _sessions.size());
+
return buf.toString();
}
@@ -1158,11 +1170,8 @@ public class AMQConnection extends Closeable implements Connection, QueueConnect
public Reference getReference() throws NamingException
{
- return new Reference(
- AMQConnection.class.getName(),
- new StringRefAddr(AMQConnection.class.getName(), toURL()),
- AMQConnectionFactory.class.getName(),
- null); // factory location
+ return new Reference(AMQConnection.class.getName(), new StringRefAddr(AMQConnection.class.getName(), toURL()),
+ AMQConnectionFactory.class.getName(), null); // factory location
}
public SSLConfiguration getSSLConfiguration()
@@ -1175,19 +1184,16 @@ public class AMQConnection extends Closeable implements Connection, QueueConnect
return _defaultTopicExchangeName;
}
-
public void setDefaultTopicExchangeName(AMQShortString defaultTopicExchangeName)
{
_defaultTopicExchangeName = defaultTopicExchangeName;
}
-
public AMQShortString getDefaultQueueExchangeName()
{
return _defaultQueueExchangeName;
}
-
public void setDefaultQueueExchangeName(AMQShortString defaultQueueExchangeName)
{
_defaultQueueExchangeName = defaultQueueExchangeName;
@@ -1200,10 +1206,9 @@ public class AMQConnection extends Closeable implements Connection, QueueConnect
public AMQShortString getTemporaryQueueExchangeName()
{
- return _temporaryQueueExchangeName; //To change body of created methods use File | Settings | File Templates.
+ return _temporaryQueueExchangeName; // To change body of created methods use File | Settings | File Templates.
}
-
public void setTemporaryTopicExchangeName(AMQShortString temporaryTopicExchangeName)
{
_temporaryTopicExchangeName = temporaryTopicExchangeName;
diff --git a/qpid/java/client/src/main/java/org/apache/qpid/client/AMQConnectionURL.java b/qpid/java/client/src/main/java/org/apache/qpid/client/AMQConnectionURL.java
index 0dcc544ea8..b3fbd1f510 100644
--- a/qpid/java/client/src/main/java/org/apache/qpid/client/AMQConnectionURL.java
+++ b/qpid/java/client/src/main/java/org/apache/qpid/client/AMQConnectionURL.java
@@ -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
@@ -20,12 +20,6 @@
*/
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 java.net.URI;
import java.net.URISyntaxException;
import java.util.HashMap;
@@ -33,6 +27,12 @@ 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 String _url;
@@ -49,7 +49,6 @@ public class AMQConnectionURL implements ConnectionURL
private AMQShortString _temporaryTopicExchangeName;
private AMQShortString _temporaryQueueExchangeName;
-
public AMQConnectionURL(String fullURL) throws URLSyntaxException
{
_url = fullURL;
@@ -58,18 +57,18 @@ public class AMQConnectionURL implements ConnectionURL
_failoverOptions = new HashMap<String, String>();
// Connection URL format
- //amqp://[user:pass@][clientid]/virtualhost?brokerlist='tcp://host:port?option=\'value\',option=\'value\';vm://:3/virtualpath?option=\'value\'',failover='method?option=\'value\',option='value''"
+ // amqp://[user:pass@][clientid]/virtualhost?brokerlist='tcp://host:port?option=\'value\',option=\'value\';vm://:3/virtualpath?option=\'value\'',failover='method?option=\'value\',option='value''"
// Options are of course optional except for requiring a single broker in the broker list.
try
{
URI connection = new URI(fullURL);
- if (connection.getScheme() == null || !(connection.getScheme().equalsIgnoreCase(AMQ_PROTOCOL)))
+ if ((connection.getScheme() == null) || !(connection.getScheme().equalsIgnoreCase(AMQ_PROTOCOL)))
{
throw new URISyntaxException(fullURL, "Not an AMQP URL");
}
- if (connection.getHost() == null || connection.getHost().equals(""))
+ if ((connection.getHost() == null) || connection.getHost().equals(""))
{
String uid = AMQConnectionFactory.getUniqueClientID();
if (uid == null)
@@ -91,7 +90,7 @@ public class AMQConnectionURL implements ConnectionURL
if (userInfo == null)
{
- //Fix for Java 1.5 which doesn't parse UserInfo for non http URIs
+ // Fix for Java 1.5 which doesn't parse UserInfo for non http URIs
userInfo = connection.getAuthority();
if (userInfo != null)
@@ -112,16 +111,16 @@ public class AMQConnectionURL implements ConnectionURL
if (userInfo == null)
{
- throw URLHelper.parseError(AMQ_PROTOCOL.length() + 3,
- "User information not found on url", fullURL);
+ throw URLHelper.parseError(AMQ_PROTOCOL.length() + 3, "User information not found on url", fullURL);
}
else
{
parseUserInfo(userInfo);
}
+
String virtualHost = connection.getPath();
- if (virtualHost != null && (!virtualHost.equals("")))
+ if ((virtualHost != null) && (!virtualHost.equals("")))
{
setVirtualHost(virtualHost);
}
@@ -130,7 +129,7 @@ public class AMQConnectionURL implements ConnectionURL
int authLength = connection.getAuthority().length();
int start = AMQ_PROTOCOL.length() + 3;
int testIndex = start + authLength;
- if (testIndex < fullURL.length() && fullURL.charAt(testIndex) == '?')
+ if ((testIndex < fullURL.length()) && (fullURL.charAt(testIndex) == '?'))
{
throw URLHelper.parseError(start, testIndex - start, "Virtual host found", fullURL);
}
@@ -141,14 +140,9 @@ public class AMQConnectionURL implements ConnectionURL
}
-
URLHelper.parseOptions(_options, connection.getQuery());
processOptions();
-
- //Fragment is #string (not used)
- //System.out.println(connection.getFragment());
-
}
catch (URISyntaxException uris)
{
@@ -165,11 +159,10 @@ public class AMQConnectionURL implements ConnectionURL
}
else
{
- if (slash != 0 && fullURL.charAt(slash - 1) == ':')
+ 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,14 +175,14 @@ public class AMQConnectionURL implements ConnectionURL
private void parseUserInfo(String userinfo) throws URLSyntaxException
{
- //user info = user:pass
+ // user info = user:pass
int colonIndex = userinfo.indexOf(':');
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
{
@@ -205,7 +198,7 @@ public class AMQConnectionURL implements ConnectionURL
{
String brokerlist = _options.get(OPTIONS_BROKERLIST);
- //brokerlist tcp://host:port?option='value',option='value';vm://:3/virtualpath?option='value'
+ // brokerlist tcp://host:port?option='value',option='value';vm://:3/virtualpath?option='value'
StringTokenizer st = new StringTokenizer(brokerlist, "" + URLHelper.BROKER_SEPARATOR);
while (st.hasMoreTokens())
@@ -244,19 +237,16 @@ public class AMQConnectionURL implements ConnectionURL
_defaultTopicExchangeName = new AMQShortString(_options.get(OPTIONS_DEFAULT_TOPIC_EXCHANGE));
}
-
if (_options.containsKey(OPTIONS_DEFAULT_QUEUE_EXCHANGE))
{
_defaultQueueExchangeName = new AMQShortString(_options.get(OPTIONS_DEFAULT_QUEUE_EXCHANGE));
}
-
if (_options.containsKey(OPTIONS_TEMPORARY_QUEUE_EXCHANGE))
{
_temporaryQueueExchangeName = new AMQShortString(_options.get(OPTIONS_TEMPORARY_QUEUE_EXCHANGE));
}
-
if (_options.containsKey(OPTIONS_TEMPORARY_TOPIC_EXCHANGE))
{
_temporaryTopicExchangeName = new AMQShortString(_options.get(OPTIONS_TEMPORARY_TOPIC_EXCHANGE));
@@ -439,12 +429,11 @@ public class AMQConnectionURL implements ConnectionURL
return sb.toString();
}
-
public static void main(String[] args) throws URLSyntaxException
{
-
- String url2 = "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''";
+ String url2 =
+ "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);
@@ -452,5 +441,4 @@ public class AMQConnectionURL implements ConnectionURL
System.out.println(connectionurl2);
}
-
}
diff --git a/qpid/java/client/src/main/java/org/apache/qpid/client/AMQDestination.java b/qpid/java/client/src/main/java/org/apache/qpid/client/AMQDestination.java
index 661372845a..585991d905 100644
--- a/qpid/java/client/src/main/java/org/apache/qpid/client/AMQDestination.java
+++ b/qpid/java/client/src/main/java/org/apache/qpid/client/AMQDestination.java
@@ -53,6 +53,8 @@ public abstract class AMQDestination implements Destination, Referenceable
private String _url;
private AMQShortString _urlAsShortString;
+ private boolean _validated;
+
private byte[] _byteEncoding;
private static final int IS_DURABLE_MASK = 0x1;
private static final int IS_EXCLUSIVE_MASK = 0x2;
@@ -198,12 +200,16 @@ public abstract class AMQDestination implements Destination, Referenceable
{
return toURL();
- /*
- return "Destination: " + _destinationName + ", " +
- "Queue Name: " + _queueName + ", Exchange: " + _exchangeName +
- ", Exchange class: " + _exchangeClass + ", Exclusive: " + _isExclusive +
- ", AutoDelete: " + _isAutoDelete + ", Routing Key: " + getRoutingKey();
- */
+ }
+
+ public boolean isValidated()
+ {
+ return _validated;
+ }
+
+ public void setValidated(boolean validated)
+ {
+ _validated = validated;
}
public String toURL()
@@ -348,15 +354,7 @@ public abstract class AMQDestination implements Destination, Referenceable
{
return false;
}
- /* if (_isExclusive != that._isExclusive)
- {
- return false;
- }
- if (_isAutoDelete != that._isAutoDelete)
- {
- return false;
- }
- */
+
return true;
}
@@ -370,8 +368,7 @@ public abstract class AMQDestination implements Destination, Referenceable
{
result = 29 * result + _queueName.hashCode();
}
-// result = result * (_isExclusive ? 13 : 7);
-// result = result * (_isAutoDelete ? 13 : 7);
+
return result;
}
diff --git a/qpid/java/client/src/main/java/org/apache/qpid/client/AMQSession.java b/qpid/java/client/src/main/java/org/apache/qpid/client/AMQSession.java
index 82f9a036d2..8bb5b622f7 100644
--- a/qpid/java/client/src/main/java/org/apache/qpid/client/AMQSession.java
+++ b/qpid/java/client/src/main/java/org/apache/qpid/client/AMQSession.java
@@ -202,6 +202,7 @@ public class AMQSession extends Closeable implements Session, QueueSession, Topi
/** Responsible for decoding a message fragment and passing it to the appropriate message consumer. */
private static final Logger _dispatcherLogger = Logger.getLogger(Dispatcher.class);
+ private AtomicBoolean _firstDispatcher = new AtomicBoolean(true);
private class Dispatcher extends Thread
{
@@ -327,8 +328,11 @@ public class AMQSession extends Closeable implements Session, QueueSession, Topi
") is closed rejecting(requeue)...");
}
}
-
- rejectMessage(message, true);
+ // Don't reject if we're already closing
+ if (!_closed.get())
+ {
+ rejectMessage(message, true);
+ }
}
else
{
@@ -995,42 +999,42 @@ public class AMQSession extends Closeable implements Session, QueueSession, Topi
throw new java.lang.UnsupportedOperationException();
}
- public MessageProducer createProducer(Destination destination, boolean mandatory,
- boolean immediate, boolean waitUntilSent)
+ public BasicMessageProducer createProducer(Destination destination, boolean mandatory,
+ boolean immediate, boolean waitUntilSent)
throws JMSException
{
return createProducerImpl(destination, mandatory, immediate, waitUntilSent);
}
- public MessageProducer createProducer(Destination destination, boolean mandatory, boolean immediate)
+ public BasicMessageProducer createProducer(Destination destination, boolean mandatory, boolean immediate)
throws JMSException
{
return createProducerImpl(destination, mandatory, immediate);
}
- public MessageProducer createProducer(Destination destination, boolean immediate)
+ public BasicMessageProducer createProducer(Destination destination, boolean immediate)
throws JMSException
{
return createProducerImpl(destination, DEFAULT_MANDATORY, immediate);
}
- public MessageProducer createProducer(Destination destination) throws JMSException
+ public BasicMessageProducer createProducer(Destination destination) throws JMSException
{
return createProducerImpl(destination, DEFAULT_MANDATORY, DEFAULT_IMMEDIATE);
}
- private org.apache.qpid.jms.MessageProducer createProducerImpl(Destination destination, boolean mandatory,
- boolean immediate)
+ private BasicMessageProducer createProducerImpl(Destination destination, boolean mandatory,
+ boolean immediate)
throws JMSException
{
return createProducerImpl(destination, mandatory, immediate, false);
}
- private org.apache.qpid.jms.MessageProducer createProducerImpl(final Destination destination, final boolean mandatory,
- final boolean immediate, final boolean waitUntilSent)
+ private BasicMessageProducer createProducerImpl(final Destination destination, final boolean mandatory,
+ final boolean immediate, final boolean waitUntilSent)
throws JMSException
{
- return (org.apache.qpid.jms.MessageProducer) new FailoverSupport()
+ return (BasicMessageProducer) new FailoverSupport()
{
public Object operation() throws JMSException
{
@@ -1248,8 +1252,10 @@ public class AMQSession extends Closeable implements Session, QueueSession, Topi
{
JMSException ex = new JMSException("Error registering consumer: " + e);
- //todo remove
- e.printStackTrace();
+ if (_logger.isDebugEnabled())
+ {
+ e.printStackTrace();
+ }
ex.setLinkedException(e);
throw ex;
}
@@ -1926,6 +1932,24 @@ public class AMQSession extends Closeable implements Session, QueueSession, Topi
synchronized void startDistpatcherIfNecessary()
{
+ if (Boolean.parseBoolean(System.getProperties().getProperty("REGISTER_CONSUMERS_FLOWED", "false")))
+ {
+// if (!connectionStopped)
+ {
+ if (isSuspended() && _firstDispatcher.getAndSet(false))
+ {
+ try
+ {
+ suspendChannel(false);
+ }
+ catch (AMQException e)
+ {
+ _logger.info("Suspending channel threw an exception:" + e);
+ }
+ }
+ }
+ }
+
startDistpatcherIfNecessary(false);
}
@@ -1974,6 +1998,27 @@ public class AMQSession extends Closeable implements Session, QueueSession, Topi
bindQueue(amqd, queueName, protocolHandler, consumer.getRawSelectorFieldTable());
+ // The dispatcher will be null if we have just created this session
+ // so suspend the channel before we register our consumer so that we don't
+ // start prefetching until a receive/mListener is set.
+ if (Boolean.parseBoolean(System.getProperties().getProperty("REGISTER_CONSUMERS_FLOWED", "false")))
+ {
+ if (_dispatcher == null)
+ {
+ if (!isSuspended())
+ {
+ try
+ {
+ suspendChannel(true);
+ }
+ catch (AMQException e)
+ {
+ _logger.info("Suspending channel threw an exception:" + e);
+ }
+ }
+ }
+ }
+
try
{
consumeFromQueue(consumer, queueName, protocolHandler, nowait, consumer.getMessageSelector());
@@ -2089,7 +2134,7 @@ public class AMQSession extends Closeable implements Session, QueueSession, Topi
// Remove the consumer from the map
BasicMessageConsumer consumer = (BasicMessageConsumer) _consumers.get(consumerTag);
if (consumer != null)
- {
+ {
// fixme this isn't right.. needs to check if _queue contains data for this consumer
if (consumer.isAutoClose())// && _queue.isEmpty())
{
diff --git a/qpid/java/client/src/main/java/org/apache/qpid/client/BasicMessageConsumer.java b/qpid/java/client/src/main/java/org/apache/qpid/client/BasicMessageConsumer.java
index 73010ce517..1c3cdbcb65 100644
--- a/qpid/java/client/src/main/java/org/apache/qpid/client/BasicMessageConsumer.java
+++ b/qpid/java/client/src/main/java/org/apache/qpid/client/BasicMessageConsumer.java
@@ -20,9 +20,9 @@
*/
package org.apache.qpid.client;
+import java.util.Arrays;
import java.util.Iterator;
import java.util.List;
-import java.util.Arrays;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.TimeUnit;
@@ -34,6 +34,7 @@ import javax.jms.Message;
import javax.jms.MessageListener;
import org.apache.log4j.Logger;
+
import org.apache.qpid.AMQException;
import org.apache.qpid.client.message.AbstractJMSMessage;
import org.apache.qpid.client.message.MessageFactoryRegistry;
@@ -138,10 +139,10 @@ public class BasicMessageConsumer extends Closeable implements MessageConsumer
private boolean _noConsume;
private List<StackTraceElement> _closedStack = null;
- protected BasicMessageConsumer(int channelId, AMQConnection connection, AMQDestination destination, String messageSelector,
- boolean noLocal, MessageFactoryRegistry messageFactory, AMQSession session,
- AMQProtocolHandler protocolHandler, FieldTable rawSelectorFieldTable,
- int prefetchHigh, int prefetchLow, boolean exclusive, int acknowledgeMode, boolean noConsume, boolean autoClose)
+ protected BasicMessageConsumer(int channelId, AMQConnection connection, AMQDestination destination,
+ String messageSelector, boolean noLocal, MessageFactoryRegistry messageFactory, AMQSession session,
+ AMQProtocolHandler protocolHandler, FieldTable rawSelectorFieldTable, int prefetchHigh, int prefetchLow,
+ boolean exclusive, int acknowledgeMode, boolean noConsume, boolean autoClose)
{
_channelId = channelId;
_connection = connection;
@@ -160,7 +161,7 @@ public class BasicMessageConsumer extends Closeable implements MessageConsumer
_autoClose = autoClose;
_noConsume = noConsume;
- //Force queue browsers not to use acknowledge modes.
+ // Force queue browsers not to use acknowledge modes.
if (_noConsume)
{
_acknowledgeMode = Session.NO_ACKNOWLEDGE;
@@ -175,12 +176,14 @@ public class BasicMessageConsumer extends Closeable implements MessageConsumer
public String getMessageSelector() throws JMSException
{
checkPreConditions();
+
return _messageSelector;
}
public MessageListener getMessageListener() throws JMSException
{
checkPreConditions();
+
return _messageListener.get();
}
@@ -198,14 +201,14 @@ public class BasicMessageConsumer extends Closeable implements MessageConsumer
{
checkPreConditions();
- //if the current listener is non-null and the session is not stopped, then
- //it is an error to call this method.
+ // if the current listener is non-null and the session is not stopped, then
+ // it is an error to call this method.
- //i.e. it is only valid to call this method if
+ // i.e. it is only valid to call this method if
//
- // (a) the connection is stopped, in which case the dispatcher is not running
- // OR
- // (b) the listener is null AND we are not receiving synchronously at present
+ // (a) the connection is stopped, in which case the dispatcher is not running
+ // OR
+ // (b) the listener is null AND we are not receiving synchronously at present
//
if (!_session.getAMQConnection().started())
@@ -215,7 +218,8 @@ public class BasicMessageConsumer extends Closeable implements MessageConsumer
if (_logger.isDebugEnabled())
{
- _logger.debug("Session stopped : Message listener(" + messageListener + ") set for destination " + _destination);
+ _logger.debug("Session stopped : Message listener(" + messageListener + ") set for destination "
+ + _destination);
}
}
else
@@ -224,6 +228,7 @@ public class BasicMessageConsumer extends Closeable implements MessageConsumer
{
throw new javax.jms.IllegalStateException("Another thread is already receiving synchronously.");
}
+
if (!_messageListener.compareAndSet(null, messageListener))
{
throw new javax.jms.IllegalStateException("Attempt to alter listener while session is started.");
@@ -233,7 +238,7 @@ public class BasicMessageConsumer extends Closeable implements MessageConsumer
if (messageListener != null)
{
- //handle case where connection has already been started, and the dispatcher has alreaded started
+ // handle case where connection has already been started, and the dispatcher has alreaded started
// putting values on the _synchronousQueue
synchronized (_session)
@@ -263,10 +268,12 @@ public class BasicMessageConsumer extends Closeable implements MessageConsumer
{
throw new javax.jms.IllegalStateException("Another thread is already receiving.");
}
+
if (isMessageListenerSet())
{
throw new javax.jms.IllegalStateException("A listener has already been set.");
}
+
_receivingThread = Thread.currentThread();
}
@@ -331,6 +338,7 @@ public class BasicMessageConsumer extends Closeable implements MessageConsumer
{
return null;
}
+
Object o = null;
if (l > 0)
{
@@ -340,6 +348,7 @@ public class BasicMessageConsumer extends Closeable implements MessageConsumer
{
o = _synchronousQueue.take();
}
+
final AbstractJMSMessage m = returnMessageOrThrow(o);
if (m != null)
{
@@ -352,6 +361,7 @@ public class BasicMessageConsumer extends Closeable implements MessageConsumer
catch (InterruptedException e)
{
_logger.warn("Interrupted: " + e);
+
return null;
}
finally
@@ -365,6 +375,7 @@ public class BasicMessageConsumer extends Closeable implements MessageConsumer
if (isAutoClose() && _closeWhenNoMessages && _synchronousQueue.isEmpty())
{
close(false);
+
return true;
}
else
@@ -387,6 +398,7 @@ public class BasicMessageConsumer extends Closeable implements MessageConsumer
{
return null;
}
+
Object o = _synchronousQueue.poll();
final AbstractJMSMessage m = returnMessageOrThrow(o);
if (m != null)
@@ -414,8 +426,7 @@ public class BasicMessageConsumer extends Closeable implements MessageConsumer
* @throws JMSException if the argument is a throwable. If it is a JMSException it is rethrown as is, but if not a
* JMSException is created with the linked exception set appropriately
*/
- private AbstractJMSMessage returnMessageOrThrow(Object o)
- throws JMSException
+ private AbstractJMSMessage returnMessageOrThrow(Object o) throws JMSException
{
// errors are passed via the queue too since there is no way of interrupting the poll() via the API.
if (o instanceof Throwable)
@@ -425,6 +436,7 @@ public class BasicMessageConsumer extends Closeable implements MessageConsumer
{
e.setLinkedException((Exception) o);
}
+
throw e;
}
else
@@ -433,7 +445,6 @@ public class BasicMessageConsumer extends Closeable implements MessageConsumer
}
}
-
public void close() throws JMSException
{
close(true);
@@ -441,7 +452,7 @@ public class BasicMessageConsumer extends Closeable implements MessageConsumer
public void close(boolean sendClose) throws JMSException
{
- //synchronized (_closed)
+ // synchronized (_closed)
if (_logger.isInfoEnabled())
{
@@ -456,7 +467,8 @@ public class BasicMessageConsumer extends Closeable implements MessageConsumer
{
if (_closedStack != null)
{
- _logger.trace(_consumerTag + " close():" + Arrays.asList(Thread.currentThread().getStackTrace()).subList(3, 6));
+ _logger.trace(_consumerTag + " close():"
+ + Arrays.asList(Thread.currentThread().getStackTrace()).subList(3, 6));
_logger.trace(_consumerTag + " previously:" + _closedStack.toString());
}
else
@@ -464,14 +476,14 @@ public class BasicMessageConsumer extends Closeable implements MessageConsumer
_closedStack = Arrays.asList(Thread.currentThread().getStackTrace()).subList(3, 6);
}
}
+
if (sendClose)
{
// TODO: Be aware of possible changes to parameter order as versions change.
- final AMQFrame cancelFrame = BasicCancelBody.createAMQFrame(_channelId,
- _protocolHandler.getProtocolMajorVersion(),
- _protocolHandler.getProtocolMinorVersion(),
- _consumerTag, // consumerTag
- false); // nowait
+ final AMQFrame cancelFrame =
+ BasicCancelBody.createAMQFrame(_channelId, _protocolHandler.getProtocolMajorVersion(),
+ _protocolHandler.getProtocolMinorVersion(), _consumerTag, // consumerTag
+ false); // nowait
try
{
@@ -485,25 +497,28 @@ public class BasicMessageConsumer extends Closeable implements MessageConsumer
}
catch (AMQException e)
{
- _logger.error("Error closing consumer: " + e, e);
- throw new JMSException("Error closing consumer: " + e);
+ // _logger.error("Error closing consumer: " + e, e);
+ JMSException jmse = new JMSException("Error closing consumer: " + e);
+ jmse.setLinkedException(e);
+ throw jmse;
}
}
else
{
-// //fixme this probably is not right
-// if (!isNoConsume())
- { //done in BasicCancelOK Handler but not sending one so just deregister.
+ // //fixme this probably is not right
+ // if (!isNoConsume())
+ { // done in BasicCancelOK Handler but not sending one so just deregister.
deregisterConsumer();
}
}
- if (_messageListener != null && _receiving.get())
+ if ((_messageListener != null) && _receiving.get())
{
if (_logger.isInfoEnabled())
{
_logger.info("Interrupting thread: " + _receivingThread);
}
+
_receivingThread.interrupt();
}
}
@@ -516,7 +531,7 @@ public class BasicMessageConsumer extends Closeable implements MessageConsumer
*/
void markClosed()
{
-// synchronized (_closed)
+ // synchronized (_closed)
{
_closed.set(true);
@@ -524,7 +539,8 @@ public class BasicMessageConsumer extends Closeable implements MessageConsumer
{
if (_closedStack != null)
{
- _logger.trace(_consumerTag + " markClosed():" + Arrays.asList(Thread.currentThread().getStackTrace()).subList(3, 8));
+ _logger.trace(_consumerTag + " markClosed():"
+ + Arrays.asList(Thread.currentThread().getStackTrace()).subList(3, 8));
_logger.trace(_consumerTag + " previously:" + _closedStack.toString());
}
else
@@ -533,6 +549,7 @@ public class BasicMessageConsumer extends Closeable implements MessageConsumer
}
}
}
+
deregisterConsumer();
}
@@ -551,22 +568,22 @@ public class BasicMessageConsumer extends Closeable implements MessageConsumer
{
_logger.debug("notifyMessage called with message number " + messageFrame.getDeliverBody().deliveryTag);
}
+
try
{
- AbstractJMSMessage jmsMessage = _messageFactory.createMessage(messageFrame.getDeliverBody().deliveryTag,
- messageFrame.getDeliverBody().redelivered,
- messageFrame.getDeliverBody().exchange,
- messageFrame.getDeliverBody().routingKey,
- messageFrame.getContentHeader(),
- messageFrame.getBodies());
+ AbstractJMSMessage jmsMessage =
+ _messageFactory.createMessage(messageFrame.getDeliverBody().deliveryTag,
+ messageFrame.getDeliverBody().redelivered, messageFrame.getDeliverBody().exchange,
+ messageFrame.getDeliverBody().routingKey, messageFrame.getContentHeader(), messageFrame.getBodies());
if (debug)
{
_logger.debug("Message is of type: " + jmsMessage.getClass().getName());
}
-// synchronized (_closed)
+ // synchronized (_closed)
+
{
-// if (!_closed.get())
+ // if (!_closed.get())
{
jmsMessage.setConsumer(this);
@@ -575,12 +592,12 @@ public class BasicMessageConsumer extends Closeable implements MessageConsumer
notifyMessage(jmsMessage, channelId);
}
-// else
-// {
-// _logger.error("MESSAGE REJECTING!");
-// _session.rejectMessage(jmsMessage, true);
-// //_logger.error("MESSAGE JUST DROPPED!");
-// }
+ // else
+ // {
+ // _logger.error("MESSAGE REJECTING!");
+ // _session.rejectMessage(jmsMessage, true);
+ // //_logger.error("MESSAGE JUST DROPPED!");
+ // }
}
}
catch (Exception e)
@@ -606,11 +623,11 @@ public class BasicMessageConsumer extends Closeable implements MessageConsumer
{
if (isMessageListenerSet())
{
- //we do not need a lock around the test above, and the dispatch below as it is invalid
- //for an application to alter an installed listener while the session is started
-// synchronized (_closed)
+ // we do not need a lock around the test above, and the dispatch below as it is invalid
+ // for an application to alter an installed listener while the session is started
+ // synchronized (_closed)
{
-// if (!_closed.get())
+ // if (!_closed.get())
{
preApplicationProcessing(jmsMessage);
@@ -641,9 +658,11 @@ public class BasicMessageConsumer extends Closeable implements MessageConsumer
{
switch (_acknowledgeMode)
{
+
case Session.PRE_ACKNOWLEDGE:
_session.acknowledgeMessage(msg.getDeliveryTag(), false);
break;
+
case Session.CLIENT_ACKNOWLEDGE:
// we set the session so that when the user calls acknowledge() it can call the method on session
// to send out the appropriate frame
@@ -657,17 +676,21 @@ public class BasicMessageConsumer extends Closeable implements MessageConsumer
msg.setJMSDestination(_destination);
switch (_acknowledgeMode)
{
+
case Session.CLIENT_ACKNOWLEDGE:
if (isNoConsume())
{
_session.acknowledgeMessage(msg.getDeliveryTag(), false);
}
+
break;
+
case Session.DUPS_OK_ACKNOWLEDGE:
if (++_outstanding >= _prefetchHigh)
{
_dups_ok_acknowledge_send = true;
}
+
if (_outstanding <= _prefetchLow)
{
_dups_ok_acknowledge_send = false;
@@ -680,14 +703,18 @@ public class BasicMessageConsumer extends Closeable implements MessageConsumer
_session.acknowledgeMessage(msg.getDeliveryTag(), true);
}
}
+
break;
+
case Session.AUTO_ACKNOWLEDGE:
// we do not auto ack a message if the application code called recover()
if (!_session.isInRecovery())
{
_session.acknowledgeMessage(msg.getDeliveryTag(), false);
}
+
break;
+
case Session.SESSION_TRANSACTED:
if (isNoConsume())
{
@@ -697,6 +724,7 @@ public class BasicMessageConsumer extends Closeable implements MessageConsumer
{
_receivedDeliveryTags.add(msg.getDeliveryTag());
}
+
break;
}
}
@@ -721,14 +749,15 @@ public class BasicMessageConsumer extends Closeable implements MessageConsumer
void notifyError(Throwable cause)
{
-// synchronized (_closed)
+ // synchronized (_closed)
{
_closed.set(true);
if (_logger.isTraceEnabled())
{
if (_closedStack != null)
{
- _logger.trace(_consumerTag + " notifyError():" + Arrays.asList(Thread.currentThread().getStackTrace()).subList(3, 8));
+ _logger.trace(_consumerTag + " notifyError():"
+ + Arrays.asList(Thread.currentThread().getStackTrace()).subList(3, 8));
_logger.trace(_consumerTag + " previously" + _closedStack.toString());
}
else
@@ -737,7 +766,7 @@ public class BasicMessageConsumer extends Closeable implements MessageConsumer
}
}
}
- //QPID-293 can "request redelivery of this error through dispatcher"
+ // QPID-293 can "request redelivery of this error through dispatcher"
// we have no way of propagating the exception to a message listener - a JMS limitation - so we
// deal with the case where we have a synchronous receive() waiting for a message to arrive
@@ -749,10 +778,10 @@ public class BasicMessageConsumer extends Closeable implements MessageConsumer
_logger.debug("Passed exception to synchronous queue for propagation to receive()");
}
}
+
deregisterConsumer();
}
-
/**
* Perform cleanup to deregister this consumer. This occurs when closing the consumer in both the clean case and in
* the case of an error occurring.
@@ -782,7 +811,7 @@ public class BasicMessageConsumer extends Closeable implements MessageConsumer
this.checkNotClosed();
- if (_session == null || _session.isClosed())
+ if ((_session == null) || _session.isClosed())
{
throw new javax.jms.IllegalStateException("Invalid Session");
}
@@ -817,7 +846,6 @@ public class BasicMessageConsumer extends Closeable implements MessageConsumer
return _autoClose;
}
-
public boolean isNoConsume()
{
return _noConsume;
@@ -827,10 +855,7 @@ public class BasicMessageConsumer extends Closeable implements MessageConsumer
{
_closeWhenNoMessages = b;
- if (_closeWhenNoMessages
- && _synchronousQueue.isEmpty()
- && _receiving.get()
- && _messageListener != null)
+ if (_closeWhenNoMessages && _synchronousQueue.isEmpty() && _receiving.get() && (_messageListener != null))
{
_receivingThread.interrupt();
}
@@ -846,13 +871,13 @@ public class BasicMessageConsumer extends Closeable implements MessageConsumer
_logger.debug("Rejecting received messages in _receivedDTs (RQ)");
}
- //rollback received but not committed messages
+ // rollback received but not committed messages
while (!_receivedDeliveryTags.isEmpty())
{
if (_logger.isDebugEnabled())
{
- _logger.debug("Rejecting the messages(" + _receivedDeliveryTags.size() + ") in _receivedDTs (RQ)" +
- "for consumer with tag:" + _consumerTag);
+ _logger.debug("Rejecting the messages(" + _receivedDeliveryTags.size() + ") in _receivedDTs (RQ)"
+ + "for consumer with tag:" + _consumerTag);
}
Long tag = _receivedDeliveryTags.poll();
@@ -876,14 +901,15 @@ public class BasicMessageConsumer extends Closeable implements MessageConsumer
}
}
- //rollback pending messages
+ // rollback pending messages
if (_synchronousQueue.size() > 0)
{
if (_logger.isDebugEnabled())
{
- _logger.debug("Rejecting the messages(" + _synchronousQueue.size() + ") in _syncQueue (PRQ)" +
- "for consumer with tag:" + _consumerTag);
+ _logger.debug("Rejecting the messages(" + _synchronousQueue.size() + ") in _syncQueue (PRQ)"
+ + "for consumer with tag:" + _consumerTag);
}
+
Iterator iterator = _synchronousQueue.iterator();
while (iterator.hasNext())
@@ -898,13 +924,14 @@ public class BasicMessageConsumer extends Closeable implements MessageConsumer
{
_logger.trace("Rejected message:" + ((AbstractJMSMessage) o).getDeliveryTag());
}
+
iterator.remove();
}
else
{
- _logger.error("Queue contained a :" + o.getClass() +
- " unable to reject as it is not an AbstractJMSMessage. Will be cleared");
+ _logger.error("Queue contained a :" + o.getClass()
+ + " unable to reject as it is not an AbstractJMSMessage. Will be cleared");
iterator.remove();
}
}
@@ -919,7 +946,6 @@ public class BasicMessageConsumer extends Closeable implements MessageConsumer
}
}
-
public String debugIdentity()
{
return String.valueOf(_consumerTag);
diff --git a/qpid/java/client/src/main/java/org/apache/qpid/client/BasicMessageProducer.java b/qpid/java/client/src/main/java/org/apache/qpid/client/BasicMessageProducer.java
index b01e087ce1..bd7cc94582 100644
--- a/qpid/java/client/src/main/java/org/apache/qpid/client/BasicMessageProducer.java
+++ b/qpid/java/client/src/main/java/org/apache/qpid/client/BasicMessageProducer.java
@@ -21,6 +21,7 @@
package org.apache.qpid.client;
import java.io.UnsupportedEncodingException;
+import java.util.UUID;
import javax.jms.BytesMessage;
import javax.jms.DeliveryMode;
@@ -118,6 +119,9 @@ public class BasicMessageProducer extends Closeable implements org.apache.qpid.j
private final boolean _mandatory;
private final boolean _waitUntilSent;
+
+ private boolean _disableMessageId;
+
private static final ContentBody[] NO_CONTENT_BODIES = new ContentBody[0];
protected BasicMessageProducer(AMQConnection connection, AMQDestination destination, boolean transacted, int channelId,
@@ -172,15 +176,14 @@ public class BasicMessageProducer extends Closeable implements org.apache.qpid.j
{
checkPreConditions();
checkNotClosed();
- // IGNORED
+ _disableMessageId = b;
}
public boolean getDisableMessageID() throws JMSException
{
checkNotClosed();
- // Always false for AMQP
- return false;
+ return _disableMessageId;
}
public void setDisableMessageTimestamp(boolean b) throws JMSException
@@ -450,6 +453,18 @@ public class BasicMessageProducer extends Closeable implements org.apache.qpid.j
origMessage.setJMSDestination(destination);
AbstractJMSMessage message = convertToNativeMessage(origMessage);
+
+ if(_disableMessageId)
+ {
+ message.setJMSMessageID(null);
+ }
+ else
+ {
+ if (message.getJMSMessageID() == null)
+ {
+ message.setJMSMessageID(UUID.randomUUID().toString());
+ }
+ }
int type;
if (destination instanceof Topic)
@@ -667,4 +682,9 @@ public class BasicMessageProducer extends Closeable implements org.apache.qpid.j
{
return _session;
}
+
+ public boolean isBound(AMQDestination destination) throws JMSException
+ {
+ return _session.isQueueBound(destination.getExchangeName(),null,destination.getRoutingKey());
+ }
}
diff --git a/qpid/java/client/src/main/java/org/apache/qpid/client/JMSAMQException.java b/qpid/java/client/src/main/java/org/apache/qpid/client/JMSAMQException.java
index d2ab6bd2c2..d1237cff49 100644
--- a/qpid/java/client/src/main/java/org/apache/qpid/client/JMSAMQException.java
+++ b/qpid/java/client/src/main/java/org/apache/qpid/client/JMSAMQException.java
@@ -1,5 +1,25 @@
/*
*
+ * 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.
+ *
+ */
+/*
+ *
* Copyright (c) 2006 The Apache Software Foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
@@ -22,10 +42,35 @@ import javax.jms.JMSException;
import org.apache.qpid.AMQException;
/**
+ * JMSException does not accept wrapped exceptions in its constructor. Presumably this is because it is a relatively old
+ * Java exception class, before this was added as a default to Throwable. This exception class accepts wrapped exceptions
+ * as well as error messages, through its constructor, but is a JMSException.
+ *
+ * <p/><table id="crc"><caption>CRC Card</caption>
+ * <tr><th> Responsibilities <th> Collaborations
+ * <tr><td> Accept wrapped exceptions as a JMSException.
+ * </table>
+ *
* @author Apache Software Foundation
*/
public class JMSAMQException extends JMSException
{
+ /**
+ * Creates a JMSException, wrapping another exception class.
+ *
+ * @param message The error message.
+ * @param cause The underlying exception that caused this one. May be null if none is to be set.
+ */
+ public JMSAMQException(String message, Exception cause)
+ {
+ super(message);
+
+ if (cause != null)
+ {
+ setLinkedException(cause);
+ }
+ }
+
public JMSAMQException(AMQException s)
{
super(s.getMessage(), String.valueOf(s.getErrorCode()));
diff --git a/qpid/java/client/src/main/java/org/apache/qpid/client/QueueSenderAdapter.java b/qpid/java/client/src/main/java/org/apache/qpid/client/QueueSenderAdapter.java
index c9d29d8077..e0c4b61333 100644
--- a/qpid/java/client/src/main/java/org/apache/qpid/client/QueueSenderAdapter.java
+++ b/qpid/java/client/src/main/java/org/apache/qpid/client/QueueSenderAdapter.java
@@ -7,14 +7,15 @@ import javax.jms.Message;
import javax.jms.MessageProducer;
import javax.jms.Queue;
import javax.jms.QueueSender;
+import javax.jms.InvalidDestinationException;
public class QueueSenderAdapter implements QueueSender {
- private MessageProducer _delegate;
+ private BasicMessageProducer _delegate;
private Queue _queue;
private boolean closed = false;
- public QueueSenderAdapter(MessageProducer msgProducer, Queue queue){
+ public QueueSenderAdapter(BasicMessageProducer msgProducer, Queue queue){
_delegate = msgProducer;
_queue = queue;
}
@@ -122,12 +123,13 @@ public class QueueSenderAdapter implements QueueSender {
_delegate.setTimeToLive(timeToLive);
}
- private void checkPreConditions() throws IllegalStateException, IllegalStateException
+ private void checkPreConditions() throws JMSException
{
checkPreConditions(_queue);
}
- private void checkPreConditions(Queue queue) throws IllegalStateException, IllegalStateException {
+ private void checkPreConditions(Queue queue) throws JMSException
+ {
if (closed){
throw new javax.jms.IllegalStateException("Publisher is closed");
}
@@ -137,5 +139,28 @@ public class QueueSenderAdapter implements QueueSender {
if(session == null || session.isClosed()){
throw new javax.jms.IllegalStateException("Invalid Session");
}
- }
+
+ if(!(queue instanceof AMQDestination))
+ {
+ throw new InvalidDestinationException("Queue: " + queue + " is not a valid Qpid queue");
+ }
+ AMQDestination destination = (AMQDestination) queue;
+ if(!destination.isValidated() && checkQueueBeforePublish())
+ {
+
+ if (_delegate.isBound(destination))
+ {
+ destination.setValidated(true);
+ }
+ else
+ {
+ throw new InvalidDestinationException("Queue: " + queue + " is not a valid destination (no bindings on server");
+ }
+ }
+ }
+
+ private boolean checkQueueBeforePublish()
+ {
+ return "true".equalsIgnoreCase(System.getProperty("org.apache.qpid.client.verifyQueueBindingBeforePublish", "true"));
+ }
}
diff --git a/qpid/java/client/src/main/java/org/apache/qpid/client/TopicPublisherAdapter.java b/qpid/java/client/src/main/java/org/apache/qpid/client/TopicPublisherAdapter.java
index f67b984658..02a408465b 100644
--- a/qpid/java/client/src/main/java/org/apache/qpid/client/TopicPublisherAdapter.java
+++ b/qpid/java/client/src/main/java/org/apache/qpid/client/TopicPublisherAdapter.java
@@ -175,5 +175,10 @@ public class TopicPublisherAdapter implements TopicPublisher
{
throw new InvalidDestinationException("Destination " + topic + " is not a topic");
}
+ if(!(topic instanceof AMQDestination))
+ {
+ throw new InvalidDestinationException("Destination " + topic + " is not a Qpid topic");
+ }
+
}
}
diff --git a/qpid/java/client/src/main/java/org/apache/qpid/client/handler/ChannelCloseMethodHandler.java b/qpid/java/client/src/main/java/org/apache/qpid/client/handler/ChannelCloseMethodHandler.java
index e2b101ab79..f62baf2c3a 100644
--- a/qpid/java/client/src/main/java/org/apache/qpid/client/handler/ChannelCloseMethodHandler.java
+++ b/qpid/java/client/src/main/java/org/apache/qpid/client/handler/ChannelCloseMethodHandler.java
@@ -94,6 +94,8 @@ public class ChannelCloseMethodHandler implements StateAwareMethodListener
}
}
+ //fixme why is this only done when the close is expected...
+ // should the above forced closes not also cause a close?
protocolSession.channelClosed(evt.getChannelId(), errorCode, String.valueOf(reason));
}
}
diff --git a/qpid/java/client/src/main/java/org/apache/qpid/client/message/AbstractBytesMessage.java b/qpid/java/client/src/main/java/org/apache/qpid/client/message/AbstractBytesMessage.java
index 8938130417..af254fbbaf 100644
--- a/qpid/java/client/src/main/java/org/apache/qpid/client/message/AbstractBytesMessage.java
+++ b/qpid/java/client/src/main/java/org/apache/qpid/client/message/AbstractBytesMessage.java
@@ -27,6 +27,7 @@ import javax.jms.JMSException;
import javax.jms.MessageEOFException;
import org.apache.mina.common.ByteBuffer;
+
import org.apache.qpid.AMQException;
import org.apache.qpid.framing.AMQShortString;
import org.apache.qpid.framing.BasicContentHeaderProperties;
@@ -72,7 +73,7 @@ public abstract class AbstractBytesMessage extends AbstractJMSMessage
}
AbstractBytesMessage(long messageNbr, ContentHeaderBody contentHeader, AMQShortString exchange,
- AMQShortString routingKey, ByteBuffer data) throws AMQException
+ AMQShortString routingKey, ByteBuffer data) throws AMQException
{
// TODO: this casting is ugly. Need to review whole ContentHeaderBody idea
super(messageNbr, (BasicContentHeaderProperties) contentHeader.properties, exchange, routingKey, data);
@@ -93,7 +94,9 @@ public abstract class AbstractBytesMessage extends AbstractJMSMessage
}
catch (IOException e)
{
- throw new JMSException(e.toString());
+ JMSException jmse = new JMSException(e.toString());
+ jmse.setLinkedException(e);
+ throw jmse;
}
}
@@ -112,6 +115,7 @@ public abstract class AbstractBytesMessage extends AbstractJMSMessage
{
return null;
}
+
int pos = _data.position();
_data.rewind();
// one byte left is for the end of frame marker
@@ -119,12 +123,14 @@ public abstract class AbstractBytesMessage extends AbstractJMSMessage
{
// this is really redundant since pos must be zero
_data.position(pos);
+
return null;
}
else
{
String data = _data.getString(Charset.forName("UTF8").newDecoder());
_data.position(pos);
+
return data;
}
}
diff --git a/qpid/java/client/src/main/java/org/apache/qpid/client/message/AbstractJMSMessage.java b/qpid/java/client/src/main/java/org/apache/qpid/client/message/AbstractJMSMessage.java
index 66524edce3..f87b4027f6 100644
--- a/qpid/java/client/src/main/java/org/apache/qpid/client/message/AbstractJMSMessage.java
+++ b/qpid/java/client/src/main/java/org/apache/qpid/client/message/AbstractJMSMessage.java
@@ -23,6 +23,7 @@ package org.apache.qpid.client.message;
import java.util.Collections;
import java.util.Enumeration;
import java.util.Map;
+import java.util.UUID;
import javax.jms.Destination;
import javax.jms.JMSException;
@@ -32,12 +33,7 @@ import javax.jms.MessageNotWriteableException;
import org.apache.commons.collections.map.ReferenceMap;
import org.apache.mina.common.ByteBuffer;
import org.apache.qpid.AMQException;
-import org.apache.qpid.client.AMQDestination;
-import org.apache.qpid.client.AMQQueue;
-import org.apache.qpid.client.AMQTopic;
-import org.apache.qpid.client.AMQUndefinedDestination;
-import org.apache.qpid.client.BasicMessageConsumer;
-import org.apache.qpid.client.CustomJMSXProperty;
+import org.apache.qpid.client.*;
import org.apache.qpid.framing.AMQShortString;
import org.apache.qpid.framing.BasicContentHeaderProperties;
import org.apache.qpid.framing.FieldTable;
@@ -123,7 +119,7 @@ public abstract class AbstractJMSMessage extends AMQMessage implements org.apach
{
if (getContentHeaderProperties().getMessageIdAsString() == null)
{
- getContentHeaderProperties().setMessageId("ID:" + _deliveryTag);
+ getContentHeaderProperties().setMessageId("ID:" + UUID.randomUUID());
}
return getContentHeaderProperties().getMessageIdAsString();
@@ -183,7 +179,7 @@ public abstract class AbstractJMSMessage extends AMQMessage implements org.apach
}
catch (URLSyntaxException e)
{
- throw new JMSException("Illegal value in JMS_ReplyTo property: " + replyToEncoding);
+ throw new JMSAMQException("Illegal value in JMS_ReplyTo property: " + replyToEncoding, e);
}
_destinationCache.put(replyToEncoding, dest);
diff --git a/qpid/java/client/src/main/java/org/apache/qpid/client/message/JMSHeaderAdapter.java b/qpid/java/client/src/main/java/org/apache/qpid/client/message/JMSHeaderAdapter.java
index 6352f7029f..348a0bd152 100644
--- a/qpid/java/client/src/main/java/org/apache/qpid/client/message/JMSHeaderAdapter.java
+++ b/qpid/java/client/src/main/java/org/apache/qpid/client/message/JMSHeaderAdapter.java
@@ -384,7 +384,9 @@ public final class JMSHeaderAdapter
}
catch (AMQPInvalidClassException aice)
{
- throw new MessageFormatException("Only primatives are allowed object is:" + object.getClass());
+ MessageFormatException mfe = new MessageFormatException("Only primatives are allowed object is:" + object.getClass());
+ mfe.setLinkedException(aice);
+ throw mfe;
}
}
diff --git a/qpid/java/client/src/main/java/org/apache/qpid/client/message/JMSObjectMessage.java b/qpid/java/client/src/main/java/org/apache/qpid/client/message/JMSObjectMessage.java
index df1400b167..caf8741280 100644
--- a/qpid/java/client/src/main/java/org/apache/qpid/client/message/JMSObjectMessage.java
+++ b/qpid/java/client/src/main/java/org/apache/qpid/client/message/JMSObjectMessage.java
@@ -33,6 +33,7 @@ import javax.jms.MessageFormatException;
import javax.jms.ObjectMessage;
import org.apache.mina.common.ByteBuffer;
+
import org.apache.qpid.AMQException;
import org.apache.qpid.framing.AMQShortString;
import org.apache.qpid.framing.BasicContentHeaderProperties;
@@ -61,14 +62,15 @@ public class JMSObjectMessage extends AbstractJMSMessage implements ObjectMessag
_data = ByteBuffer.allocate(DEFAULT_BUFFER_SIZE);
_data.setAutoExpand(true);
}
+
getContentHeaderProperties().setContentType(MIME_TYPE_SHORT_STRING);
}
/**
* Creates read only message for delivery to consumers
*/
- JMSObjectMessage(long messageNbr, ContentHeaderBody contentHeader, AMQShortString exchange,
- AMQShortString routingKey, ByteBuffer data) throws AMQException
+ JMSObjectMessage(long messageNbr, ContentHeaderBody contentHeader, AMQShortString exchange, AMQShortString routingKey,
+ ByteBuffer data) throws AMQException
{
super(messageNbr, (BasicContentHeaderProperties) contentHeader.properties, exchange, routingKey, data);
}
@@ -79,6 +81,7 @@ public class JMSObjectMessage extends AbstractJMSMessage implements ObjectMessag
{
_data.release();
}
+
_data = null;
}
@@ -116,11 +119,13 @@ public class JMSObjectMessage extends AbstractJMSMessage implements ObjectMessag
}
catch (IOException e)
{
- throw new MessageFormatException("Message not serializable: " + e);
+ MessageFormatException mfe = new MessageFormatException("Message not serializable: " + e);
+ mfe.setLinkedException(e);
+ throw mfe;
}
}
-
+
public Serializable getObject() throws JMSException
{
ObjectInputStream in = null;
@@ -133,17 +138,20 @@ public class JMSObjectMessage extends AbstractJMSMessage implements ObjectMessag
{
_data.rewind();
in = new ObjectInputStream(_data.asInputStream());
+
return (Serializable) in.readObject();
}
catch (IOException e)
{
- e.printStackTrace();
- throw new MessageFormatException("Could not deserialize message: " + e);
+ MessageFormatException mfe = new MessageFormatException("Could not deserialize message: " + e);
+ mfe.setLinkedException(e);
+ throw mfe;
}
catch (ClassNotFoundException e)
{
- e.printStackTrace();
- throw new MessageFormatException("Could not deserialize message: " + e);
+ MessageFormatException mfe = new MessageFormatException("Could not deserialize message: " + e);
+ mfe.setLinkedException(e);
+ throw mfe;
}
finally
{
@@ -162,8 +170,7 @@ public class JMSObjectMessage extends AbstractJMSMessage implements ObjectMessag
}
}
catch (IOException ignore)
- {
- }
+ { }
}
private static String toString(ByteBuffer data)
@@ -172,6 +179,7 @@ public class JMSObjectMessage extends AbstractJMSMessage implements ObjectMessag
{
return null;
}
+
int pos = data.position();
try
{
diff --git a/qpid/java/client/src/main/java/org/apache/qpid/client/protocol/AMQProtocolHandler.java b/qpid/java/client/src/main/java/org/apache/qpid/client/protocol/AMQProtocolHandler.java
index d0cc52271a..5bc1555df7 100644
--- a/qpid/java/client/src/main/java/org/apache/qpid/client/protocol/AMQProtocolHandler.java
+++ b/qpid/java/client/src/main/java/org/apache/qpid/client/protocol/AMQProtocolHandler.java
@@ -34,6 +34,7 @@ import org.apache.qpid.AMQConnectionClosedException;
import org.apache.qpid.AMQDisconnectedException;
import org.apache.qpid.AMQException;
import org.apache.qpid.AMQTimeoutException;
+import org.apache.qpid.AMQChannelClosedException;
import org.apache.qpid.client.AMQConnection;
import org.apache.qpid.client.AMQSession;
import org.apache.qpid.client.SSLConfiguration;
@@ -248,6 +249,12 @@ public class AMQProtocolHandler extends IoHandlerAdapter
sessionClosed(session);
}
+
+ //FIXME Need to correctly handle other exceptions. Things like ...
+// if (cause instanceof AMQChannelClosedException)
+ // which will cause the JMSSession to end due to a channel close and so that Session needs
+ // to be removed from the map so we can correctly still call close without an exception when trying to close
+ // the server closed session. See also CloseChannelMethodHandler as the sessionClose is never called on exception
}
// we reach this point if failover was attempted and failed therefore we need to let the calling app
// know since we cannot recover the situation
@@ -510,11 +517,6 @@ public class AMQProtocolHandler extends IoHandlerAdapter
_protocolSession.closeSession(session);
}
- public void closeConnection() throws AMQException
- {
- closeConnection(-1);
- }
-
public void closeConnection(long timeout) throws AMQException
{
getStateManager().changeState(AMQState.CONNECTION_CLOSING);
diff --git a/qpid/java/client/src/main/java/org/apache/qpid/client/security/CallbackHandlerRegistry.properties b/qpid/java/client/src/main/java/org/apache/qpid/client/security/CallbackHandlerRegistry.properties
index 50e6f1efaa..89ee8337f8 100644
--- a/qpid/java/client/src/main/java/org/apache/qpid/client/security/CallbackHandlerRegistry.properties
+++ b/qpid/java/client/src/main/java/org/apache/qpid/client/security/CallbackHandlerRegistry.properties
@@ -16,5 +16,6 @@
# specific language governing permissions and limitations
# under the License.
#
+CallbackHandler.CRAM-MD5-HASHED=org.apache.qpid.client.security.UsernameHashedPasswordCallbackHandler
CallbackHandler.CRAM-MD5=org.apache.qpid.client.security.UsernamePasswordCallbackHandler
CallbackHandler.PLAIN=org.apache.qpid.client.security.UsernamePasswordCallbackHandler
diff --git a/qpid/java/client/src/main/java/org/apache/qpid/client/security/DynamicSaslRegistrar.java b/qpid/java/client/src/main/java/org/apache/qpid/client/security/DynamicSaslRegistrar.java
index f8ee22a5d9..04db8044de 100644
--- a/qpid/java/client/src/main/java/org/apache/qpid/client/security/DynamicSaslRegistrar.java
+++ b/qpid/java/client/src/main/java/org/apache/qpid/client/security/DynamicSaslRegistrar.java
@@ -20,10 +20,6 @@
*/
package org.apache.qpid.client.security;
-import java.io.BufferedInputStream;
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.security.Security;
@@ -34,6 +30,7 @@ import java.util.TreeMap;
import javax.security.sasl.SaslClientFactory;
+
import org.apache.log4j.Logger;
import org.apache.qpid.util.FileUtils;
@@ -50,14 +47,11 @@ import org.apache.qpid.util.FileUtils;
* mechanism=fully.qualified.class.name
* </pre>
*
- * <p/>Where mechanism is an IANA-registered mechanism name and the fully qualified class name refers to a
- * class that implements javax.security.sasl.SaslClientFactory and provides the specified mechanism.
+ * <p/>Where mechanism is an IANA-registered mechanism name and the fully qualified class name refers to a class that
+ * implements javax.security.sasl.SaslClientFactory and provides the specified mechanism.
*
- * <p><table id="crc"><caption>CRC Card</caption>
- * <tr><th> Responsibilities <th> Collaborations
- * <tr><td> Parse SASL mechanism properties.
- * <tr><td> Create and register security provider for SASL mechanisms.
- * </table>
+ * <p><table id="crc"><caption>CRC Card</caption> <tr><th> Responsibilities <th> Collaborations <tr><td> Parse SASL
+ * mechanism properties. <tr><td> Create and register security provider for SASL mechanisms. </table>
*/
public class DynamicSaslRegistrar
{
@@ -69,10 +63,7 @@ public class DynamicSaslRegistrar
/** The default name of the SASL properties file resource. */
public static final String DEFAULT_RESOURCE_NAME = "org/apache/qpid/client/security/DynamicSaslRegistrar.properties";
- /**
- * Reads the properties file, and creates a dynamic security provider to register the SASL implementations
- * with.
- */
+ /** Reads the properties file, and creates a dynamic security provider to register the SASL implementations with. */
public static void registerSaslProviders()
{
_logger.debug("public static void registerSaslProviders(): called");
@@ -80,8 +71,8 @@ public class DynamicSaslRegistrar
// Open the SASL properties file, using the default name is one is not specified.
String filename = System.getProperty(FILE_PROPERTY);
InputStream is =
- FileUtils.openFileOrDefaultResource(filename, DEFAULT_RESOURCE_NAME,
- DynamicSaslRegistrar.class.getClassLoader());
+ FileUtils.openFileOrDefaultResource(filename, DEFAULT_RESOURCE_NAME,
+ DynamicSaslRegistrar.class.getClassLoader());
try
{
@@ -94,7 +85,7 @@ public class DynamicSaslRegistrar
if (factories.size() > 0)
{
- Security.addProvider(new JCAProvider(factories));
+ Security.insertProviderAt(new JCAProvider(factories), 0);
_logger.debug("Dynamic SASL provider added as a security provider");
}
}
@@ -170,15 +161,15 @@ public class DynamicSaslRegistrar
* @return A map from SASL mechanism names to implementing client factory classes.
*
* @todo Why tree map here? Do really want mechanisms in alphabetical order? Seems more likely that the declared
- * order of the mechanisms is intended to be preserved, so that they are registered in the declared order
- * of preference. Consider LinkedHashMap instead.
+ * order of the mechanisms is intended to be preserved, so that they are registered in the declared order of
+ * preference. Consider LinkedHashMap instead.
*/
private static Map<String, Class<? extends SaslClientFactory>> parseProperties(Properties props)
{
Enumeration e = props.propertyNames();
TreeMap<String, Class<? extends SaslClientFactory>> factoriesToRegister =
- new TreeMap<String, Class<? extends SaslClientFactory>>();
+ new TreeMap<String, Class<? extends SaslClientFactory>>();
while (e.hasMoreElements())
{
diff --git a/qpid/java/client/src/main/java/org/apache/qpid/client/security/DynamicSaslRegistrar.properties b/qpid/java/client/src/main/java/org/apache/qpid/client/security/DynamicSaslRegistrar.properties
index c2a7d7928c..1bff43142b 100644
--- a/qpid/java/client/src/main/java/org/apache/qpid/client/security/DynamicSaslRegistrar.properties
+++ b/qpid/java/client/src/main/java/org/apache/qpid/client/security/DynamicSaslRegistrar.properties
@@ -17,3 +17,4 @@
# under the License.
#
AMQPLAIN=org.apache.qpid.client.security.amqplain.AmqPlainSaslClientFactory
+CRAM-MD5-HASHED=org.apache.qpid.client.security.crammd5hashed.CRAMMD5HashedSaslClientFactory
diff --git a/qpid/java/client/src/main/java/org/apache/qpid/client/security/JCAProvider.java b/qpid/java/client/src/main/java/org/apache/qpid/client/security/JCAProvider.java
index 2fa8dcddde..5bf120454e 100644
--- a/qpid/java/client/src/main/java/org/apache/qpid/client/security/JCAProvider.java
+++ b/qpid/java/client/src/main/java/org/apache/qpid/client/security/JCAProvider.java
@@ -52,7 +52,7 @@ public class JCAProvider extends Provider
super("AMQSASLProvider", 1.0, "A JCA provider that registers all "
+ "AMQ SASL providers that want to be registered");
register(providerMap);
- Security.addProvider(this);
+// Security.addProvider(this);
}
/**
diff --git a/qpid/java/client/src/main/java/org/apache/qpid/client/security/UsernameHashedPasswordCallbackHandler.java b/qpid/java/client/src/main/java/org/apache/qpid/client/security/UsernameHashedPasswordCallbackHandler.java
new file mode 100644
index 0000000000..46323e8c09
--- /dev/null
+++ b/qpid/java/client/src/main/java/org/apache/qpid/client/security/UsernameHashedPasswordCallbackHandler.java
@@ -0,0 +1,104 @@
+/*
+ *
+ * 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.client.security;
+
+import java.io.IOException;
+import java.io.UnsupportedEncodingException;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+
+import javax.security.auth.callback.Callback;
+import javax.security.auth.callback.NameCallback;
+import javax.security.auth.callback.PasswordCallback;
+import javax.security.auth.callback.UnsupportedCallbackException;
+import javax.security.sasl.RealmCallback;
+
+import com.sun.crypto.provider.HmacMD5;
+
+import org.apache.log4j.Logger;
+
+import org.apache.qpid.client.protocol.AMQProtocolSession;
+
+public class UsernameHashedPasswordCallbackHandler implements AMQCallbackHandler
+{
+ private static final Logger _logger = Logger.getLogger(UsernameHashedPasswordCallbackHandler.class);
+
+ private AMQProtocolSession _protocolSession;
+
+ public void initialise(AMQProtocolSession protocolSession)
+ {
+ _protocolSession = protocolSession;
+ }
+
+ public void handle(Callback[] callbacks) throws IOException, UnsupportedCallbackException
+ {
+ for (int i = 0; i < callbacks.length; i++)
+ {
+ Callback cb = callbacks[i];
+ if (cb instanceof NameCallback)
+ {
+ ((NameCallback) cb).setName(_protocolSession.getUsername());
+ }
+ else if (cb instanceof PasswordCallback)
+ {
+ try
+ {
+ ((PasswordCallback) cb).setPassword(getHash(_protocolSession.getPassword()));
+ }
+ catch (NoSuchAlgorithmException e)
+ {
+ UnsupportedCallbackException uce = new UnsupportedCallbackException(cb);
+ uce.initCause(e);
+ throw uce;
+ }
+ }
+ else
+ {
+ throw new UnsupportedCallbackException(cb);
+ }
+ }
+ }
+
+ private char[] getHash(String text) throws NoSuchAlgorithmException, UnsupportedEncodingException
+ {
+
+ byte[] data = text.getBytes("utf-8");
+
+ MessageDigest md = MessageDigest.getInstance("MD5");
+
+ for (byte b : data)
+ {
+ md.update(b);
+ }
+
+ byte[] digest = md.digest();
+
+ char[] hash = new char[digest.length ];
+
+ int index = 0;
+ for (byte b : digest)
+ {
+ hash[index++] = (char) b;
+ }
+
+ return hash;
+ }
+}
diff --git a/qpid/java/client/src/main/java/org/apache/qpid/client/security/crammd5hashed/CRAMMD5HashedSaslClientFactory.java b/qpid/java/client/src/main/java/org/apache/qpid/client/security/crammd5hashed/CRAMMD5HashedSaslClientFactory.java
new file mode 100644
index 0000000000..22bb1ac156
--- /dev/null
+++ b/qpid/java/client/src/main/java/org/apache/qpid/client/security/crammd5hashed/CRAMMD5HashedSaslClientFactory.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.client.security.crammd5hashed;
+
+import org.apache.qpid.client.security.amqplain.AmqPlainSaslClient;
+
+import javax.security.sasl.SaslClientFactory;
+import javax.security.sasl.SaslClient;
+import javax.security.sasl.SaslException;
+import javax.security.sasl.Sasl;
+import javax.security.auth.callback.CallbackHandler;
+import java.util.Map;
+import java.security.Security;
+
+public class CRAMMD5HashedSaslClientFactory implements SaslClientFactory
+{
+ /** The name of this mechanism */
+ public static final String MECHANISM = "CRAM-MD5-HASHED";
+
+
+ public SaslClient createSaslClient(String[] mechanisms, String authorizationId, String protocol, String serverName, Map<String, ?> props, CallbackHandler cbh) throws SaslException
+ {
+ for (int i = 0; i < mechanisms.length; i++)
+ {
+ if (mechanisms[i].equals(MECHANISM))
+ {
+ if (cbh == null)
+ {
+ throw new SaslException("CallbackHandler must not be null");
+ }
+
+ String[] mechs = {"CRAM-MD5"};
+ return Sasl.createSaslClient(mechs, authorizationId, protocol, serverName, props, cbh);
+ }
+ }
+ return null;
+ }
+
+ public String[] getMechanismNames(Map props)
+ {
+ if (props != null)
+ {
+ if (props.containsKey(Sasl.POLICY_NOPLAINTEXT) ||
+ props.containsKey(Sasl.POLICY_NODICTIONARY) ||
+ props.containsKey(Sasl.POLICY_NOACTIVE))
+ {
+ // returned array must be non null according to interface documentation
+ return new String[0];
+ }
+ }
+
+ return new String[]{MECHANISM};
+ }
+}
diff --git a/qpid/java/client/src/main/java/org/apache/qpid/client/transport/AMQNoTransportForProtocolException.java b/qpid/java/client/src/main/java/org/apache/qpid/client/transport/AMQNoTransportForProtocolException.java
index 104c5bfc44..1ec3adc2eb 100644
--- a/qpid/java/client/src/main/java/org/apache/qpid/client/transport/AMQNoTransportForProtocolException.java
+++ b/qpid/java/client/src/main/java/org/apache/qpid/client/transport/AMQNoTransportForProtocolException.java
@@ -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
@@ -33,7 +33,7 @@ public class AMQNoTransportForProtocolException extends AMQTransportConnectionEx
public AMQNoTransportForProtocolException(BrokerDetails details, String message)
{
- super(message);
+ super(null, message, null);
_details = details;
}
diff --git a/qpid/java/client/src/main/java/org/apache/qpid/client/transport/AMQTransportConnectionException.java b/qpid/java/client/src/main/java/org/apache/qpid/client/transport/AMQTransportConnectionException.java
index 4b17661bc3..fec7ff693c 100644
--- a/qpid/java/client/src/main/java/org/apache/qpid/client/transport/AMQTransportConnectionException.java
+++ b/qpid/java/client/src/main/java/org/apache/qpid/client/transport/AMQTransportConnectionException.java
@@ -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
@@ -21,12 +21,12 @@
package org.apache.qpid.client.transport;
import org.apache.qpid.AMQException;
+import org.apache.qpid.protocol.AMQConstant;
public class AMQTransportConnectionException extends AMQException
{
- public AMQTransportConnectionException(String message)
+ public AMQTransportConnectionException(AMQConstant errorCode, String message, Throwable cause)
{
- super(message);
-
+ super(errorCode, message, cause);
}
}
diff --git a/qpid/java/client/src/main/java/org/apache/qpid/client/transport/TransportConnection.java b/qpid/java/client/src/main/java/org/apache/qpid/client/transport/TransportConnection.java
index 8368eee125..0bc83e9804 100644
--- a/qpid/java/client/src/main/java/org/apache/qpid/client/transport/TransportConnection.java
+++ b/qpid/java/client/src/main/java/org/apache/qpid/client/transport/TransportConnection.java
@@ -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
@@ -26,12 +26,14 @@ import java.util.Iterator;
import java.util.Map;
import org.apache.log4j.Logger;
+
import org.apache.mina.common.IoConnector;
import org.apache.mina.common.IoHandlerAdapter;
import org.apache.mina.common.IoServiceConfig;
import org.apache.mina.transport.socket.nio.SocketConnector;
import org.apache.mina.transport.vmpipe.VmPipeAcceptor;
import org.apache.mina.transport.vmpipe.VmPipeAddress;
+
import org.apache.qpid.client.AMQBrokerDetails;
import org.apache.qpid.client.vmbroker.AMQVMBrokerCreationException;
import org.apache.qpid.jms.BrokerDetails;
@@ -64,13 +66,11 @@ public class TransportConnection
int transport = getTransport(details.getTransport());
if (transport == -1)
-
{
throw new AMQNoTransportForProtocolException(details);
}
if (transport == _currentInstance)
-
{
if (transport == VM)
{
@@ -88,40 +88,42 @@ public class TransportConnection
_currentInstance = transport;
switch (transport)
-
{
- case TCP:
- _instance = new SocketTransportConnection(new SocketTransportConnection.SocketConnectorFactory()
- {
- public IoConnector newSocketConnector()
+
+ case TCP:
+ _instance = new SocketTransportConnection(new SocketTransportConnection.SocketConnectorFactory()
{
- SocketConnector result;
- //FIXME - this needs to be sorted to use the new Mina MultiThread SA.
- if (Boolean.getBoolean("qpidnio"))
+ public IoConnector newSocketConnector()
{
- _logger.fatal("Using Qpid NIO - sysproperty 'qpidnio' is set.");
-// result = new org.apache.qpid.nio.SocketConnector(); // non-blocking connector
+ SocketConnector result;
+ // FIXME - this needs to be sorted to use the new Mina MultiThread SA.
+ if (Boolean.getBoolean("qpidnio"))
+ {
+ _logger.fatal("Using Qpid NIO - sysproperty 'qpidnio' is set.");
+ // result = new org.apache.qpid.nio.SocketConnector(); // non-blocking connector
+ }
+ // else
+
+ {
+ _logger.info("Using Mina NIO");
+ result = new SocketConnector(); // non-blocking connector
+ }
+
+ // Don't have the connector's worker thread wait around for other connections (we only use
+ // one SocketConnector per connection at the moment anyway). This allows short-running
+ // clients (like unit tests) to complete quickly.
+ result.setWorkerTimeout(0);
+
+ return result;
}
-// else
- {
- _logger.info("Using Mina NIO");
- result = new SocketConnector(); // non-blocking connector
- }
-
- // Don't have the connector's worker thread wait around for other connections (we only use
- // one SocketConnector per connection at the moment anyway). This allows short-running
- // clients (like unit tests) to complete quickly.
- result.setWorkerTimeout(0);
+ });
+ break;
- return result;
- }
- });
- break;
- case VM:
- {
- _instance = getVMTransport(details, Boolean.getBoolean("amqj.AutoCreateVMBroker"));
- break;
- }
+ case VM:
+ {
+ _instance = getVMTransport(details, Boolean.getBoolean("amqj.AutoCreateVMBroker"));
+ break;
+ }
}
return _instance;
@@ -142,7 +144,8 @@ public class TransportConnection
return -1;
}
- private static ITransportConnection getVMTransport(BrokerDetails details, boolean AutoCreate) throws AMQVMBrokerCreationException
+ private static ITransportConnection getVMTransport(BrokerDetails details, boolean AutoCreate)
+ throws AMQVMBrokerCreationException
{
int port = details.getPort();
@@ -154,14 +157,14 @@ public class TransportConnection
}
else
{
- throw new AMQVMBrokerCreationException(port, "VM Broker on port " + port + " does not exist. Auto create disabled.");
+ throw new AMQVMBrokerCreationException(null, port, "VM Broker on port " + port
+ + " does not exist. Auto create disabled.", null);
}
}
return new VmPipeTransportConnection(port);
}
-
public static void createVMBroker(int port) throws AMQVMBrokerCreationException
{
if (_acceptor == null)
@@ -192,7 +195,7 @@ public class TransportConnection
{
_logger.error(e);
- //Try and unbind provider
+ // Try and unbind provider
try
{
VmPipeAddress pipe = new VmPipeAddress(port);
@@ -203,7 +206,7 @@ public class TransportConnection
}
catch (Exception ignore)
{
- //ignore
+ // ignore
}
if (provider == null)
@@ -227,7 +230,7 @@ public class TransportConnection
because = e.getCause().toString();
}
- throw new AMQVMBrokerCreationException(port, because + " Stopped binding of InVM Qpid.AMQP");
+ throw new AMQVMBrokerCreationException(null, port, because + " Stopped binding of InVM Qpid.AMQP", e);
}
}
}
@@ -246,14 +249,14 @@ public class TransportConnection
// can't use introspection to get Provider as it is a server class.
// need to go straight to IoHandlerAdapter but that requries the queues and exchange from the ApplicationRegistry which we can't access.
- //get right constructor and pass in instancec ID - "port"
+ // get right constructor and pass in instancec ID - "port"
IoHandlerAdapter provider;
try
{
- Class[] cnstr = {Integer.class};
- Object[] params = {port};
+ Class[] cnstr = { Integer.class };
+ Object[] params = { port };
provider = (IoHandlerAdapter) Class.forName(protocolProviderClass).getConstructor(cnstr).newInstance(params);
- //Give the broker a second to create
+ // Give the broker a second to create
_logger.info("Created VMBroker Instance:" + port);
}
catch (Exception e)
@@ -270,8 +273,10 @@ public class TransportConnection
because = e.getCause().toString();
}
-
- throw new AMQVMBrokerCreationException(port, because + " Stopped InVM Qpid.AMQP creation");
+ AMQVMBrokerCreationException amqbce =
+ new AMQVMBrokerCreationException(null, port, because + " Stopped InVM Qpid.AMQP creation", null);
+ amqbce.initCause(e);
+ throw amqbce;
}
return provider;
diff --git a/qpid/java/client/src/main/java/org/apache/qpid/client/vmbroker/AMQVMBrokerCreationException.java b/qpid/java/client/src/main/java/org/apache/qpid/client/vmbroker/AMQVMBrokerCreationException.java
index 607ddcc26a..4b2982fe9c 100644
--- a/qpid/java/client/src/main/java/org/apache/qpid/client/vmbroker/AMQVMBrokerCreationException.java
+++ b/qpid/java/client/src/main/java/org/apache/qpid/client/vmbroker/AMQVMBrokerCreationException.java
@@ -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
@@ -21,19 +21,25 @@
package org.apache.qpid.client.vmbroker;
import org.apache.qpid.client.transport.AMQTransportConnectionException;
+import org.apache.qpid.protocol.AMQConstant;
public class AMQVMBrokerCreationException extends AMQTransportConnectionException
{
private int _port;
+ /**
+ * @param port
+ *
+ * @deprecated
+ */
public AMQVMBrokerCreationException(int port)
{
- this(port, "Unable to create vm broker");
+ this(null, port, "Unable to create vm broker", null);
}
- public AMQVMBrokerCreationException(int port, String message)
+ public AMQVMBrokerCreationException(AMQConstant errorCode, int port, String message, Throwable cause)
{
- super(message);
+ super(errorCode, message, cause);
_port = port;
}
diff --git a/qpid/java/client/src/main/java/org/apache/qpid/jms/FailoverPolicy.java b/qpid/java/client/src/main/java/org/apache/qpid/jms/FailoverPolicy.java
index 9adf04e182..6ad3fb4bae 100644
--- a/qpid/java/client/src/main/java/org/apache/qpid/jms/FailoverPolicy.java
+++ b/qpid/java/client/src/main/java/org/apache/qpid/jms/FailoverPolicy.java
@@ -101,7 +101,7 @@ public class FailoverPolicy
}
catch (Exception cnfe)
{
- throw new IllegalArgumentException("Unknown failover method:" + failoverMethod);
+ throw new IllegalArgumentException("Unknown failover method:" + failoverMethod, cnfe);
}
}
}
diff --git a/qpid/java/client/src/test/java/org/apache/qpid/client/MessageListenerMultiConsumerTest.java b/qpid/java/client/src/test/java/org/apache/qpid/client/MessageListenerMultiConsumerTest.java
index a406f9f86e..794fd5c8c1 100644
--- a/qpid/java/client/src/test/java/org/apache/qpid/client/MessageListenerMultiConsumerTest.java
+++ b/qpid/java/client/src/test/java/org/apache/qpid/client/MessageListenerMultiConsumerTest.java
@@ -65,6 +65,7 @@ public class MessageListenerMultiConsumerTest extends TestCase
private final CountDownLatch _allMessagesSent = new CountDownLatch(2); //all messages Sent Lock
+
protected void setUp() throws Exception
{
super.setUp();
@@ -122,30 +123,39 @@ public class MessageListenerMultiConsumerTest extends TestCase
TransportConnection.killAllVMBrokers();
}
+// public void testRecieveC1thenC2() throws Exception
+// {
+//
+// for (int msg = 0; msg < MSG_COUNT / 2; msg++)
+// {
+//
+// assertTrue(_consumer1.receive() != null);
+// }
+//
+// for (int msg = 0; msg < MSG_COUNT / 2; msg++)
+// {
+// assertTrue(_consumer2.receive() != null);
+// }
+// }
- public void testRecieveC1thenC2() throws Exception
+ public void testRecieveInterleaved() throws Exception
{
-
- for (int msg = 0; msg < MSG_COUNT / 2; msg++)
+ int msg = 0;
+ int MAX_LOOPS = MSG_COUNT * 2;
+ for (int loops = 0; msg < MSG_COUNT || loops < MAX_LOOPS; loops++)
{
- assertTrue(_consumer1.receive() != null);
- }
-
- for (int msg = 0; msg < MSG_COUNT / 2; msg++)
- {
- assertTrue(_consumer2.receive() != null);
+ if (_consumer1.receive(100) != null)
+ {
+ msg++;
+ }
+ if (_consumer2.receive(100) != null)
+ {
+ msg++;
+ }
}
- }
-
- public void testRecieveInterleaved() throws Exception
- {
- for (int msg = 0; msg < MSG_COUNT / 2; msg++)
- {
- assertTrue(_consumer1.receive() != null);
- assertTrue(_consumer2.receive() != null);
- }
+ assertEquals("Not all messages received.", MSG_COUNT, msg);
}
@@ -161,7 +171,7 @@ public class MessageListenerMultiConsumerTest extends TestCase
if (receivedCount1 == MSG_COUNT / 2)
{
- _allMessagesSent.countDown();
+ _allMessagesSent.countDown();
}
}
@@ -196,6 +206,18 @@ public class MessageListenerMultiConsumerTest extends TestCase
assertEquals(MSG_COUNT, receivedCount1 + receivedCount2);
}
+ public void testRecieveC2Only_OnlyRunWith_REGISTER_CONSUMERS_FLOWED() throws Exception
+ {
+ if (Boolean.parseBoolean(System.getProperties().getProperty("REGISTER_CONSUMERS_FLOWED", "false")))
+ {
+ for (int msg = 0; msg < MSG_COUNT; msg++)
+ {
+ assertTrue(MSG_COUNT + " msg should be received. Only received:" + msg,
+ _consumer2.receive(1000) != null);
+ }
+ }
+ }
+
public static junit.framework.Test suite()
{
diff --git a/qpid/java/client/src/test/java/org/apache/qpid/client/MessageListenerTest.java b/qpid/java/client/src/test/java/org/apache/qpid/client/MessageListenerTest.java
index 5fb77af4db..7b5957ac8c 100644
--- a/qpid/java/client/src/test/java/org/apache/qpid/client/MessageListenerTest.java
+++ b/qpid/java/client/src/test/java/org/apache/qpid/client/MessageListenerTest.java
@@ -144,6 +144,36 @@ public class MessageListenerTest extends TestCase implements MessageListener
}
+ public void testRecieveTheUseMessageListener() throws Exception
+ {
+
+ _logger.error("Test disabled as initial receive is not called first");
+ // Perform initial receive to start connection
+// assertTrue(_consumer.receive(2000) != null);
+// receivedCount++;
+
+ // Sleep to ensure remaining 4 msgs end up on _synchronousQueue
+// Thread.sleep(1000);
+
+ // Set the message listener and wait for the messages to come in.
+ _consumer.setMessageListener(this);
+
+ _logger.info("Waiting 3 seconds for messages");
+
+ try
+ {
+ _awaitMessages.await(3000, TimeUnit.MILLISECONDS);
+ }
+ catch (InterruptedException e)
+ {
+ //do nothing
+ }
+ //Should have recieved all async messages
+ assertEquals(MSG_COUNT, receivedCount);
+
+ }
+
+
public void onMessage(Message message)
{
_logger.info("Received Message(" + receivedCount + "):" + message);
diff --git a/qpid/java/client/src/test/java/org/apache/qpid/client/ResetMessageListenerTest.java b/qpid/java/client/src/test/java/org/apache/qpid/client/ResetMessageListenerTest.java
index 10bf1a8d6d..42594fff8e 100644
--- a/qpid/java/client/src/test/java/org/apache/qpid/client/ResetMessageListenerTest.java
+++ b/qpid/java/client/src/test/java/org/apache/qpid/client/ResetMessageListenerTest.java
@@ -83,7 +83,7 @@ public class ResetMessageListenerTest extends TestCase
Hashtable<String, String> env = new Hashtable<String, String>();
env.put("connectionfactory.connection", "amqp://guest:guest@MLT_ID/test?brokerlist='vm://:1'");
- env.put("queue.queue", "direct://amq.direct//MessageListenerTest");
+ env.put("queue.queue", "direct://amq.direct//ResetMessageListenerTest");
_context = factory.getInitialContext(env);
diff --git a/qpid/java/client/src/test/java/org/apache/qpid/test/unit/basic/InvalidDestinationTest.java b/qpid/java/client/src/test/java/org/apache/qpid/test/unit/basic/InvalidDestinationTest.java
new file mode 100644
index 0000000000..1b5da2631d
--- /dev/null
+++ b/qpid/java/client/src/test/java/org/apache/qpid/test/unit/basic/InvalidDestinationTest.java
@@ -0,0 +1,109 @@
+package org.apache.qpid.test.unit.basic;
+
+import org.apache.qpid.client.AMQConnection;
+import org.apache.qpid.client.AMQDestination;
+import org.apache.qpid.client.AMQSession;
+import org.apache.qpid.client.AMQQueue;
+import org.apache.qpid.client.vmbroker.AMQVMBrokerCreationException;
+import org.apache.qpid.client.transport.TransportConnection;
+
+import junit.framework.TestCase;
+
+import javax.jms.MessageConsumer;
+import javax.jms.Session;
+import javax.jms.QueueSession;
+import javax.jms.Queue;
+import javax.jms.QueueSender;
+import javax.jms.TextMessage;
+import javax.jms.InvalidDestinationException;
+
+public class InvalidDestinationTest extends TestCase
+{
+ private AMQConnection _connection;
+ private AMQDestination _destination;
+ private AMQSession _session;
+ private MessageConsumer _consumer;
+
+ private static final String VM_BROKER = "vm://:1";
+
+
+ protected void setUp() throws Exception
+ {
+ super.setUp();
+ createVMBroker();
+ _connection = new AMQConnection(VM_BROKER, "guest", "guest", "ReceiveTestClient", "test");
+ }
+
+ public void createVMBroker()
+ {
+ try
+ {
+ TransportConnection.createVMBroker(1);
+ }
+ catch (AMQVMBrokerCreationException e)
+ {
+ fail("Unable to create broker: " + e);
+ }
+ }
+
+ protected void tearDown() throws Exception
+ {
+ _connection.close();
+ TransportConnection.killVMBroker(1);
+ super.tearDown();
+ }
+
+
+
+ public void testInvalidDestination() throws Exception
+ {
+ Queue invalidDestination = new AMQQueue("amq.direct","unknownQ");
+ AMQQueue validDestination = new AMQQueue("amq.direct","knownQ");
+ QueueSession queueSession = _connection.createQueueSession(false, Session.AUTO_ACKNOWLEDGE);
+
+ // This is the only easy way to create and bind a queue from the API :-(
+ MessageConsumer consumer = queueSession.createConsumer(validDestination);
+
+ QueueSender sender = queueSession.createSender(invalidDestination);
+ TextMessage msg = queueSession.createTextMessage("Hello");
+ try
+ {
+ sender.send(msg);
+ fail("Expected InvalidDestinationException");
+ }
+ catch (InvalidDestinationException ex)
+ {
+ // pass
+ }
+ sender.close();
+
+ sender = queueSession.createSender(null);
+ invalidDestination = new AMQQueue("amq.direct","unknownQ");
+
+ try
+ {
+ sender.send(invalidDestination,msg);
+ fail("Expected InvalidDestinationException");
+ }
+ catch (InvalidDestinationException ex)
+ {
+ // pass
+ }
+ sender.send(validDestination,msg);
+ sender.close();
+ validDestination = new AMQQueue("amq.direct","knownQ");
+ sender = queueSession.createSender(validDestination);
+ sender.send(msg);
+
+
+
+
+ }
+
+
+ public static junit.framework.Test suite()
+ {
+
+ return new junit.framework.TestSuite(InvalidDestinationTest.class);
+ }
+}
diff --git a/qpid/java/client/src/test/java/org/apache/qpid/test/unit/close/MessageRequeueTest.java b/qpid/java/client/src/test/java/org/apache/qpid/test/unit/close/MessageRequeueTest.java
index 7762cb3fe9..62234ad21f 100644
--- a/qpid/java/client/src/test/java/org/apache/qpid/test/unit/close/MessageRequeueTest.java
+++ b/qpid/java/client/src/test/java/org/apache/qpid/test/unit/close/MessageRequeueTest.java
@@ -330,7 +330,7 @@ public class MessageRequeueTest extends TestCase
public void testRequeue() throws JMSException, AMQException, URLSyntaxException
{
int run = 0;
- while (run < 10)
+// while (run < 10)
{
run++;
@@ -350,17 +350,10 @@ public class MessageRequeueTest extends TestCase
_logger.debug("Create Consumer");
MessageConsumer consumer = session.createConsumer(q);
- try
- {
- Thread.sleep(2000);
- }
- catch (InterruptedException e)
- {
- //
- }
+ conn.start();
_logger.debug("Receiving msg");
- Message msg = consumer.receive(1000);
+ Message msg = consumer.receive(2000);
assertNotNull("Message should not be null", msg);
diff --git a/qpid/java/client/src/test/java/org/apache/qpid/test/unit/topic/DurableSubscriptionTest.java b/qpid/java/client/src/test/java/org/apache/qpid/test/unit/topic/DurableSubscriptionTest.java
index 0828ab398c..190b3861f0 100644
--- a/qpid/java/client/src/test/java/org/apache/qpid/test/unit/topic/DurableSubscriptionTest.java
+++ b/qpid/java/client/src/test/java/org/apache/qpid/test/unit/topic/DurableSubscriptionTest.java
@@ -100,7 +100,9 @@ public class DurableSubscriptionTest extends TestCase
AMQTopic topic = new AMQTopic(con,"MyTopic");
Session session1 = con.createSession(false, AMQSession.NO_ACKNOWLEDGE);
MessageConsumer consumer1 = session1.createConsumer(topic);
- MessageProducer producer = session1.createProducer(topic);
+
+ Session sessionProd = con.createSession(false, AMQSession.NO_ACKNOWLEDGE);
+ MessageProducer producer = sessionProd.createProducer(topic);
Session session2 = con.createSession(false, AMQSession.NO_ACKNOWLEDGE);
TopicSubscriber consumer2 = session2.createDurableSubscriber(topic, "MySubscription");
@@ -112,12 +114,12 @@ public class DurableSubscriptionTest extends TestCase
Message msg;
msg = consumer1.receive();
assertEquals("A", ((TextMessage) msg).getText());
- msg = consumer1.receive(1000);
+ msg = consumer1.receive(100);
assertEquals(null, msg);
msg = consumer2.receive();
assertEquals("A", ((TextMessage) msg).getText());
- msg = consumer2.receive(1000);
+ msg = consumer2.receive(100);
assertEquals(null, msg);
consumer2.close();
@@ -127,14 +129,14 @@ public class DurableSubscriptionTest extends TestCase
producer.send(session1.createTextMessage("B"));
- msg = consumer1.receive();
+ msg = consumer1.receive(100);
assertEquals("B", ((TextMessage) msg).getText());
- msg = consumer1.receive(1000);
+ msg = consumer1.receive(100);
assertEquals(null, msg);
- msg = consumer3.receive();
+ msg = consumer3.receive(100);
assertEquals("B", ((TextMessage) msg).getText());
- msg = consumer3.receive(1000);
+ msg = consumer3.receive(100);
assertEquals(null, msg);
con.close();
diff --git a/qpid/java/client/src/test/java/org/apache/qpid/test/unit/transacted/CommitRollbackTest.java b/qpid/java/client/src/test/java/org/apache/qpid/test/unit/transacted/CommitRollbackTest.java
index 2abc139ced..685fe20048 100644
--- a/qpid/java/client/src/test/java/org/apache/qpid/test/unit/transacted/CommitRollbackTest.java
+++ b/qpid/java/client/src/test/java/org/apache/qpid/test/unit/transacted/CommitRollbackTest.java
@@ -53,12 +53,15 @@ public class CommitRollbackTest extends TestCase
Queue _jmsQueue;
private static final Logger _logger = Logger.getLogger(CommitRollbackTest.class);
+ private static final String BROKER = "vm://:1";
protected void setUp() throws Exception
{
super.setUp();
- TransportConnection.createVMBroker(1);
-
+ if (BROKER.startsWith("vm"))
+ {
+ TransportConnection.createVMBroker(1);
+ }
testMethod++;
queue += testMethod;
@@ -68,7 +71,7 @@ public class CommitRollbackTest extends TestCase
private void newConnection() throws AMQException, URLSyntaxException, JMSException
{
- conn = new AMQConnection("amqp://guest:guest@client/test?brokerlist='vm://:1'");
+ conn = new AMQConnection("amqp://guest:guest@client/test?brokerlist='" + BROKER + "'");
_session = conn.createSession(true, Session.CLIENT_ACKNOWLEDGE);
@@ -87,7 +90,10 @@ public class CommitRollbackTest extends TestCase
super.tearDown();
conn.close();
- TransportConnection.killVMBroker(1);
+ if (BROKER.startsWith("vm"))
+ {
+ TransportConnection.killVMBroker(1);
+ }
}
/**
@@ -261,7 +267,7 @@ public class CommitRollbackTest extends TestCase
assertTrue("session is not transacted", _pubSession.getTransacted());
_logger.info("sending test message");
- String MESSAGE_TEXT = "testGetThenDisconnect";
+ String MESSAGE_TEXT = "testGetThenRollback";
_publisher.send(_pubSession.createTextMessage(MESSAGE_TEXT));
_pubSession.commit();
@@ -394,16 +400,60 @@ public class CommitRollbackTest extends TestCase
_logger.info("receiving result");
result = _consumer.receive(1000);
assertNotNull("test message was consumed and rolled back, but is gone", result);
- assertEquals("1", ((TextMessage) result).getText());
- assertTrue("Messasge is not marked as redelivered" + result, 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, result.getJMSRedelivered());
-
+ if (result.getJMSRedelivered())
+ {
+ assertEquals("1", ((TextMessage) result).getText());
+
+ 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, result.getJMSRedelivered());
+ }
+ else
+ {
+ assertEquals("2", ((TextMessage) result).getText());
+ assertTrue("Messasge is marked as redelivered" + result, !result.getJMSRedelivered());
+
+ result = _consumer.receive(1000);
+ assertNotNull("test message was consumed and rolled back, but is gone", result);
+ assertEquals("1", ((TextMessage) result).getText());
+ assertTrue("Messasge is not marked as redelivered" + result, result.getJMSRedelivered());
+
+ }
result = _consumer.receive(1000);
assertNull("test message should be null:" + result, result);
+
+ }
+
+
+ public void testPutThenRollbackThenGet() throws Exception
+ {
+ assertTrue("session is not transacted", _session.getTransacted());
+ assertTrue("session is not transacted", _pubSession.getTransacted());
+
+ _logger.info("sending test message");
+ String MESSAGE_TEXT = "testPutThenRollbackThenGet";
+
+ _publisher.send(_pubSession.createTextMessage(MESSAGE_TEXT));
+ _pubSession.commit();
+
+ assertNotNull(_consumer.receive(100));
+
+ _publisher.send(_pubSession.createTextMessage(MESSAGE_TEXT));
+
+ _logger.info("rolling back");
+ _pubSession.rollback();
+
+ _logger.info("receiving result");
+ Message result = _consumer.receive(1000);
+ assertNull("test message was put and rolled back, but is still present", result);
+
+ _publisher.send(_pubSession.createTextMessage(MESSAGE_TEXT));
+
+ _pubSession.commit();
+
+ assertNotNull(_consumer.receive(100));
+
}
}
diff --git a/qpid/java/client/src/test/java/org/apache/qpid/testutil/Config.java b/qpid/java/client/src/test/java/org/apache/qpid/testutil/Config.java
index 8109d20a33..b777cf93b6 100644
--- a/qpid/java/client/src/test/java/org/apache/qpid/testutil/Config.java
+++ b/qpid/java/client/src/test/java/org/apache/qpid/testutil/Config.java
@@ -172,7 +172,7 @@ public class Config
}
catch(NumberFormatException e)
{
- throw new RuntimeException("Bad port number: " + value);
+ throw new RuntimeException("Bad port number: " + value, e);
}
}
else if("-name".equalsIgnoreCase(key))
diff --git a/qpid/java/client/src/test/java/org/apache/qpid/testutil/QpidClientConnection.java b/qpid/java/client/src/test/java/org/apache/qpid/testutil/QpidClientConnection.java
index f2afa472ab..195ed79dab 100644
--- a/qpid/java/client/src/test/java/org/apache/qpid/testutil/QpidClientConnection.java
+++ b/qpid/java/client/src/test/java/org/apache/qpid/testutil/QpidClientConnection.java
@@ -3,6 +3,7 @@ package org.apache.qpid.testutil;
import org.apache.qpid.client.AMQConnectionFactory;
import org.apache.qpid.client.AMQConnectionURL;
import org.apache.qpid.client.AMQConnection;
+import org.apache.qpid.client.JMSAMQException;
import org.apache.qpid.url.URLSyntaxException;
import org.apache.log4j.Logger;
@@ -70,7 +71,7 @@ public class QpidClientConnection implements ExceptionListener
}
catch (URLSyntaxException e)
{
- throw new JMSException("URL syntax error in [" + brokerUrl + "]: " + e.getMessage());
+ throw new JMSAMQException("URL syntax error in [" + brokerUrl + "]: " + e.getMessage(), e);
}
}
}
diff --git a/qpid/java/common/bin/qpid-run b/qpid/java/common/bin/qpid-run
index 6d7837c120..fe8fd0e9cc 100644
--- a/qpid/java/common/bin/qpid-run
+++ b/qpid/java/common/bin/qpid-run
@@ -106,15 +106,20 @@ usage() {
export EXTERNAL_CLASSPATH=$CLASSPATH
unset CLASSPATH
-conf=$QPID_HOME/etc/$program.conf
-if [ ! -e $conf ]; then
- conf=$QPID_HOME/etc/$(basename ${sourced}).conf
+#Use QPID_CLASSPATH if set
+if [ -n "$QPID_CLASSPATH" ]; then
+ export CLASSPATH=$QPID_CLASSPATH
+ echo "Using QPID_CLASSPATH" $QPID_CLASSPATH
+else
+ echo "Warning: Qpid classpath not set. CLASSPATH must include qpid jars."
fi
-if [ -r $conf ]; then
- . $conf
+#Use QPID_JAVA_MEM if set
+if [ -n "$QPID_JAVA_MEM" ]; then
+ export JAVA_MEM=$QPID_JAVA_MEM
+ echo "Using QPID_JAVA_MEM setting" $QPID_JAVA_MEM
else
- die "unable to source $conf"
+ echo "Info: QPID_JAVA_MEM not set. Defaulting to JAVA_MEM" $JAVA_MEM
fi
declare -a RUN_ARGS JAVA_ARGS
diff --git a/qpid/java/common/src/main/java/org/apache/qpid/AMQException.java b/qpid/java/common/src/main/java/org/apache/qpid/AMQException.java
index 0222fd9b4e..3e93243a1d 100644
--- a/qpid/java/common/src/main/java/org/apache/qpid/AMQException.java
+++ b/qpid/java/common/src/main/java/org/apache/qpid/AMQException.java
@@ -23,11 +23,41 @@ package org.apache.qpid;
import org.apache.log4j.Logger;
import org.apache.qpid.protocol.AMQConstant;
-/** Generic AMQ exception. */
+/**
+ * AMQException forms the root exception of all exceptions relating to the AMQ protocol. It provides space to associate
+ * an AMQ error code with the exception, which is a numberic value, with a meaning defined by the protocol.
+ *
+ * <p/><table id="crc"><caption>CRC Card</caption>
+ * <tr><th> Responsibilities <th> Collaborations
+ * <tr><td> Represents an exception condition associated with an AMQ protocol error code.
+ * </table>
+ *
+ * @todo This exception class is also used as a generic exception throughout Qpid code. This usage may not be strictly
+ * correct if this is to signify a protocol exception. Should review.
+ */
public class AMQException extends Exception
{
+ /** Holds the AMQ error code constant associated with this exception. */
private AMQConstant _errorCode;
+ /**
+ * Creates an exception with an optional error code, optional message and optional underlying cause.
+ *
+ * @param errorCode The error code. May be null if not to be set.
+ * @param msg The exception message. May be null if not to be set.
+ * @param t The underlying cause of the exception. May be null if not to be set.
+ */
+ public AMQException(AMQConstant errorCode, String msg, Throwable t)
+ {
+ super(((msg == null) ? "" : msg) + ((errorCode == null) ? "" : (" [error code " + errorCode + "]")), t);
+ _errorCode = errorCode;
+ }
+
+ /**
+ * @param message
+ *
+ * @deprecated Use {@link #AMQException(org.apache.qpid.protocol.AMQConstant, String, Throwable)} instead.
+ */
public AMQException(String message)
{
super(message);
@@ -35,6 +65,12 @@ public class AMQException extends Exception
_errorCode = AMQConstant.getConstant(-1);
}
+ /**
+ * @param msg
+ * @param t
+ *
+ * @deprecated Use {@link #AMQException(org.apache.qpid.protocol.AMQConstant, String, Throwable)} instead.
+ */
public AMQException(String msg, Throwable t)
{
super(msg, t);
@@ -42,18 +78,19 @@ public class AMQException extends Exception
_errorCode = AMQConstant.getConstant(-1);
}
- public AMQException(AMQConstant errorCode, String msg, Throwable t)
- {
- super(msg + " [error code " + errorCode + ']', t);
- _errorCode = errorCode;
- }
-
+ /**
+ * @param errorCode
+ * @param msg
+ *
+ * @deprecated Use {@link #AMQException(org.apache.qpid.protocol.AMQConstant, String, Throwable)} instead.
+ */
public AMQException(AMQConstant errorCode, String msg)
{
super(msg + " [error code " + errorCode + ']');
_errorCode = errorCode;
}
+ /*
public AMQException(Logger logger, String msg, Throwable t)
{
this(msg, t);
@@ -71,10 +108,15 @@ public class AMQException extends Exception
this(errorCode, msg);
logger.error(getMessage(), this);
}
+ */
+ /**
+ * Gets the AMQ protocol exception code associated with this exception.
+ *
+ * @return The AMQ protocol exception code associated with this exception.
+ */
public AMQConstant getErrorCode()
{
return _errorCode;
}
-
}
diff --git a/qpid/java/common/src/main/java/org/apache/qpid/configuration/PropertyException.java b/qpid/java/common/src/main/java/org/apache/qpid/configuration/PropertyException.java
index 958f59191f..7c85a08e11 100644
--- a/qpid/java/common/src/main/java/org/apache/qpid/configuration/PropertyException.java
+++ b/qpid/java/common/src/main/java/org/apache/qpid/configuration/PropertyException.java
@@ -1,3 +1,4 @@
+/* Copyright Rupert Smith, 2005 to 2006, all rights reserved. */
/*
*
* Licensed to the Apache Software Foundation (ASF) under one
@@ -7,9 +8,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
@@ -21,6 +22,7 @@
package org.apache.qpid.configuration;
import org.apache.log4j.Logger;
+
import org.apache.qpid.AMQException;
import org.apache.qpid.protocol.AMQConstant;
@@ -49,7 +51,7 @@ public class PropertyException extends AMQException
super(errorCode, msg);
}
- public PropertyException(Logger logger, String msg, Throwable t)
+ /*public PropertyException(Logger logger, String msg, Throwable t)
{
super(logger, msg, t);
}
@@ -62,5 +64,5 @@ public class PropertyException extends AMQException
public PropertyException(Logger logger, AMQConstant errorCode, String msg)
{
super(logger, errorCode, msg);
- }
+ }*/
}
diff --git a/qpid/java/common/src/main/java/org/apache/qpid/framing/AMQDataBlockDecoder.java b/qpid/java/common/src/main/java/org/apache/qpid/framing/AMQDataBlockDecoder.java
index 43f888c029..9f36448986 100644
--- a/qpid/java/common/src/main/java/org/apache/qpid/framing/AMQDataBlockDecoder.java
+++ b/qpid/java/common/src/main/java/org/apache/qpid/framing/AMQDataBlockDecoder.java
@@ -94,7 +94,7 @@ public class AMQDataBlockDecoder
if(bodyFactory == null)
{
- throw new AMQFrameDecodingException("Unsupported frame type: " + type);
+ throw new AMQFrameDecodingException(null, "Unsupported frame type: " + type, null);
}
final int channel = in.getUnsignedShort();
@@ -103,8 +103,8 @@ public class AMQDataBlockDecoder
// bodySize can be zero
if (channel < 0 || bodySize < 0)
{
- throw new AMQFrameDecodingException("Undecodable frame: type = " + type + " channel = " + channel +
- " bodySize = " + bodySize);
+ throw new AMQFrameDecodingException(null, "Undecodable frame: type = " + type + " channel = " + channel +
+ " bodySize = " + bodySize, null);
}
AMQFrame frame = new AMQFrame(in, channel, bodySize, bodyFactory);
@@ -113,7 +113,7 @@ public class AMQDataBlockDecoder
byte marker = in.get();
if ((marker & 0xFF) != 0xCE)
{
- throw new AMQFrameDecodingException("End of frame marker not found. Read " + marker + " length=" + bodySize + " type=" + type);
+ throw new AMQFrameDecodingException(null, "End of frame marker not found. Read " + marker + " length=" + bodySize + " type=" + type, null);
}
return frame;
}
diff --git a/qpid/java/common/src/main/java/org/apache/qpid/framing/AMQFrameDecodingException.java b/qpid/java/common/src/main/java/org/apache/qpid/framing/AMQFrameDecodingException.java
index a24bd6aaa9..c462dec2a3 100644
--- a/qpid/java/common/src/main/java/org/apache/qpid/framing/AMQFrameDecodingException.java
+++ b/qpid/java/common/src/main/java/org/apache/qpid/framing/AMQFrameDecodingException.java
@@ -1,3 +1,4 @@
+/* Copyright Rupert Smith, 2005 to 2006, all rights reserved. */
/*
*
* Licensed to the Apache Software Foundation (ASF) under one
@@ -7,9 +8,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
@@ -21,21 +22,23 @@
package org.apache.qpid.framing;
import org.apache.log4j.Logger;
+
import org.apache.qpid.AMQException;
+import org.apache.qpid.protocol.AMQConstant;
public class AMQFrameDecodingException extends AMQException
{
- public AMQFrameDecodingException(String message)
+ /*public AMQFrameDecodingException(String message)
{
super(message);
- }
+ }*/
- public AMQFrameDecodingException(String message, Throwable t)
+ public AMQFrameDecodingException(AMQConstant errorCode, String message, Throwable t)
{
- super(message, t);
+ super(errorCode, message, t);
}
- public AMQFrameDecodingException(Logger log, String message)
+ /*public AMQFrameDecodingException(Logger log, String message)
{
super(log, message);
}
@@ -43,6 +46,5 @@ public class AMQFrameDecodingException extends AMQException
public AMQFrameDecodingException(Logger log, String message, Throwable t)
{
super(log, message, t);
- }
-
+ }*/
}
diff --git a/qpid/java/common/src/main/java/org/apache/qpid/framing/AMQShortString.java b/qpid/java/common/src/main/java/org/apache/qpid/framing/AMQShortString.java
index f51296dafc..f2492585bc 100644
--- a/qpid/java/common/src/main/java/org/apache/qpid/framing/AMQShortString.java
+++ b/qpid/java/common/src/main/java/org/apache/qpid/framing/AMQShortString.java
@@ -9,7 +9,7 @@ import org.apache.mina.common.ByteBuffer;
* and thus can be held more effectively in a byte buffer.
*
*/
-public final class AMQShortString implements CharSequence
+public final class AMQShortString implements CharSequence, Comparable<AMQShortString>
{
private static final Logger _logger = Logger.getLogger(AMQShortString.class);
diff --git a/qpid/java/common/src/main/java/org/apache/qpid/framing/BasicContentHeaderProperties.java b/qpid/java/common/src/main/java/org/apache/qpid/framing/BasicContentHeaderProperties.java
index 8b784fa3f7..008afb490e 100644
--- a/qpid/java/common/src/main/java/org/apache/qpid/framing/BasicContentHeaderProperties.java
+++ b/qpid/java/common/src/main/java/org/apache/qpid/framing/BasicContentHeaderProperties.java
@@ -341,7 +341,7 @@ public class BasicContentHeaderProperties implements CommonContentHeaderProperti
}
catch (AMQFrameDecodingException e)
{
- throw new RuntimeException("Error in content header data: " + e);
+ throw new RuntimeException("Error in content header data: " + e, e);
}
final int endPos = buffer.position();
@@ -381,7 +381,7 @@ public class BasicContentHeaderProperties implements CommonContentHeaderProperti
}
catch (AMQFrameDecodingException e)
{
- throw new RuntimeException("Error in content header data: " + e);
+ throw new RuntimeException("Error in content header data: " + e, e);
}
}
diff --git a/qpid/java/common/src/main/java/org/apache/qpid/framing/ContentHeaderPropertiesFactory.java b/qpid/java/common/src/main/java/org/apache/qpid/framing/ContentHeaderPropertiesFactory.java
index 7dac018872..712eb437db 100644
--- a/qpid/java/common/src/main/java/org/apache/qpid/framing/ContentHeaderPropertiesFactory.java
+++ b/qpid/java/common/src/main/java/org/apache/qpid/framing/ContentHeaderPropertiesFactory.java
@@ -49,7 +49,7 @@ public class ContentHeaderPropertiesFactory
}
else
{
- throw new AMQFrameDecodingException("Unsupport content header class id: " + classId);
+ throw new AMQFrameDecodingException(null, "Unsupport content header class id: " + classId, null);
}
properties.populatePropertiesFromBuffer(buffer, propertyFlags, size);
return properties;
diff --git a/qpid/java/common/src/main/java/org/apache/qpid/framing/EncodingUtils.java b/qpid/java/common/src/main/java/org/apache/qpid/framing/EncodingUtils.java
index f94cd4934c..f0cdda487c 100644
--- a/qpid/java/common/src/main/java/org/apache/qpid/framing/EncodingUtils.java
+++ b/qpid/java/common/src/main/java/org/apache/qpid/framing/EncodingUtils.java
@@ -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
@@ -23,6 +23,7 @@ package org.apache.qpid.framing;
import java.nio.charset.Charset;
import org.apache.log4j.Logger;
+
import org.apache.mina.common.ByteBuffer;
public class EncodingUtils
@@ -49,96 +50,95 @@ public class EncodingUtils
}
}
-
public static int encodedShortStringLength(short s)
{
- if( s == 0 )
+ if (s == 0)
{
return 1 + 1;
}
int len = 0;
- if(s < 0)
+ if (s < 0)
{
- len=1;
+ len = 1;
// sloppy - doesn't work of Integer.MIN_VALUE
- s=(short)-s;
+ s = (short) -s;
}
- if(s>9999)
+ if (s > 9999)
{
- return 1+5;
+ return 1 + 5;
}
- else if(s>999)
+ else if (s > 999)
{
- return 1+4;
+ return 1 + 4;
}
- else if(s>99)
+ else if (s > 99)
{
- return 1+3;
+ return 1 + 3;
}
- else if(s>9)
+ else if (s > 9)
{
- return 1+2;
+ return 1 + 2;
}
else
{
- return 1+1;
+ return 1 + 1;
}
}
-
public static int encodedShortStringLength(int i)
{
- if( i == 0 )
+ if (i == 0)
{
return 1 + 1;
}
int len = 0;
- if(i < 0)
+ if (i < 0)
{
- len=1;
+ len = 1;
// sloppy - doesn't work of Integer.MIN_VALUE
- i=-i;
+ i = -i;
}
// range is now 1 - 2147483647
- if(i < Short.MAX_VALUE)
+ if (i < Short.MAX_VALUE)
{
- return len + encodedShortStringLength((short)i);
+ return len + encodedShortStringLength((short) i);
}
else if (i > 999999)
{
- return len + 6 + encodedShortStringLength((short)(i/1000000));
+ return len + 6 + encodedShortStringLength((short) (i / 1000000));
}
else // if (i > 99999)
{
- return len + 5 + encodedShortStringLength((short)(i/100000));
+ return len + 5 + encodedShortStringLength((short) (i / 100000));
}
}
public static int encodedShortStringLength(long l)
{
- if(l == 0)
+ if (l == 0)
{
return 1 + 1;
}
int len = 0;
- if(l < 0)
+ if (l < 0)
{
- len=1;
+ len = 1;
// sloppy - doesn't work of Long.MIN_VALUE
- l=-l;
+ l = -l;
}
- if(l < Integer.MAX_VALUE)
+
+ if (l < Integer.MAX_VALUE)
{
return len + encodedShortStringLength((int) l);
}
- else if(l > 9999999999L)
+ else if (l > 9999999999L)
{
return len + 10 + encodedShortStringLength((int) (l / 10000000000L));
}
@@ -149,7 +149,6 @@ public class EncodingUtils
}
-
public static int encodedShortStringLength(AMQShortString s)
{
if (s == null)
@@ -162,7 +161,6 @@ public class EncodingUtils
}
}
-
public static int encodedLongStringLength(String s)
{
if (s == null)
@@ -219,7 +217,6 @@ public class EncodingUtils
return 0;
}
-
public static void writeShortStringBytes(ByteBuffer buffer, String s)
{
if (s != null)
@@ -230,6 +227,7 @@ public class EncodingUtils
{
encodedString[i] = (byte) cha[i];
}
+
writeBytes(buffer, encodedString);
}
else
@@ -239,7 +237,6 @@ public class EncodingUtils
}
}
-
public static void writeShortStringBytes(ByteBuffer buffer, AMQShortString s)
{
if (s != null)
@@ -256,7 +253,7 @@ public class EncodingUtils
public static void writeLongStringBytes(ByteBuffer buffer, String s)
{
- assert s == null || s.length() <= 0xFFFE;
+ assert (s == null) || (s.length() <= 0xFFFE);
if (s != null)
{
int len = s.length();
@@ -267,6 +264,7 @@ public class EncodingUtils
{
encodedString[i] = (byte) cha[i];
}
+
buffer.put(encodedString);
}
else
@@ -277,7 +275,7 @@ public class EncodingUtils
public static void writeLongStringBytes(ByteBuffer buffer, char[] s)
{
- assert s == null || s.length <= 0xFFFE;
+ assert (s == null) || (s.length <= 0xFFFE);
if (s != null)
{
int len = s.length;
@@ -287,6 +285,7 @@ public class EncodingUtils
{
encodedString[i] = (byte) s[i];
}
+
buffer.put(encodedString);
}
else
@@ -297,7 +296,7 @@ public class EncodingUtils
public static void writeLongStringBytes(ByteBuffer buffer, byte[] bytes)
{
- assert bytes == null || bytes.length <= 0xFFFE;
+ assert (bytes == null) || (bytes.length <= 0xFFFE);
if (bytes != null)
{
writeUnsignedInteger(buffer, bytes.length);
@@ -330,7 +329,6 @@ public class EncodingUtils
}
}
-
public static int unsignedIntegerLength()
{
return 4;
@@ -356,7 +354,6 @@ public class EncodingUtils
}
}
-
public static void writeFieldTableBytes(ByteBuffer buffer, FieldTable table)
{
if (table != null)
@@ -400,10 +397,9 @@ public class EncodingUtils
if (value1)
{
- packedValue = (byte) (packedValue | (byte)(1 << 1));
+ packedValue = (byte) (packedValue | (byte) (1 << 1));
}
-
buffer.put(packedValue);
}
@@ -413,213 +409,181 @@ public class EncodingUtils
if (value1)
{
- packedValue = (byte) (packedValue | (byte)(1 << 1));
+ packedValue = (byte) (packedValue | (byte) (1 << 1));
}
if (value2)
{
- packedValue = (byte) (packedValue | (byte)(1 << 2));
+ packedValue = (byte) (packedValue | (byte) (1 << 2));
}
-
buffer.put(packedValue);
}
-
-
- public static void writeBooleans(ByteBuffer buffer,
- boolean value0,
- boolean value1,
- boolean value2,
- boolean value3)
+ public static void writeBooleans(ByteBuffer buffer, boolean value0, boolean value1, boolean value2, boolean value3)
{
byte packedValue = value0 ? (byte) 1 : (byte) 0;
if (value1)
{
- packedValue = (byte) (packedValue | (byte)(1 << 1));
+ packedValue = (byte) (packedValue | (byte) (1 << 1));
}
if (value2)
{
- packedValue = (byte) (packedValue | (byte)(1 << 2));
+ packedValue = (byte) (packedValue | (byte) (1 << 2));
}
if (value3)
{
- packedValue = (byte) (packedValue | (byte)(1 << 3));
+ packedValue = (byte) (packedValue | (byte) (1 << 3));
}
buffer.put(packedValue);
}
- public static void writeBooleans(ByteBuffer buffer,
- boolean value0,
- boolean value1,
- boolean value2,
- boolean value3,
- boolean value4)
+ public static void writeBooleans(ByteBuffer buffer, boolean value0, boolean value1, boolean value2, boolean value3,
+ boolean value4)
{
byte packedValue = value0 ? (byte) 1 : (byte) 0;
if (value1)
{
- packedValue = (byte) (packedValue | (byte)(1 << 1));
+ packedValue = (byte) (packedValue | (byte) (1 << 1));
}
if (value2)
{
- packedValue = (byte) (packedValue | (byte)(1 << 2));
+ packedValue = (byte) (packedValue | (byte) (1 << 2));
}
if (value3)
{
- packedValue = (byte) (packedValue | (byte)(1 << 3));
+ packedValue = (byte) (packedValue | (byte) (1 << 3));
}
if (value4)
{
- packedValue = (byte) (packedValue | (byte)(1 << 4));
+ packedValue = (byte) (packedValue | (byte) (1 << 4));
}
buffer.put(packedValue);
}
- public static void writeBooleans(ByteBuffer buffer,
- boolean value0,
- boolean value1,
- boolean value2,
- boolean value3,
- boolean value4,
- boolean value5)
+ public static void writeBooleans(ByteBuffer buffer, boolean value0, boolean value1, boolean value2, boolean value3,
+ boolean value4, boolean value5)
{
byte packedValue = value0 ? (byte) 1 : (byte) 0;
if (value1)
{
- packedValue = (byte) (packedValue | (byte)(1 << 1));
+ packedValue = (byte) (packedValue | (byte) (1 << 1));
}
if (value2)
{
- packedValue = (byte) (packedValue | (byte)(1 << 2));
+ packedValue = (byte) (packedValue | (byte) (1 << 2));
}
if (value3)
{
- packedValue = (byte) (packedValue | (byte)(1 << 3));
+ packedValue = (byte) (packedValue | (byte) (1 << 3));
}
if (value4)
{
- packedValue = (byte) (packedValue | (byte)(1 << 4));
+ packedValue = (byte) (packedValue | (byte) (1 << 4));
}
if (value5)
{
- packedValue = (byte) (packedValue | (byte)(1 << 5));
+ packedValue = (byte) (packedValue | (byte) (1 << 5));
}
buffer.put(packedValue);
}
- public static void writeBooleans(ByteBuffer buffer,
- boolean value0,
- boolean value1,
- boolean value2,
- boolean value3,
- boolean value4,
- boolean value5,
- boolean value6)
+ public static void writeBooleans(ByteBuffer buffer, boolean value0, boolean value1, boolean value2, boolean value3,
+ boolean value4, boolean value5, boolean value6)
{
byte packedValue = value0 ? (byte) 1 : (byte) 0;
if (value1)
{
- packedValue = (byte) (packedValue | (byte)(1 << 1));
+ packedValue = (byte) (packedValue | (byte) (1 << 1));
}
if (value2)
{
- packedValue = (byte) (packedValue | (byte)(1 << 2));
+ packedValue = (byte) (packedValue | (byte) (1 << 2));
}
if (value3)
{
- packedValue = (byte) (packedValue | (byte)(1 << 3));
+ packedValue = (byte) (packedValue | (byte) (1 << 3));
}
if (value4)
{
- packedValue = (byte) (packedValue | (byte)(1 << 4));
+ packedValue = (byte) (packedValue | (byte) (1 << 4));
}
if (value5)
{
- packedValue = (byte) (packedValue | (byte)(1 << 5));
+ packedValue = (byte) (packedValue | (byte) (1 << 5));
}
if (value6)
{
- packedValue = (byte) (packedValue | (byte)(1 << 6));
+ packedValue = (byte) (packedValue | (byte) (1 << 6));
}
buffer.put(packedValue);
}
- public static void writeBooleans(ByteBuffer buffer,
- boolean value0,
- boolean value1,
- boolean value2,
- boolean value3,
- boolean value4,
- boolean value5,
- boolean value6,
- boolean value7)
+ public static void writeBooleans(ByteBuffer buffer, boolean value0, boolean value1, boolean value2, boolean value3,
+ boolean value4, boolean value5, boolean value6, boolean value7)
{
byte packedValue = value0 ? (byte) 1 : (byte) 0;
if (value1)
{
- packedValue = (byte) (packedValue | (byte)(1 << 1));
+ packedValue = (byte) (packedValue | (byte) (1 << 1));
}
if (value2)
{
- packedValue = (byte) (packedValue | (byte)(1 << 2));
+ packedValue = (byte) (packedValue | (byte) (1 << 2));
}
if (value3)
{
- packedValue = (byte) (packedValue | (byte)(1 << 3));
+ packedValue = (byte) (packedValue | (byte) (1 << 3));
}
if (value4)
{
- packedValue = (byte) (packedValue | (byte)(1 << 4));
+ packedValue = (byte) (packedValue | (byte) (1 << 4));
}
if (value5)
{
- packedValue = (byte) (packedValue | (byte)(1 << 5));
+ packedValue = (byte) (packedValue | (byte) (1 << 5));
}
if (value6)
{
- packedValue = (byte) (packedValue | (byte)(1 << 6));
+ packedValue = (byte) (packedValue | (byte) (1 << 6));
}
if (value7)
{
- packedValue = (byte) (packedValue | (byte)(1 << 7));
+ packedValue = (byte) (packedValue | (byte) (1 << 7));
}
buffer.put(packedValue);
}
-
-
-
/**
* This is used for writing longstrs.
*
@@ -647,26 +611,27 @@ public class EncodingUtils
public static boolean[] readBooleans(ByteBuffer buffer)
{
final byte packedValue = buffer.get();
- if(packedValue == 0)
+ if (packedValue == 0)
{
return ALL_FALSE_ARRAY;
}
+
final boolean[] result = new boolean[8];
result[0] = ((packedValue & 1) != 0);
result[1] = ((packedValue & (1 << 1)) != 0);
result[2] = ((packedValue & (1 << 2)) != 0);
result[3] = ((packedValue & (1 << 3)) != 0);
- if((packedValue & 0xF0) == 0)
+ if ((packedValue & 0xF0) == 0)
{
result[0] = ((packedValue & 1) != 0);
}
+
result[4] = ((packedValue & (1 << 4)) != 0);
result[5] = ((packedValue & (1 << 5)) != 0);
result[6] = ((packedValue & (1 << 6)) != 0);
result[7] = ((packedValue & (1 << 7)) != 0);
-
return result;
}
@@ -742,6 +707,7 @@ public class EncodingUtils
{
stringChars[i] = (char) stringBytes[i];
}
+
return new String(stringChars);
}
}
@@ -757,6 +723,7 @@ public class EncodingUtils
{
byte[] result = new byte[(int) length];
buffer.get(result);
+
return result;
}
}
@@ -764,15 +731,14 @@ public class EncodingUtils
public static long readTimestamp(ByteBuffer buffer)
{
// Discard msb from AMQ timestamp
- //buffer.getUnsignedInt();
+ // buffer.getUnsignedInt();
return buffer.getLong();
}
-
static byte[] hexToByteArray(String id)
{
// Should check param for null, long enough for this check, upper-case and trailing char
- String s = (id.charAt(1) == 'x') ? id.substring(2) : id; // strip 0x
+ String s = (id.charAt(1) == 'x') ? id.substring(2) : id; // strip 0x
int len = s.length();
int byte_len = len / 2;
@@ -786,7 +752,7 @@ public class EncodingUtils
byte b1 = Byte.parseByte(s.substring(ch, ch + 1), 16);
byte b2 = Byte.parseByte(s.substring(ch + 1, ch + 2), 16);
- b[i] = (byte) (b1 * 16 + b2);
+ b[i] = (byte) ((b1 * 16) + b2);
}
return (b);
@@ -795,7 +761,7 @@ public class EncodingUtils
public static char[] convertToHexCharArray(byte[] from)
{
int length = from.length;
- char[] result_buff = new char[length * 2 + 2];
+ char[] result_buff = new char[(length * 2) + 2];
result_buff[0] = '0';
result_buff[1] = 'x';
@@ -831,7 +797,7 @@ public class EncodingUtils
byte[] from = new byte[size];
// Is this not the same.
- //bb.get(from, 0, length);
+ // bb.get(from, 0, length);
for (int i = 0; i < size; i++)
{
from[i] = bb.get(i);
@@ -840,9 +806,9 @@ public class EncodingUtils
return (new String(convertToHexCharArray(from)));
}
- private static char hex_chars[] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'};
+ private static char[] hex_chars = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };
- //**** new methods
+ // **** new methods
// AMQP_BOOLEAN_PROPERTY_PREFIX
@@ -854,6 +820,7 @@ public class EncodingUtils
public static boolean readBoolean(ByteBuffer buffer)
{
byte packedValue = buffer.get();
+
return (packedValue == 1);
}
@@ -878,7 +845,6 @@ public class EncodingUtils
return 1;
}
-
// AMQP_SHORT_PROPERTY_PREFIX
public static void writeShort(ByteBuffer buffer, Short aShort)
{
@@ -943,7 +909,6 @@ public class EncodingUtils
return 4;
}
-
// Double_PROPERTY_PREFIX
public static void writeDouble(ByteBuffer buffer, Double aDouble)
{
@@ -960,7 +925,6 @@ public class EncodingUtils
return 8;
}
-
public static byte[] readBytes(ByteBuffer buffer)
{
short length = buffer.getUnsigned();
@@ -981,7 +945,7 @@ public class EncodingUtils
{
if (data != null)
{
- // TODO: check length fits in an unsigned byte
+ // TODO: check length fits in an unsigned byte
writeUnsignedByte(buffer, (short) data.length);
buffer.put(data);
}
@@ -992,7 +956,7 @@ public class EncodingUtils
}
}
- //CHAR_PROPERTY
+ // CHAR_PROPERTY
public static int encodedCharLength()
{
return encodedByteLength();
@@ -1000,31 +964,29 @@ public class EncodingUtils
public static char readChar(ByteBuffer buffer)
{
- //This is valid as we know that the Character is ASCII 0..127
+ // This is valid as we know that the Character is ASCII 0..127
return (char) buffer.get();
}
public static void writeChar(ByteBuffer buffer, char character)
{
- //This is valid as we know that the Character is ASCII 0..127
+ // This is valid as we know that the Character is ASCII 0..127
writeByte(buffer, (byte) character);
}
-
-
-
public static long readLongAsShortString(ByteBuffer buffer)
{
short length = buffer.getUnsigned();
short pos = 0;
- if(length == 0)
+ if (length == 0)
{
return 0L;
}
+
byte digit = buffer.get();
boolean isNegative;
long result = 0;
- if(digit == (byte)'-')
+ if (digit == (byte) '-')
{
isNegative = true;
pos++;
@@ -1034,15 +996,16 @@ public class EncodingUtils
{
isNegative = false;
}
- result = digit - (byte)'0';
+
+ result = digit - (byte) '0';
pos++;
- while(pos < length)
+ while (pos < length)
{
pos++;
digit = buffer.get();
result = (result << 3) + (result << 1);
- result += digit - (byte)'0';
+ result += digit - (byte) '0';
}
return result;
@@ -1051,33 +1014,13 @@ public class EncodingUtils
public static long readUnsignedInteger(ByteBuffer buffer)
{
long l = 0xFF & buffer.get();
- l <<=8;
+ l <<= 8;
l = l | (0xFF & buffer.get());
- l <<=8;
+ l <<= 8;
l = l | (0xFF & buffer.get());
- l <<=8;
+ l <<= 8;
l = l | (0xFF & buffer.get());
return l;
}
-
-
- public static void main(String[] args)
- {
- ByteBuffer buf = ByteBuffer.allocate(8);
- buf.setAutoExpand(true);
-
- long l = (long) Integer.MAX_VALUE;
- l += 1024L;
-
- writeUnsignedInteger(buf, l);
-
- buf.flip();
-
- long l2 = readUnsignedInteger(buf);
-
- System.out.println("before: " + l);
- System.out.println("after: " + l2);
- }
-
}
diff --git a/qpid/java/common/src/main/java/org/apache/qpid/framing/VersionSpecificRegistry.java b/qpid/java/common/src/main/java/org/apache/qpid/framing/VersionSpecificRegistry.java
index ec371453aa..faa7cc1e82 100644
--- a/qpid/java/common/src/main/java/org/apache/qpid/framing/VersionSpecificRegistry.java
+++ b/qpid/java/common/src/main/java/org/apache/qpid/framing/VersionSpecificRegistry.java
@@ -148,34 +148,30 @@ public class VersionSpecificRegistry
}
catch(NullPointerException e)
{
- throw new AMQFrameDecodingException(_log,
- "Class " + classID + " unknown in AMQP version " + _protocolMajorVersion + "-" + _protocolMinorVersion
- + " (while trying to decode class " + classID + " method " + methodID + ".");
+ throw new AMQFrameDecodingException(null, "Class " + classID + " unknown in AMQP version " + _protocolMajorVersion
+ + "-" + _protocolMinorVersion + " (while trying to decode class " + classID + " method " + methodID + ".", e);
}
catch(IndexOutOfBoundsException e)
{
if(classID >= _registry.length)
{
- throw new AMQFrameDecodingException(_log,
- "Class " + classID + " unknown in AMQP version " + _protocolMajorVersion + "-" + _protocolMinorVersion
- + " (while trying to decode class " + classID + " method " + methodID + ".");
-
+ throw new AMQFrameDecodingException(null, "Class " + classID + " unknown in AMQP version " + _protocolMajorVersion
+ + "-" + _protocolMinorVersion + " (while trying to decode class " + classID + " method " + methodID
+ + ".", e);
}
else
{
- throw new AMQFrameDecodingException(_log,
- "Method " + methodID + " unknown in AMQP version " + _protocolMajorVersion + "-" + _protocolMinorVersion
- + " (while trying to decode class " + classID + " method " + methodID + ".");
-
+ throw new AMQFrameDecodingException(null, "Method " + methodID + " unknown in AMQP version "
+ + _protocolMajorVersion + "-" + _protocolMinorVersion + " (while trying to decode class " + classID
+ + " method " + methodID + ".", e);
}
}
if (bodyFactory == null)
{
- throw new AMQFrameDecodingException(_log,
- "Method " + methodID + " unknown in AMQP version " + _protocolMajorVersion + "-" + _protocolMinorVersion
- + " (while trying to decode class " + classID + " method " + methodID + ".");
+ throw new AMQFrameDecodingException(null, "Method " + methodID + " unknown in AMQP version " + _protocolMajorVersion
+ + "-" + _protocolMinorVersion + " (while trying to decode class " + classID + " method " + methodID + ".", null);
}
diff --git a/qpid/java/common/src/main/java/org/apache/qpid/pool/Event.java b/qpid/java/common/src/main/java/org/apache/qpid/pool/Event.java
index 09890a103d..7300ec8c3f 100644
--- a/qpid/java/common/src/main/java/org/apache/qpid/pool/Event.java
+++ b/qpid/java/common/src/main/java/org/apache/qpid/pool/Event.java
@@ -85,4 +85,27 @@ abstract public class Event
}
+
+ public static final class CloseEvent extends Event
+ {
+ private final IoFilter.NextFilter _nextFilter;
+
+ public CloseEvent(final IoFilter.NextFilter nextFilter)
+ {
+ super();
+ _nextFilter = nextFilter;
+ }
+
+
+ public void process(IoSession session)
+ {
+ _nextFilter.sessionClosed(session);
+ }
+
+ public IoFilter.NextFilter getNextFilter()
+ {
+ return _nextFilter;
+ }
+ }
+
}
diff --git a/qpid/java/common/src/main/java/org/apache/qpid/pool/PoolingFilter.java b/qpid/java/common/src/main/java/org/apache/qpid/pool/PoolingFilter.java
index 8126ca4bc8..c9c96925cb 100644
--- a/qpid/java/common/src/main/java/org/apache/qpid/pool/PoolingFilter.java
+++ b/qpid/java/common/src/main/java/org/apache/qpid/pool/PoolingFilter.java
@@ -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
@@ -24,10 +24,13 @@ import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import org.apache.log4j.Logger;
+
import org.apache.mina.common.IdleStatus;
import org.apache.mina.common.IoFilterAdapter;
import org.apache.mina.common.IoSession;
+import org.apache.qpid.pool.Event.CloseEvent;
+
public class PoolingFilter extends IoFilterAdapter implements Job.JobCompletionHandler
{
private static final Logger _logger = Logger.getLogger(PoolingFilter.class);
@@ -47,12 +50,12 @@ public class PoolingFilter extends IoFilterAdapter implements Job.JobCompletionH
void fireAsynchEvent(IoSession session, Event event)
{
Job job = getJobForSession(session);
- // job.acquire(); //prevents this job being removed from _jobs
+ // job.acquire(); //prevents this job being removed from _jobs
job.add(event);
- //Additional checks on pool to check that it hasn't shutdown.
+ // Additional checks on pool to check that it hasn't shutdown.
// The alternative is to catch the RejectedExecutionException that will result from executing on a shutdown pool
- if (job.activate() && _poolReference.getPool() != null && !_poolReference.getPool().isShutdown())
+ if (job.activate() && (_poolReference.getPool() != null) && !_poolReference.getPool().isShutdown())
{
_poolReference.getPool().execute(job);
}
@@ -68,16 +71,6 @@ public class PoolingFilter extends IoFilterAdapter implements Job.JobCompletionH
private Job getJobForSession(IoSession session)
{
return (Job) session.getAttribute(_name);
-
-/* if(job == null)
- {
- System.err.println("Error in " + _name);
- Thread.dumpStack();
- }
-
-
- job = _jobs.get(session);
- return job == null ? createJobForSession(session) : job;*/
}
private Job createJobForSession(IoSession session)
@@ -87,35 +80,36 @@ public class PoolingFilter extends IoFilterAdapter implements Job.JobCompletionH
private Job addJobForSession(IoSession session, Job job)
{
- //atomic so ensures all threads agree on the same job
+ // atomic so ensures all threads agree on the same job
Job existing = _jobs.putIfAbsent(session, job);
- return existing == null ? job : existing;
+
+ return (existing == null) ? job : existing;
}
- //Job.JobCompletionHandler
+ // Job.JobCompletionHandler
public void completed(IoSession session, Job job)
{
-// if (job.isComplete())
-// {
-// job.release();
-// if (!job.isReferenced())
-// {
-// _jobs.remove(session);
-// }
-// }
-// else
- if(!job.isComplete())
+ // if (job.isComplete())
+ // {
+ // job.release();
+ // if (!job.isReferenced())
+ // {
+ // _jobs.remove(session);
+ // }
+ // }
+ // else
+ if (!job.isComplete())
{
// ritchiem : 2006-12-13 Do we need to perform the additional checks here?
- // Can the pool be shutdown at this point?
- if (job.activate() && _poolReference.getPool() != null && !_poolReference.getPool().isShutdown())
+ // Can the pool be shutdown at this point?
+ if (job.activate() && (_poolReference.getPool() != null) && !_poolReference.getPool().isShutdown())
{
_poolReference.getPool().execute(job);
}
}
}
- //IoFilter methods that are processed by threads on the pool
+ // IoFilter methods that are processed by threads on the pool
public void sessionOpened(final NextFilter nextFilter, final IoSession session) throws Exception
{
@@ -127,37 +121,33 @@ public class PoolingFilter extends IoFilterAdapter implements Job.JobCompletionH
nextFilter.sessionClosed(session);
}
- public void sessionIdle(final NextFilter nextFilter, final IoSession session,
- final IdleStatus status) throws Exception
+ public void sessionIdle(final NextFilter nextFilter, final IoSession session, final IdleStatus status) throws Exception
{
nextFilter.sessionIdle(session, status);
}
- public void exceptionCaught(final NextFilter nextFilter, final IoSession session,
- final Throwable cause) throws Exception
+ public void exceptionCaught(final NextFilter nextFilter, final IoSession session, final Throwable cause) throws Exception
{
- nextFilter.exceptionCaught(session,cause);
+ nextFilter.exceptionCaught(session, cause);
}
- public void messageReceived(final NextFilter nextFilter, final IoSession session,
- final Object message) throws Exception
+ public void messageReceived(final NextFilter nextFilter, final IoSession session, final Object message) throws Exception
{
- nextFilter.messageReceived(session,message);
+ nextFilter.messageReceived(session, message);
}
- public void messageSent(final NextFilter nextFilter, final IoSession session,
- final Object message) throws Exception
+ public void messageSent(final NextFilter nextFilter, final IoSession session, final Object message) throws Exception
{
nextFilter.messageSent(session, message);
}
- public void filterWrite(final NextFilter nextFilter, final IoSession session,
- final WriteRequest writeRequest) throws Exception
+ public void filterWrite(final NextFilter nextFilter, final IoSession session, final WriteRequest writeRequest)
+ throws Exception
{
nextFilter.filterWrite(session, writeRequest);
}
- //IoFilter methods that are processed on current thread (NOT on pooled thread)
+ // IoFilter methods that are processed on current thread (NOT on pooled thread)
public void filterClose(NextFilter nextFilter, IoSession session) throws Exception
{
@@ -199,13 +189,17 @@ public class PoolingFilter extends IoFilterAdapter implements Job.JobCompletionH
super(refCountingPool, name);
}
- public void messageReceived(final NextFilter nextFilter, final IoSession session,
- final Object message) throws Exception
+ public void messageReceived(final NextFilter nextFilter, final IoSession session, final Object message)
+ throws Exception
{
fireAsynchEvent(session, new Event.ReceivedEvent(nextFilter, message));
}
+ public void sessionClosed(final NextFilter nextFilter, final IoSession session) throws Exception
+ {
+ fireAsynchEvent(session, new CloseEvent(nextFilter));
+ }
}
@@ -217,26 +211,27 @@ public class PoolingFilter extends IoFilterAdapter implements Job.JobCompletionH
super(refCountingPool, name);
}
-
- public void filterWrite(final NextFilter nextFilter, final IoSession session,
- final WriteRequest writeRequest) throws Exception
+ public void filterWrite(final NextFilter nextFilter, final IoSession session, final WriteRequest writeRequest)
+ throws Exception
{
fireAsynchEvent(session, new Event.WriteEvent(nextFilter, writeRequest));
}
+ public void sessionClosed(final NextFilter nextFilter, final IoSession session) throws Exception
+ {
+ fireAsynchEvent(session, new CloseEvent(nextFilter));
+ }
+
}
- public static PoolingFilter createAynschReadPoolingFilter(ReferenceCountingExecutorService refCountingPool,String name)
+ public static PoolingFilter createAynschReadPoolingFilter(ReferenceCountingExecutorService refCountingPool, String name)
{
- return new AsynchReadPoolingFilter(refCountingPool,name);
+ return new AsynchReadPoolingFilter(refCountingPool, name);
}
-
- public static PoolingFilter createAynschWritePoolingFilter(ReferenceCountingExecutorService refCountingPool,String name)
+ public static PoolingFilter createAynschWritePoolingFilter(ReferenceCountingExecutorService refCountingPool, String name)
{
- return new AsynchWritePoolingFilter(refCountingPool,name);
+ return new AsynchWritePoolingFilter(refCountingPool, name);
}
}
-
-
diff --git a/qpid/java/common/src/main/java/org/apache/qpid/url/AMQBindingURL.java b/qpid/java/common/src/main/java/org/apache/qpid/url/AMQBindingURL.java
index f558523864..353c0d39c2 100644
--- a/qpid/java/common/src/main/java/org/apache/qpid/url/AMQBindingURL.java
+++ b/qpid/java/common/src/main/java/org/apache/qpid/url/AMQBindingURL.java
@@ -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
@@ -24,9 +24,10 @@ import java.net.URI;
import java.net.URISyntaxException;
import java.util.HashMap;
+import org.apache.log4j.Logger;
+
import org.apache.qpid.exchange.ExchangeDefaults;
import org.apache.qpid.framing.AMQShortString;
-import org.apache.log4j.Logger;
public class AMQBindingURL implements BindingURL
{
@@ -39,10 +40,9 @@ public class AMQBindingURL implements BindingURL
AMQShortString _queueName;
private HashMap<String, String> _options;
-
public AMQBindingURL(String url) throws URLSyntaxException
{
- //format:
+ // format:
// <exch_class>://<exch_name>/[<destination>]/[<queue>]?<option>='<value>'[,<option>='<value>']*
_logger.debug("Parsing URL: " + url);
_url = url;
@@ -61,10 +61,10 @@ public class AMQBindingURL implements BindingURL
if (exchangeClass == null)
{
- _url = ExchangeDefaults.DIRECT_EXCHANGE_CLASS + "://" +
- "" + "//" + _url;
- //URLHelper.parseError(-1, "Exchange Class not specified.", _url);
+ _url = ExchangeDefaults.DIRECT_EXCHANGE_CLASS + "://" + "" + "//" + _url;
+ // URLHelper.parseError(-1, "Exchange Class not specified.", _url);
parseBindingURL();
+
return;
}
else
@@ -76,7 +76,7 @@ public class AMQBindingURL implements BindingURL
if (exchangeName == null)
{
- if(getExchangeClass().equals(ExchangeDefaults.DIRECT_EXCHANGE_CLASS))
+ if (getExchangeClass().equals(ExchangeDefaults.DIRECT_EXCHANGE_CLASS))
{
setExchangeName("");
}
@@ -92,11 +92,10 @@ public class AMQBindingURL implements BindingURL
String queueName;
- if (connection.getPath() == null ||
- connection.getPath().equals(""))
+ if ((connection.getPath() == null) || connection.getPath().equals(""))
{
throw URLHelper.parseError(_url.indexOf(_exchangeName.toString()) + _exchangeName.length(),
- "Destination or Queue requried", _url);
+ "Destination or Queue requried", _url);
}
else
{
@@ -104,7 +103,7 @@ public class AMQBindingURL implements BindingURL
if (slash == -1)
{
throw URLHelper.parseError(_url.indexOf(_exchangeName.toString()) + _exchangeName.length(),
- "Destination requried", _url);
+ "Destination requried", _url);
}
else
{
@@ -127,9 +126,8 @@ public class AMQBindingURL implements BindingURL
setQueueName(queueName);
- //Fragment is #string (not used)
- //System.out.println(connection.getFragment());
- _logger.debug("URL Parsed: " + this);
+ // Fragment is #string (not used)
+ _logger.debug("URL Parsed: " + this);
}
catch (URISyntaxException uris)
@@ -162,7 +160,7 @@ public class AMQBindingURL implements BindingURL
private void processOptions()
{
- //this is where we would parse any options that needed more than just storage.
+ // this is where we would parse any options that needed more than just storage.
}
public String getURL()
@@ -219,11 +217,13 @@ public class AMQBindingURL implements BindingURL
{
if (containsOption(BindingURL.OPTION_CLIENTID) && containsOption(BindingURL.OPTION_SUBSCRIPTION))
{
- _queueName = new AMQShortString(getOption(BindingURL.OPTION_CLIENTID + ":" + BindingURL.OPTION_SUBSCRIPTION));
+ _queueName =
+ new AMQShortString(getOption(BindingURL.OPTION_CLIENTID + ":" + BindingURL.OPTION_SUBSCRIPTION));
}
else
{
- throw URLHelper.parseError(-1, "Durable subscription must have values for " + BindingURL.OPTION_CLIENTID + " and " + BindingURL.OPTION_SUBSCRIPTION + ".", _url);
+ throw URLHelper.parseError(-1, "Durable subscription must have values for " + BindingURL.OPTION_CLIENTID
+ + " and " + BindingURL.OPTION_SUBSCRIPTION + ".", _url);
}
}
@@ -237,7 +237,6 @@ public class AMQBindingURL implements BindingURL
_queueName = name;
}
-
}
public String getOption(String key)
@@ -275,7 +274,6 @@ public class AMQBindingURL implements BindingURL
setOption(OPTION_ROUTING_KEY, key.toString());
}
-
public String toString()
{
StringBuffer sb = new StringBuffer();
@@ -289,18 +287,7 @@ public class AMQBindingURL implements BindingURL
sb.append(_queueName);
sb.append(URLHelper.printOptions(_options));
- return sb.toString();
- }
-
- public static void main(String args[]) throws URLSyntaxException
- {
- String url = "exchangeClass://exchangeName/Destination/Queue?option='value',option2='value2'";
-
- AMQBindingURL dest = new AMQBindingURL(url);
-
- System.out.println(url);
- System.out.println(dest);
+ return sb.toString();
}
-
}
diff --git a/qpid/java/common/src/main/java/org/apache/qpid/url/URLHelper.java b/qpid/java/common/src/main/java/org/apache/qpid/url/URLHelper.java
index 806f879818..c08b443acf 100644
--- a/qpid/java/common/src/main/java/org/apache/qpid/url/URLHelper.java
+++ b/qpid/java/common/src/main/java/org/apache/qpid/url/URLHelper.java
@@ -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
@@ -30,10 +30,10 @@ public class URLHelper
public static void parseOptions(HashMap<String, String> optionMap, String options) throws URLSyntaxException
{
- //options looks like this
- //brokerlist='tcp://host:port?option='value',option='value';vm://:3/virtualpath?option='value'',failover='method?option='value',option='value''
+ // options looks like this
+ // brokerlist='tcp://host:port?option='value',option='value';vm://:3/virtualpath?option='value'',failover='method?option='value',option='value''
- if (options == null || options.indexOf('=') == -1)
+ if ((options == null) || (options.indexOf('=') == -1))
{
return;
}
@@ -49,8 +49,8 @@ public class URLHelper
// to store index of final "'"
int valueIndex = optionIndex;
- //Walk remainder of url.
- while (nestedQuotes > 0 || valueIndex < length)
+ // Walk remainder of url.
+ while ((nestedQuotes > 0) || (valueIndex < length))
{
valueIndex++;
@@ -61,27 +61,24 @@ public class URLHelper
if (options.charAt(valueIndex) == '\'')
{
- if (valueIndex + 1 < options.length())
+ if ((valueIndex + 1) < options.length())
{
- if (options.charAt(valueIndex + 1) == DEFAULT_OPTION_SEPERATOR ||
- options.charAt(valueIndex + 1) == ALTERNATIVE_OPTION_SEPARATOR ||
- options.charAt(valueIndex + 1) == BROKER_SEPARATOR ||
- options.charAt(valueIndex + 1) == '\'')
+ if ((options.charAt(valueIndex + 1) == DEFAULT_OPTION_SEPERATOR)
+ || (options.charAt(valueIndex + 1) == ALTERNATIVE_OPTION_SEPARATOR)
+ || (options.charAt(valueIndex + 1) == BROKER_SEPARATOR)
+ || (options.charAt(valueIndex + 1) == '\''))
{
nestedQuotes--;
-// System.out.println(
-// options + "\n" + "-" + nestedQuotes + ":" + getPositionString(valueIndex - 2, 1));
+
if (nestedQuotes == 0)
{
- //We've found the value of an option
+ // We've found the value of an option
break;
}
}
else
{
nestedQuotes++;
-// System.out.println(
-// options + "\n" + "+" + nestedQuotes + ":" + getPositionString(valueIndex - 2, 1));
}
}
else
@@ -98,11 +95,11 @@ public class URLHelper
}
}
- if (nestedQuotes != 0 || valueIndex < (optionIndex + 2))
+ if ((nestedQuotes != 0) || (valueIndex < (optionIndex + 2)))
{
int sepIndex = 0;
- //Try and identify illegal separator character
+ // Try and identify illegal separator character
if (nestedQuotes > 1)
{
for (int i = 0; i < nestedQuotes; i++)
@@ -112,14 +109,14 @@ public class URLHelper
}
}
- if (sepIndex >= options.length() || sepIndex == 0)
+ if ((sepIndex >= options.length()) || (sepIndex == 0))
{
throw parseError(valueIndex, "Unterminated option", options);
}
else
{
- throw parseError(sepIndex, "Unterminated option. Possible illegal option separator:'" +
- options.charAt(sepIndex) + "'", options);
+ throw parseError(sepIndex, "Unterminated option. Possible illegal option separator:'"
+ + options.charAt(sepIndex) + "'", options);
}
}
@@ -130,12 +127,11 @@ public class URLHelper
if (valueIndex < (options.length() - 1))
{
- //Recurse to get remaining options
+ // Recurse to get remaining options
parseOptions(optionMap, options.substring(valueIndex + 2));
}
}
-
public static URLSyntaxException parseError(int index, String error, String url)
{
return parseError(index, 1, error, url);
diff --git a/qpid/java/distribution/src/main/assembly/bin.xml b/qpid/java/distribution/src/main/assembly/bin.xml
index 0d4146ed1d..ef85137f90 100644
--- a/qpid/java/distribution/src/main/assembly/bin.xml
+++ b/qpid/java/distribution/src/main/assembly/bin.xml
@@ -83,6 +83,24 @@
<fileMode>420</fileMode>
</file>
<file>
+ <source>../broker/etc/jmxremote.access</source>
+ <outputDirectory>qpid-${qpid.version}/etc</outputDirectory>
+ <destName>jmxremote.access</destName>
+ <fileMode>420</fileMode>
+ </file>
+ <file>
+ <source>../broker/etc/transient_config.xml</source>
+ <outputDirectory>qpid-${qpid.version}/etc</outputDirectory>
+ <destName>transient_config.xml</destName>
+ <fileMode>420</fileMode>
+ </file>
+ <file>
+ <source>../broker/etc/persistent_config.xml</source>
+ <outputDirectory>qpid-${qpid.version}/etc</outputDirectory>
+ <destName>persistent_config.xml</destName>
+ <fileMode>420</fileMode>
+ </file>
+ <file>
<source>../broker/etc/log4j.xml</source>
<outputDirectory>qpid-${qpid.version}/etc</outputDirectory>
<destName>log4j.xml</destName>
@@ -113,6 +131,18 @@
<fileMode>420</fileMode>
</file>
<file>
+ <source>../broker/bin/qpid.stop</source>
+ <outputDirectory>qpid-${qpid.version}/bin</outputDirectory>
+ <destName>qpid.stop</destName>
+ <fileMode>493</fileMode>
+ </file>
+ <file>
+ <source>../broker/bin/qpid.stopall</source>
+ <outputDirectory>qpid-${qpid.version}/bin</outputDirectory>
+ <destName>qpid.stopall</destName>
+ <fileMode>493</fileMode>
+ </file>
+ <file>
<source>../common/bin/qpid-run</source>
<outputDirectory>qpid-${qpid.version}/bin</outputDirectory>
<destName>qpid-run</destName>
diff --git a/qpid/java/distribution/src/main/assembly/management-eclipse-plugin.xml b/qpid/java/distribution/src/main/assembly/management-eclipse-plugin.xml
index 5d89c55968..98534d43d0 100644
--- a/qpid/java/distribution/src/main/assembly/management-eclipse-plugin.xml
+++ b/qpid/java/distribution/src/main/assembly/management-eclipse-plugin.xml
@@ -88,6 +88,13 @@
</includes>
<fileMode>777</fileMode>
</fileSet>
+ <fileSet>
+ <directory>../management/eclipse-plugin/src/main/resources/sasl</directory>
+ <outputDirectory>qpidmc/eclipse/plugins/jmxremote.optional_1.0.1/META-INF</outputDirectory>
+ <includes>
+ <include>MANIFEST.MF</include>
+ </includes>
+ </fileSet>
</fileSets>
<dependencySets>
diff --git a/qpid/java/management/eclipse-plugin/META-INF/MANIFEST.MF b/qpid/java/management/eclipse-plugin/META-INF/MANIFEST.MF
index 5e5ba41be0..a92f375886 100644
--- a/qpid/java/management/eclipse-plugin/META-INF/MANIFEST.MF
+++ b/qpid/java/management/eclipse-plugin/META-INF/MANIFEST.MF
@@ -7,6 +7,7 @@ Bundle-Activator: org.apache.qpid.management.ui.Activator
Bundle-Localization: plugin
Require-Bundle: org.eclipse.ui,
org.eclipse.core.runtime,
- org.eclipse.ui.forms
+ org.eclipse.ui.forms,
+ jmxremote.optional
Eclipse-LazyStart: true
Bundle-Vendor: Apache Software Foundation
diff --git a/qpid/java/management/eclipse-plugin/bin/qpidmc.bat b/qpid/java/management/eclipse-plugin/bin/qpidmc.bat
index 6250b53e68..e444bc5811 100644
--- a/qpid/java/management/eclipse-plugin/bin/qpidmc.bat
+++ b/qpid/java/management/eclipse-plugin/bin/qpidmc.bat
@@ -52,4 +52,4 @@ goto exit
rem Slurp the command line arguments. This loop allows for an unlimited number
rem of agruments (up to the command line limit, anyway).
-"%JAVA_HOME%\bin\java" -Xms40m -Xmx256m -Declipse.consoleLog=true -jar %QPIDMC_HOME%\eclipse\startup.jar org.eclipse.core.launcher.Main -launcher %QPIDMC_HOME%\eclipse\eclipse -name "Qpid Management Console" -showsplash 600 -configuration "file:%QPIDMC_HOME%\configuration" -os win32 -ws win32 -arch x86
+"%JAVA_HOME%\bin\java" -Xms40m -Xmx256m -Declipse.consoleLog=false -Dsecurity=PLAIN -jar %QPIDMC_HOME%\eclipse\startup.jar org.eclipse.core.launcher.Main -launcher %QPIDMC_HOME%\eclipse\eclipse -name "Qpid Management Console" -showsplash 600 -configuration "file:%QPIDMC_HOME%\configuration" -os win32 -ws win32 -arch x86
diff --git a/qpid/java/management/eclipse-plugin/bin/qpidmc.sh b/qpid/java/management/eclipse-plugin/bin/qpidmc.sh
index 2472545a14..aae61b14c7 100755
--- a/qpid/java/management/eclipse-plugin/bin/qpidmc.sh
+++ b/qpid/java/management/eclipse-plugin/bin/qpidmc.sh
@@ -61,4 +61,4 @@ elif [ $os = "Linux" ]; then
os="linux"
fi
-"$JAVA_HOME/bin/java" -Xms40m -Xmx256m -Declipse.consoleLog=false -jar $QPIDMC_HOME/eclipse/startup.jar org.eclipse.core.launcher.Main -launcher $QPIDMC_HOME/eclipse/eclipse -name "Qpid Management Console" -showsplash 600 -configuration "file:$QPIDMC_HOME/configuration" -os $os -ws $ws -arch $arch
+"$JAVA_HOME/bin/java" -Xms40m -Xmx256m -Declipse.consoleLog=false -Dsecurity=PLAIN -jar $QPIDMC_HOME/eclipse/startup.jar org.eclipse.core.launcher.Main -launcher $QPIDMC_HOME/eclipse/eclipse -name "Qpid Management Console" -showsplash 600 -configuration "file:$QPIDMC_HOME/configuration" -os $os -ws $ws -arch $arch
diff --git a/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/ApplicationRegistry.java b/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/ApplicationRegistry.java
index 38a4d4561f..714f84ea49 100644
--- a/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/ApplicationRegistry.java
+++ b/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/ApplicationRegistry.java
@@ -41,7 +41,9 @@ public abstract class ApplicationRegistry
{
private static ImageRegistry imageRegistry = new ImageRegistry();
private static FontRegistry fontRegistry = new FontRegistry();
-
+ public static final boolean debug = Boolean.getBoolean("debug");
+ public static final String securityMechanism = System.getProperty("security", null);
+
static
{
imageRegistry.put(Constants.CONSOLE_IMAGE,
@@ -130,4 +132,9 @@ public abstract class ApplicationRegistry
_closedServerList.clear();
return list;
}
+
+ public static String getSecurityMechanism()
+ {
+ return securityMechanism;
+ }
}
diff --git a/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/ApplicationWorkbenchWindowAdvisor.java b/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/ApplicationWorkbenchWindowAdvisor.java
index 3d163fb111..e3aedef28e 100644
--- a/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/ApplicationWorkbenchWindowAdvisor.java
+++ b/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/ApplicationWorkbenchWindowAdvisor.java
@@ -49,7 +49,7 @@ public class ApplicationWorkbenchWindowAdvisor extends WorkbenchWindowAdvisor
IWorkbenchWindowConfigurer configurer = getWindowConfigurer();
int x = Display.getDefault().getBounds().width;
int y = Display.getDefault().getBounds().height;
- configurer.setInitialSize(new Point(4*x/5, 3*y/4));
+ configurer.setInitialSize(new Point(9*x/10, 8*y/10));
configurer.setShowCoolBar(true);
configurer.setShowStatusLine(false);
diff --git a/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/Constants.java b/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/Constants.java
index 91dec841cf..da70dc736c 100644
--- a/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/Constants.java
+++ b/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/Constants.java
@@ -1,3 +1,4 @@
+/* Copyright Rupert Smith, 2005 to 2006, all rights reserved. */
/*
*
* Licensed to the Apache Software Foundation (ASF) under one
@@ -7,9 +8,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
@@ -29,98 +30,110 @@ import static org.apache.qpid.management.ui.Constants.CONNECTION_PROTOCOLS;
*/
public class Constants
{
- public final static String APPLICATION_NAME = "Qpid Management Console";
-
- public final static String ACTION_REMOVE_MBEANNODE = "Remove from list";
- public final static String VALUE = "value";
- public final static String TYPE = "type";
- public final static String NODE_TYPE_SERVER = "server";
- public final static String NODE_TYPE_DOMAIN = "domain";
- public final static String NODE_TYPE_MBEANTYPE = "mbeantype";
+ public static final String APPLICATION_NAME = "Qpid Management Console";
+
+ public static final String ACTION_REMOVE_MBEANNODE = "Remove from list";
+ public static final String VALUE = "value";
+ public static final String TYPE = "type";
+ public static final String NODE_TYPE_SERVER = "server";
+ public static final String NODE_TYPE_DOMAIN = "domain";
+ public static final String NODE_TYPE_MBEANTYPE = "mbeantype";
// currently used only for virtual host instances, but will work as general also
- public final static String NODE_TYPE_TYPEINSTANCE = "mbeantype_instance";
- public final static String MBEAN = "mbean";
- public final static String ATTRIBUTE = "Attribute";
- public final static String ATTRIBUTES = "Attributes";
- public final static String NOTIFICATION = "Notifications";
- public final static String RESULT = "Result";
- public final static String VIRTUAL_HOST = "VirtualHost";
- public final static String DEFAULT_VH = "Default";
- public final static String DEFAULT_USERNAME = "guest";
- public final static String DEFAULT_PASSWORD = "guest";
-
- public final static String USERNAME = "Username";
- public final static String PASSWORD = "Password";
-
+ public static final String NODE_TYPE_TYPEINSTANCE = "mbeantype_instance";
+ public static final String MBEAN = "mbean";
+ public static final String ATTRIBUTE = "Attribute";
+ public static final String ATTRIBUTES = "Attributes";
+ public static final String NOTIFICATIONS = "Notifications";
+ public static final String RESULT = "Result";
+ public static final String VIRTUAL_HOST = "VirtualHost";
+ public static final String DEFAULT_VH = "Default";
+ public static final String DEFAULT_USERNAME = "guest";
+ public static final String DEFAULT_PASSWORD = "guest";
+
+ public static final String USERNAME = "Username";
+ public static final String PASSWORD = "Password";
+
// Attributes and operations are used to customize the GUI for Qpid. If these are changes in the
// Qpid server, then these should be updated accordingly
- public final static String ATTRIBUTE_QUEUE_OWNER = "owner";
- public final static String ATTRIBUTE_QUEUE_DEPTH = "QueueDepth";
- public final static String ATTRIBUTE_QUEUE_CONSUMERCOUNT = "ActiveConsumerCount";
- public final static String OPERATION_CREATE_QUEUE = "createNewQueue";
- public final static String OPERATION_CREATE_BINDING = "createNewBinding";
- public final static String OPERATION_MOVE_MESSAGES = "moveMessages";
-
- public final static String ALL = "All";
-
- public final static String NAVIGATION_ROOT = "Qpid Connections";
- public final static String DESCRIPTION = " Description";
-
- public final static String QUEUE = "Queue";
- public final static String CONNECTION ="Connection";
- public final static String EXCHANGE = "Exchange";
- public final static String EXCHANGE_TYPE = "ExchangeType";
- public final static String[] EXCHANGE_TYPE_VALUES = {"direct", "topic", "headers"};
- public final static String[] BOOLEAN_TYPE_VALUES = {"false", "true"};
- public final static String[] ATTRIBUTE_TABLE_TITLES = {"Attribute Name", "Value"};
- public static final String[] CONNECTION_PROTOCOLS ={"RMI"};
+ public static final String ATTRIBUTE_QUEUE_OWNER = "owner";
+ public static final String ATTRIBUTE_QUEUE_DEPTH = "QueueDepth";
+ public static final String ATTRIBUTE_QUEUE_CONSUMERCOUNT = "ActiveConsumerCount";
+ public static final String OPERATION_CREATE_QUEUE = "createNewQueue";
+ public static final String OPERATION_CREATE_BINDING = "createNewBinding";
+ public static final String OPERATION_MOVE_MESSAGES = "moveMessages";
+
+ public static final String OPERATION_CREATEUSER = "createUser";
+ public static final String OPERATION_VIEWUSERS = "viewUsers";
+ public static final String OPERATION_PARAM_USERNAME = "username";
+
+ public static final String OPERATION_SUCCESSFUL = "Operation successful";
+ public static final String OPERATION_UNSUCCESSFUL = "Operation unsuccessful";
+
+ public static final String ALL = "All";
+
+ public static final String NAVIGATION_ROOT = "Qpid Connections";
+ public static final String DESCRIPTION = " Description";
+
+ public static final String ADMIN_MBEAN_TYPE = "UserManagement";
+ public static final String QUEUE = "Queue";
+ public static final String CONNECTION = "Connection";
+ public static final String EXCHANGE = "Exchange";
+ public static final String EXCHANGE_TYPE = "ExchangeType";
+ public static final String[] EXCHANGE_TYPE_VALUES = { "direct", "fanout", "headers", "topic" };
+ public static final String[] BOOLEAN_TYPE_VALUES = { "false", "true" };
+ public static final String[] ATTRIBUTE_TABLE_TITLES = { "Attribute Name", "Value" };
+ public static final String[] CONNECTION_PROTOCOLS = { "RMI" };
public static final String DEFAULT_PROTOCOL = CONNECTION_PROTOCOLS[0];
-
- public final static String ACTION_ADDSERVER = "New Connection";
- public final static String ACTION_RECONNECT = "Reconnect";
- public final static String ACTION_LOGIN = "Login";
-
- public final static String QUEUE_SORT_BY_NAME = "Queue Name";
- public final static String QUEUE_SORT_BY_DEPTH = "Queue Depth";
- public final static String QUEUE_SORT_BY_CONSUMERCOUNT = "Consumer Count";
- public final static String QUEUE_SHOW_TEMP_QUEUES= "show temporary queues";
-
- public final static String SUBSCRIBE_BUTTON = "Subscribe";
- public final static String UNSUBSCRIBE_BUTTON = "Unsubscribe";
-
- public final static String CONSOLE_IMAGE = "ConsoelImage";
- public final static String CLOSED_FOLDER_IMAGE = "ClosedFolderImage";
- public final static String OPEN_FOLDER_IMAGE = "OpenFolderImage";
- public final static String MBEAN_IMAGE = "MBeanImage";
- public final static String NOTIFICATION_IMAGE = "NotificationImage";
-
- public final static String FONT_BUTTON = "ButtonFont";
- public final static String FONT_BOLD = "BoldFont";
- public final static String FONT_ITALIC = "ItalicFont";
- public final static String FONT_TABLE_CELL = "TableCellFont";
- public final static String FONT_NORMAL = "Normal";
-
- public final static String BUTTON_DETAILS = "Details";
- public final static String BUTTON_EDIT_ATTRIBUTE = "Edit Attribute";
- public final static String BUTTON_REFRESH = "Refresh";
- public final static String BUTTON_GRAPH = "Graph";
- public final static int TIMER_INTERVAL = 5000;
- public final static String BUTTON_EXECUTE = "Execute";
- public final static String BUTTON_CLEAR = "Clear";
- public final static String BUTTON_CONNECT = "Connect";
- public final static String BUTTON_CANCEL = "Cancel";
- public final static String BUTTON_UPDATE = "Update";
-
-
- public final static int OPERATION_IMPACT_INFO = 0;
- public final static int OPERATION_IMPACT_ACTION = 1;
- public final static int OPERATION_IMPACT_ACTIONINFO = 2;
- public final static int OPERATION_IMPACT_UNKNOWN = 3;
-
- public final static String ERROR_SERVER_CONNECTION = "Server could not be connected";
- public final static String INFO_PROTOCOL = "Please select the protocol";
- public final static String INFO_HOST_ADDRESS = "Please enter the host address";
- public final static String INFO_HOST_PORT = "Please enter the port number";
- public final static String INFO_USERNAME = "Please enter the " + USERNAME;
- public final static String INFO_PASSWORD = "Please enter the " + PASSWORD;
+
+ public static final String ACTION_ADDSERVER = "New Connection";
+ public static final String ACTION_RECONNECT = "Reconnect";
+ public static final String ACTION_LOGIN = "Login";
+
+ public static final String QUEUE_SORT_BY_NAME = "Queue Name";
+ public static final String QUEUE_SORT_BY_DEPTH = "Queue Depth";
+ public static final String QUEUE_SORT_BY_CONSUMERCOUNT = "Consumer Count";
+ public static final String QUEUE_SHOW_TEMP_QUEUES = "show temporary queues";
+
+ public static final String SUBSCRIBE_BUTTON = "Subscribe";
+ public static final String UNSUBSCRIBE_BUTTON = "Unsubscribe";
+
+ public static final String CONSOLE_IMAGE = "ConsoelImage";
+ public static final String CLOSED_FOLDER_IMAGE = "ClosedFolderImage";
+ public static final String OPEN_FOLDER_IMAGE = "OpenFolderImage";
+ public static final String MBEAN_IMAGE = "MBeanImage";
+ public static final String NOTIFICATION_IMAGE = "NotificationImage";
+
+ public static final String FONT_BUTTON = "ButtonFont";
+ public static final String FONT_BOLD = "BoldFont";
+ public static final String FONT_ITALIC = "ItalicFont";
+ public static final String FONT_TABLE_CELL = "TableCellFont";
+ public static final String FONT_NORMAL = "Normal";
+
+ public static final String BUTTON_DETAILS = "Details";
+ public static final String BUTTON_EDIT_ATTRIBUTE = "Edit Attribute";
+ public static final String BUTTON_REFRESH = "Refresh";
+ public static final String BUTTON_GRAPH = "Graph";
+ public static final int TIMER_INTERVAL = 5000;
+ public static final String BUTTON_EXECUTE = "Execute";
+ public static final String BUTTON_CLEAR = "Clear";
+ public static final String BUTTON_CONNECT = "Connect";
+ public static final String BUTTON_CANCEL = "Cancel";
+ public static final String BUTTON_UPDATE = "Update";
+
+ public static final int OPERATION_IMPACT_INFO = 0;
+ public static final int OPERATION_IMPACT_ACTION = 1;
+ public static final int OPERATION_IMPACT_ACTIONINFO = 2;
+ public static final int OPERATION_IMPACT_UNKNOWN = 3;
+
+ public static final String ERROR_SERVER_CONNECTION = "Server could not be connected";
+ public static final String INFO_PROTOCOL = "Please select the protocol";
+ public static final String INFO_HOST_ADDRESS = "Please enter the host address";
+ public static final String INFO_HOST_PORT = "Please enter the port number";
+ public static final String INFO_USERNAME = "Please enter the " + USERNAME;
+ public static final String INFO_PASSWORD = "Please enter the " + PASSWORD;
+
+ public static final String MECH_CRAMMD5 = "CRAM-MD5";
+ public static final String MECH_PLAIN = "PLAIN";
+ public static final String SASL_CRAMMD5 = "SASL/CRAM-MD5";
+ public static final String SASL_PLAIN = "SASL/PLAIN";
}
diff --git a/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/ManagedBean.java b/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/ManagedBean.java
index 38c3e8f413..31825e925d 100644
--- a/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/ManagedBean.java
+++ b/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/ManagedBean.java
@@ -20,6 +20,7 @@
*/
package org.apache.qpid.management.ui;
+import static org.apache.qpid.management.ui.Constants.*;
import java.util.HashMap;
/**
@@ -50,7 +51,7 @@ public abstract class ManagedBean extends ManagedObject
this._properties = properties;
setName(getProperty("name"));
setType(getProperty("type"));
- _virtualHostName = getProperty(Constants.VIRTUAL_HOST);
+ _virtualHostName = getProperty(VIRTUAL_HOST);
}
public String getDomain()
{
@@ -89,7 +90,7 @@ public abstract class ManagedBean extends ManagedObject
public String getVirtualHostName()
{
// To make it work with the broker with no virtual host implementation
- return _virtualHostName == null ? Constants.DEFAULT_VH : _virtualHostName;
+ return _virtualHostName == null ? DEFAULT_VH : _virtualHostName;
}
/**
@@ -106,21 +107,26 @@ public abstract class ManagedBean extends ManagedObject
public boolean isQueue()
{
- return _type.endsWith(Constants.QUEUE);
+ return _type.endsWith(QUEUE);
}
public boolean isConnection()
{
- return _type.endsWith(Constants.CONNECTION);
+ return _type.endsWith(CONNECTION);
}
public boolean isExchange()
{
- return _type.endsWith(Constants.EXCHANGE);
+ return _type.endsWith(EXCHANGE);
}
public boolean isTempQueue()
{
return (isQueue() && getName().startsWith("tmp_"));
}
+
+ public boolean isAdmin()
+ {
+ return _type.endsWith(ADMIN_MBEAN_TYPE);
+ }
}
diff --git a/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/Perspective.java b/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/Perspective.java
index da49d70b88..f93200cadf 100644
--- a/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/Perspective.java
+++ b/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/Perspective.java
@@ -37,8 +37,8 @@ public class Perspective implements IPerspectiveFactory
layout.setEditorAreaVisible(false);
// standalone view meaning it can't be docked or stacked with other views, and it doesn't have a title bar.
- layout.addStandaloneView(NavigationView.ID, true, IPageLayout.LEFT, 0.25f, editorArea);
- layout.addStandaloneView(MBeanView.ID, true, IPageLayout.RIGHT, 0.75f, editorArea);
+ layout.addStandaloneView(NavigationView.ID, true, IPageLayout.LEFT, 0.30f, editorArea);
+ layout.addStandaloneView(MBeanView.ID, true, IPageLayout.RIGHT, 0.70f, editorArea);
layout.getViewLayout(NavigationView.ID).setCloseable(false);
layout.getViewLayout(MBeanView.ID).setCloseable(false);
diff --git a/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/ServerRegistry.java b/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/ServerRegistry.java
index fa71ee9bc7..313e143df5 100644
--- a/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/ServerRegistry.java
+++ b/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/ServerRegistry.java
@@ -128,6 +128,10 @@ public abstract class ServerRegistry
return _virtualHosts;
}
+ public abstract void setUserList(List<String> list);
+
+ public abstract List<String> getUsernames();
+
public abstract void addManagedObject(ManagedBean key);
public abstract List<ManagedBean> getMBeans();
@@ -154,7 +158,7 @@ public abstract class ServerRegistry
public abstract boolean hasSubscribedForNotifications(ManagedBean mbean, String name, String type);
- public abstract void clearNotifications(ManagedBean mbean);
+ public abstract void clearNotifications(ManagedBean mbean, List<NotificationObject> list);
public ClientListener getNotificationListener()
{
diff --git a/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/actions/AddServer.java b/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/actions/AddServer.java
index 5a926e6474..0e12c59de4 100644
--- a/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/actions/AddServer.java
+++ b/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/actions/AddServer.java
@@ -194,9 +194,6 @@ public class AddServer/* extends Action*/ implements IWorkbenchWindowActionDeleg
}
}
- //If you create it, you dispose it.
- shell.dispose();
-
// enable the main shell
_window.getShell().setEnabled(true);
_window.getShell().open();
@@ -263,7 +260,7 @@ public class AddServer/* extends Action*/ implements IWorkbenchWindowActionDeleg
user.setLayoutData(new GridData(SWT.TRAIL, SWT.TOP, false, false));
final Text textUser = new Text(composite, SWT.BORDER);
- textUser.setText(DEFAULT_USERNAME);
+ textUser.setText("");
textUser.setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, false));
Label password = new Label(composite, SWT.NONE);
@@ -271,7 +268,7 @@ public class AddServer/* extends Action*/ implements IWorkbenchWindowActionDeleg
password.setLayoutData(new GridData(SWT.TRAIL, SWT.TOP, false, false));
final Text textPwd = new Text(composite, SWT.BORDER | SWT.SINGLE | SWT.PASSWORD);
- textPwd.setText(DEFAULT_PASSWORD);
+ textPwd.setText("");
//textPwd.setEchoChar('*');
textPwd.setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, false));
@@ -327,11 +324,7 @@ public class AddServer/* extends Action*/ implements IWorkbenchWindowActionDeleg
_domain = comboDomain.getText();
_addServer = true;
-
- if (!connectButton.getShell().isDisposed())
- {
- connectButton.getShell().dispose();
- }
+ shell.dispose();
}
});
diff --git a/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/actions/ReconnectServer.java b/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/actions/ReconnectServer.java
index 8fe08462cd..9aa265ab3c 100644
--- a/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/actions/ReconnectServer.java
+++ b/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/actions/ReconnectServer.java
@@ -168,9 +168,6 @@ public class ReconnectServer implements IWorkbenchWindowActionDelegate
}
}
- //If you create it, you dispose it.
- shell.dispose();
-
// enable the main shell
_window.getShell().setEnabled(true);
_window.getShell().open();
@@ -194,7 +191,7 @@ public class ReconnectServer implements IWorkbenchWindowActionDelegate
user.setLayoutData(new GridData(SWT.TRAIL, SWT.TOP, false, false));
final Text textUser = new Text(composite, SWT.BORDER);
- textUser.setText(DEFAULT_USERNAME);
+ textUser.setText("");
textUser.setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, false));
// Put cursor on this field
textUser.setFocus();
@@ -204,7 +201,7 @@ public class ReconnectServer implements IWorkbenchWindowActionDelegate
password.setLayoutData(new GridData(SWT.TRAIL, SWT.TOP, false, false));
final Text textPwd = new Text(composite, SWT.BORDER | SWT.SINGLE | SWT.PASSWORD);
- textPwd.setText(DEFAULT_PASSWORD);
+ textPwd.setText("");
textPwd.setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, false));
Composite buttonsComposite = new Composite(composite, SWT.NONE);
@@ -240,11 +237,7 @@ public class ReconnectServer implements IWorkbenchWindowActionDelegate
}
_connect = true;
-
- if (!connectButton.getShell().isDisposed())
- {
- connectButton.getShell().dispose();
- }
+ shell.dispose();
}
});
diff --git a/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/jmx/ClientListener.java b/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/jmx/ClientListener.java
index 82447d645e..2be0ddbebf 100644
--- a/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/jmx/ClientListener.java
+++ b/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/jmx/ClientListener.java
@@ -45,10 +45,7 @@ public class ClientListener implements NotificationListener
{
ObjectName objName = null;
String type = notification.getType();
- if (MBeanUtility.isDebug())
- {
- System.out.println(type + ":" + objName);
- }
+ MBeanUtility.printOutput(type + ":" + objName);
if (MBeanServerNotification.REGISTRATION_NOTIFICATION.equals(type))
{
diff --git a/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/jmx/JMXServerRegistry.java b/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/jmx/JMXServerRegistry.java
index b0f9928c38..816c479cf9 100644
--- a/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/jmx/JMXServerRegistry.java
+++ b/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/jmx/JMXServerRegistry.java
@@ -20,6 +20,10 @@
*/
package org.apache.qpid.management.ui.jmx;
+import static org.apache.qpid.management.ui.Constants.*;
+
+import java.lang.reflect.Constructor;
+import java.security.Security;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
@@ -35,8 +39,9 @@ import javax.management.ObjectName;
import javax.management.remote.JMXConnector;
import javax.management.remote.JMXConnectorFactory;
import javax.management.remote.JMXServiceURL;
+import javax.security.sasl.SaslClientFactory;
-import org.apache.qpid.management.ui.Constants;
+import org.apache.qpid.management.ui.ApplicationRegistry;
import org.apache.qpid.management.ui.ManagedBean;
import org.apache.qpid.management.ui.ManagedServer;
import org.apache.qpid.management.ui.ServerRegistry;
@@ -44,6 +49,10 @@ import org.apache.qpid.management.ui.model.ManagedAttributeModel;
import org.apache.qpid.management.ui.model.NotificationInfoModel;
import org.apache.qpid.management.ui.model.NotificationObject;
import org.apache.qpid.management.ui.model.OperationDataModel;
+import org.apache.qpid.management.ui.sasl.JCAProvider;
+import org.apache.qpid.management.ui.sasl.SaslProvider;
+import org.apache.qpid.management.ui.sasl.UserPasswordCallbackHandler;
+import org.apache.qpid.management.ui.sasl.UsernameHashedPasswordCallbackHandler;
public class JMXServerRegistry extends ServerRegistry
@@ -52,11 +61,12 @@ public class JMXServerRegistry extends ServerRegistry
private JMXConnector _jmxc = null;
private MBeanServerConnection _mbsc = null;
+ private List<String> _usersList;
// When an mbean gets removed from mbean server, then the notification listener
// will add that mbean in this list.
private List<ManagedBean> _mbeansToBeRemoved = new ArrayList<ManagedBean>();
- // Map containing all managed beans and ampped with unique mbean name
+ // Map containing all managed beans and mapped with unique mbean name
private HashMap<String, ManagedBean> _mbeansMap = new HashMap<String, ManagedBean>();
// Map containing MBeanInfo for all mbeans and mapped with unique mbean name
private HashMap<String, MBeanInfo> _mbeanInfoMap = new HashMap<String, MBeanInfo>();
@@ -83,11 +93,69 @@ public class JMXServerRegistry extends ServerRegistry
{
super(server);
JMXServiceURL jmxUrl = new JMXServiceURL(server.getUrl());
- Map<String, Object> env = new HashMap<String, Object>();
- String[] creds = {server.getUser(), server.getPassword()};
- env.put(JMXConnector.CREDENTIALS, creds);
-
- _jmxc = JMXConnectorFactory.connect(jmxUrl, env);
+ Map<String, Object> env = null;
+ String securityMechanism = ApplicationRegistry.getSecurityMechanism();
+
+ if (securityMechanism != null)
+ {
+ try
+ {
+ // Check if the JMXMP connector is available
+ Class klass = Class.forName("javax.management.remote.jmxmp.JMXMPConnector");
+
+ jmxUrl = new JMXServiceURL("jmxmp", server.getHost(), server.getPort());
+ env = new HashMap<String, Object>();
+
+ if (MECH_CRAMMD5.equals(securityMechanism))
+ {
+ // For SASL/CRAM-MD5
+ Map<String, Class<? extends SaslClientFactory>> map = new HashMap<String, Class<? extends SaslClientFactory>>();
+ Class<?> clazz = Class.forName("org.apache.qpid.management.ui.sasl.CRAMMD5HashedSaslClientFactory");
+ map.put("CRAM-MD5-HASHED", (Class<? extends SaslClientFactory>) clazz);
+
+ Security.addProvider(new JCAProvider(map));
+ env.put("jmx.remote.profiles", SASL_CRAMMD5);
+ env.put("jmx.remote.sasl.callback.handler",
+ new UsernameHashedPasswordCallbackHandler(server.getUser(), server.getPassword()));
+ }
+ else if (MECH_PLAIN.equals(securityMechanism))
+ {
+ // For SASL/PLAIN
+ Security.addProvider(new SaslProvider());
+ env.put("jmx.remote.profiles", SASL_PLAIN);
+ env.put("jmx.remote.sasl.callback.handler",
+ new UserPasswordCallbackHandler(server.getUser(), server.getPassword()));
+ }
+ else
+ {
+ MBeanUtility.printOutput("Security mechanism " + securityMechanism + " is not supported.");
+ }
+
+ // Now create the instance of JMXMPConnector
+ Class[] paramTypes = {JMXServiceURL.class, Map.class};
+ Constructor cons = klass.getConstructor(paramTypes);
+
+ Object[] args = {jmxUrl, env};
+ Object theObject = cons.newInstance(args);
+
+ _jmxc = (JMXConnector)theObject;
+ _jmxc.connect();
+ MBeanUtility.printOutput("Starting JMXConnector with SASL. Server=" + server.getName());
+ }
+ catch (Exception ex)
+ {
+ // When JMXMPConnector is not available
+ MBeanUtility.printOutput("Starting JMXConnector. Server=" + server.getName());
+ jmxUrl = new JMXServiceURL(server.getUrl());
+ _jmxc = JMXConnectorFactory.connect(jmxUrl, null);
+ }
+ }
+ else
+ {
+ jmxUrl = new JMXServiceURL(server.getUrl());
+ _jmxc = JMXConnectorFactory.connect(jmxUrl, null);
+ }
+
_mbsc = _jmxc.getMBeanServerConnection();
_clientListener = new ClientListener(server);
@@ -155,10 +223,7 @@ public class JMXServerRegistry extends ServerRegistry
public void removeManagedObject(ManagedBean mbean)
{
- if (MBeanUtility.isDebug())
- {
- System.out.println("Removing MBean:" + mbean.getUniqueName());
- }
+ MBeanUtility.printOutput("Removing MBean:" + mbean.getUniqueName());
if (mbean.isQueue())
{
@@ -218,17 +283,78 @@ public class JMXServerRegistry extends ServerRegistry
list.add(obj);
}
+ /**
+ * Returns all the notification objects for a given mbean. If mbean is null, it returns
+ * notification objects for all the mbeans.
+ */
public List<NotificationObject> getNotifications(ManagedBean mbean)
{
- return _notificationsMap.get(mbean.getUniqueName());
+ if (mbean == null)
+ {
+ List<NotificationObject> totalList = new ArrayList<NotificationObject>();
+ for (List<NotificationObject> list : _notificationsMap.values())
+ {
+ totalList.addAll(list);
+ }
+ return totalList;
+ }
+ else
+ {
+ return _notificationsMap.get(mbean.getUniqueName());
+ }
}
- public void clearNotifications(ManagedBean mbean)
+ public void clearNotifications(ManagedBean mbean, List<NotificationObject> list)
{
- if (_notificationsMap.containsKey(mbean.getUniqueName()))
- _notificationsMap.get(mbean.getUniqueName()).clear();
+ if (mbean == null)
+ {
+ if (list == null || list.isEmpty())
+ {
+ // All notifications of all mbeans to be cleared
+ _notificationsMap.clear();
+ }
+ else
+ {
+ // Clear the selected notifications
+ for (NotificationObject obj : list)
+ {
+ mbean = _mbeansMap.get(obj.getSource().toString());
+ List<NotificationObject> nList = _notificationsMap.get(mbean.getUniqueName());
+ if (nList != null && !nList.isEmpty())
+ {
+ nList.remove(obj);
+ }
+ }
+ }
+ }
+ else
+ {
+ if (list == null || list.isEmpty())
+ {
+ // All notifications of this mbean to be cleared
+ List<NotificationObject> nList = _notificationsMap.get(mbean.getUniqueName());
+ if (nList != null && !nList.isEmpty())
+ {
+ nList.clear();
+ }
+ }
+ else
+ {
+ // Clear the selected notifications
+ for (NotificationObject obj : list)
+ {
+ List<NotificationObject> nList = _notificationsMap.get(mbean.getUniqueName());
+ if (nList != null && !nList.isEmpty())
+ {
+ nList.remove(obj);
+ }
+ }
+ }
+ }
}
+
+
/**
* Adds notification name and type to the map. The map contains all the notification names,
* subscribed for an mbean.
@@ -254,7 +380,7 @@ public class JMXServerRegistry extends ServerRegistry
map.put(name, list);
}
// Now add the notification type to the list
- if (Constants.ALL.equals(type))
+ if (ALL.equals(type))
{
List<NotificationInfoModel> infoList = _notificationInfoMap.get(mbean.getUniqueName());
for (NotificationInfoModel model : infoList)
@@ -313,7 +439,7 @@ public class JMXServerRegistry extends ServerRegistry
HashMap<String, List<String>> map = _subscribedNotificationMap.get(mbean.getUniqueName());
if (map.containsKey(name))
{
- if (Constants.ALL.equals(type))
+ if (ALL.equals(type))
{
map.remove(name);
}
@@ -441,6 +567,16 @@ public class JMXServerRegistry extends ServerRegistry
}
return connections;
}
+
+ public void setUserList(List<String> list)
+ {
+ _usersList = list;
+ }
+
+ public List<String> getUsernames()
+ {
+ return _usersList;
+ }
public ClientNotificationListener getNotificationListener()
{
diff --git a/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/jmx/MBeanUtility.java b/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/jmx/MBeanUtility.java
index 5ceeb879b4..41db11c10e 100644
--- a/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/jmx/MBeanUtility.java
+++ b/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/jmx/MBeanUtility.java
@@ -60,13 +60,6 @@ import org.apache.qpid.management.ui.views.ViewUtility;
*/
public class MBeanUtility
{
- private static boolean _debug;
- static
- {
- String debug = System.getProperty("debug");
- _debug = "true".equalsIgnoreCase(debug) ? true : false;
- }
-
public static final BigInteger MAX_LONG = BigInteger.valueOf(Long.MAX_VALUE);
public static final BigInteger MAX_INT = BigInteger.valueOf(Integer.MAX_VALUE);
/**
@@ -149,27 +142,27 @@ public class MBeanUtility
* @param mbean managed bean
* @param ex Exception
*/
- public static void handleException(ManagedBean mbean, Exception ex)
+ public static void handleException(ManagedBean mbean, Throwable ex)
{
if (mbean == null)
{
ViewUtility.popupErrorMessage("Error", "Managed Object is null \n" + ex.toString());
- ex.printStackTrace();
+ printStackTrace(ex);
}
else if (ex instanceof IOException)
{
ViewUtility.popupErrorMessage(mbean.getInstanceName(), "IO Error occured \n" + ex.toString());
- ex.printStackTrace();
+ printStackTrace(ex);
}
else if (ex instanceof ReflectionException)
{
ViewUtility.popupErrorMessage(mbean.getInstanceName(), "Server has thrown error \n" + ex.toString());
- ex.printStackTrace();
+ printStackTrace(ex);
}
else if (ex instanceof InstanceNotFoundException)
{
ViewUtility.popupErrorMessage(mbean.getInstanceName(), "Managed Object Not Found \n" + ex.toString());
- ex.printStackTrace();
+ printStackTrace(ex);
}
else if (ex instanceof MBeanException)
{
@@ -188,8 +181,20 @@ public class MBeanUtility
}
else
{
- ViewUtility.popupErrorMessage(mbean.getInstanceName(), ex.getMessage());
- ex.printStackTrace();
+ if (ex.getCause() != null)
+ {
+ handleException(mbean, ex.getCause());
+ }
+ else
+ {
+ String msg = ex.getMessage();
+ if (msg == null)
+ {
+ msg = ex.toString();
+ }
+ ViewUtility.popupErrorMessage(mbean.getInstanceName(), msg);
+ printStackTrace(ex);
+ }
}
}
@@ -449,12 +454,19 @@ public class MBeanUtility
return Arrays.asList(domains);
}
- /**
- * return true if System property is set to true -Ddebug=true
- * @return
- */
- public static boolean isDebug()
+ public static void printOutput(String statement)
{
- return _debug;
+ if (ApplicationRegistry.debug)
+ {
+ System.out.println(statement);
+ }
+ }
+
+ private static void printStackTrace(Throwable ex)
+ {
+ if (ApplicationRegistry.debug)
+ {
+ ex.printStackTrace();
+ }
}
}
diff --git a/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/model/NotificationObject.java b/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/model/NotificationObject.java
index 8ba74b3ce8..926e5f0a24 100644
--- a/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/model/NotificationObject.java
+++ b/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/model/NotificationObject.java
@@ -24,10 +24,12 @@ import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.TimeZone;
+import javax.management.ObjectName;
+
public class NotificationObject
{
- private long _sequenceNo;
+ private long _sequenceNo;
private Date _timeStamp;
private String _message;
private Object _source;
@@ -52,6 +54,17 @@ public class NotificationObject
{
this._source = _source;
}
+
+ public String getSourceName()
+ {
+ if (_source instanceof ObjectName)
+ {
+ return ((ObjectName)_source).getKeyProperty("name");
+ }
+
+ return null;
+ }
+
public String getMessage()
{
return _message;
diff --git a/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/model/OperationData.java b/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/model/OperationData.java
index 9b6750c21a..2b83645942 100644
--- a/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/model/OperationData.java
+++ b/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/model/OperationData.java
@@ -80,5 +80,13 @@ public class OperationData
this._returnType = returnType;
}
+ public boolean isReturnTypeBoolean()
+ {
+ return (_returnType.equals("boolean") || _returnType.equals("java.lang.Boolean"));
+ }
+ public boolean isReturnTypeVoid()
+ {
+ return (_returnType.equals("void") || _returnType.equals("java.lang.Void"));
+ }
} \ No newline at end of file
diff --git a/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/sasl/CRAMMD5HashedSaslClientFactory.java b/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/sasl/CRAMMD5HashedSaslClientFactory.java
new file mode 100644
index 0000000000..32a0c12344
--- /dev/null
+++ b/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/sasl/CRAMMD5HashedSaslClientFactory.java
@@ -0,0 +1,60 @@
+/*
+ *
+ * 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.management.ui.sasl;
+
+import java.util.Map;
+
+import javax.security.auth.callback.CallbackHandler;
+import javax.security.sasl.Sasl;
+import javax.security.sasl.SaslClient;
+import javax.security.sasl.SaslClientFactory;
+import javax.security.sasl.SaslException;
+
+public class CRAMMD5HashedSaslClientFactory implements SaslClientFactory
+{
+ /** The name of this mechanism */
+ public static final String MECHANISM = "CRAM-MD5-HASHED";
+
+ public SaslClient createSaslClient(String[] mechanisms, String authorizationId, String protocol,
+ String serverName, Map<String, ?> props, CallbackHandler cbh)
+ throws SaslException
+ {
+ for (int i = 0; i < mechanisms.length; i++)
+ {
+ if (mechanisms[i].equals(MECHANISM))
+ {
+ if (cbh == null)
+ {
+ throw new SaslException("CallbackHandler must not be null");
+ }
+
+ String[] mechs = {"CRAM-MD5"};
+ return Sasl.createSaslClient(mechs, authorizationId, protocol, serverName, props, cbh);
+ }
+ }
+ return null;
+ }
+
+ public String[] getMechanismNames(Map props)
+ {
+ return new String[]{MECHANISM};
+ }
+}
diff --git a/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/sasl/ClientSaslFactory.java b/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/sasl/ClientSaslFactory.java
new file mode 100644
index 0000000000..ce9a273eaa
--- /dev/null
+++ b/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/sasl/ClientSaslFactory.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.management.ui.sasl;
+
+import java.util.Map;
+
+import javax.security.auth.callback.CallbackHandler;
+import javax.security.sasl.SaslClient;
+import javax.security.sasl.SaslClientFactory;
+import javax.security.sasl.SaslException;
+
+public class ClientSaslFactory implements SaslClientFactory
+{
+ public SaslClient createSaslClient(String[] mechs, String authorizationId, String protocol,
+ String serverName, Map props, CallbackHandler cbh)
+ throws SaslException
+ {
+ for (int i = 0; i < mechs.length; i++)
+ {
+ if (mechs[i].equals("PLAIN"))
+ {
+ return new PlainSaslClient(authorizationId, cbh);
+ }
+ }
+ return null;
+ }
+
+ /**
+ * Simple-minded implementation that ignores props
+ */
+ public String[] getMechanismNames(Map props)
+ {
+ return new String[]{"PLAIN"};
+ }
+
+}
diff --git a/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/sasl/JCAProvider.java b/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/sasl/JCAProvider.java
new file mode 100644
index 0000000000..d8189f3ac3
--- /dev/null
+++ b/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/sasl/JCAProvider.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.management.ui.sasl;
+
+import java.security.Provider;
+import java.util.Map;
+
+import javax.security.sasl.SaslClientFactory;
+
+public class JCAProvider extends Provider
+{
+ private static final long serialVersionUID = 1L;
+
+ /**
+ * Creates the security provider with a map from SASL mechanisms to implementing factories.
+ *
+ * @param providerMap The map from SASL mechanims to implementing factory classes.
+ */
+ public JCAProvider(Map<String, Class<? extends SaslClientFactory>> providerMap)
+ {
+ super("AMQSASLProvider", 1.0, "A JCA provider that registers all "
+ + "AMQ SASL providers that want to be registered");
+ register(providerMap);
+ }
+
+ /**
+ * Registers client factory classes for a map of mechanism names to client factory classes.
+ *
+ * @param providerMap The map from SASL mechanims to implementing factory classes.
+ */
+ private void register(Map<String, Class<? extends SaslClientFactory>> providerMap)
+ {
+ for (Map.Entry<String, Class<? extends SaslClientFactory>> me : providerMap.entrySet())
+ {
+ put("SaslClientFactory." + me.getKey(), me.getValue().getName());
+ }
+ }
+}
diff --git a/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/sasl/PlainSaslClient.java b/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/sasl/PlainSaslClient.java
new file mode 100644
index 0000000000..22190f29eb
--- /dev/null
+++ b/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/sasl/PlainSaslClient.java
@@ -0,0 +1,203 @@
+/*
+ *
+ * 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.management.ui.sasl;
+
+import java.io.*;
+import javax.security.auth.callback.*;
+import javax.security.sasl.*;
+
+public class PlainSaslClient implements SaslClient
+{
+
+ private boolean completed;
+ private CallbackHandler cbh;
+ private String authorizationID;
+ private String authenticationID;
+ private byte password[];
+ private static byte SEPARATOR = 0;
+
+ public PlainSaslClient(String authorizationID, CallbackHandler cbh) throws SaslException
+ {
+ completed = false;
+ this.cbh = cbh;
+ Object[] userInfo = getUserInfo();
+ this.authorizationID = authorizationID;
+ this.authenticationID = (String) userInfo[0];
+ this.password = (byte[]) userInfo[1];
+ if (authenticationID == null || password == null)
+ {
+ throw new SaslException("PLAIN: authenticationID and password must be specified");
+ }
+ }
+
+ public byte[] evaluateChallenge(byte[] challenge) throws SaslException
+ {
+ if (completed)
+ {
+ throw new IllegalStateException("PLAIN: authentication already " +
+ "completed");
+ }
+ completed = true;
+ try
+ {
+ byte authzid[] =
+ authorizationID == null ? null : authorizationID.getBytes("UTF8");
+ byte authnid[] = authenticationID.getBytes("UTF8");
+ byte response[] =
+ new byte[
+ password.length +
+ authnid.length +
+ 2 + // SEPARATOR
+ (authzid != null ? authzid.length : 0)
+ ];
+ int size = 0;
+ if (authzid != null) {
+ System.arraycopy(authzid, 0, response, 0, authzid.length);
+ size = authzid.length;
+ }
+ response[size++] = SEPARATOR;
+ System.arraycopy(authnid, 0, response, size, authnid.length);
+ size += authnid.length;
+ response[size++] = SEPARATOR;
+ System.arraycopy(password, 0, response, size, password.length);
+ clearPassword();
+ return response;
+ } catch (UnsupportedEncodingException e) {
+ throw new SaslException("PLAIN: Cannot get UTF-8 encoding of ids",
+ e);
+ }
+ }
+
+ public String getMechanismName()
+ {
+ return "PLAIN";
+ }
+
+ public boolean hasInitialResponse()
+ {
+ return true;
+ }
+
+ public boolean isComplete()
+ {
+ return completed;
+ }
+
+ public byte[] unwrap(byte[] incoming, int offset, int len) throws SaslException
+ {
+ if (completed) {
+ throw new IllegalStateException("PLAIN: this mechanism supports " +
+ "neither integrity nor privacy");
+ } else {
+ throw new IllegalStateException("PLAIN: authentication not " +
+ "completed");
+ }
+ }
+
+ public byte[] wrap(byte[] outgoing, int offset, int len) throws SaslException
+ {
+ if (completed)
+ {
+ throw new IllegalStateException("PLAIN: this mechanism supports " +
+ "neither integrity nor privacy");
+ }
+ else
+ {
+ throw new IllegalStateException("PLAIN: authentication not " +
+ "completed");
+ }
+ }
+
+ public Object getNegotiatedProperty(String propName)
+ {
+ if (completed)
+ {
+ if (propName.equals(Sasl.QOP))
+ {
+ return "auth";
+ }
+ else
+ {
+ return null;
+ }
+ }
+ else
+ {
+ throw new IllegalStateException("PLAIN: authentication not " +
+ "completed");
+ }
+ }
+
+ private void clearPassword()
+ {
+ if (password != null)
+ {
+ for (int i = 0 ; i < password.length ; i++)
+ {
+ password[i] = 0;
+ }
+ password = null;
+ }
+ }
+
+ public void dispose() throws SaslException
+ {
+ clearPassword();
+ }
+
+ protected void finalize()
+ {
+ clearPassword();
+ }
+
+ private Object[] getUserInfo() throws SaslException
+ {
+ try
+ {
+ final String userPrompt = "PLAIN authentication id: ";
+ final String pwPrompt = "PLAIN password: ";
+ NameCallback nameCb = new NameCallback(userPrompt);
+ PasswordCallback passwordCb = new PasswordCallback(pwPrompt, false);
+ cbh.handle(new Callback[] { nameCb, passwordCb });
+ String userid = nameCb.getName();
+ char pwchars[] = passwordCb.getPassword();
+ byte pwbytes[];
+ if (pwchars != null)
+ {
+ pwbytes = (new String(pwchars)).getBytes("UTF8");
+ passwordCb.clearPassword();
+ }
+ else
+ {
+ pwbytes = null;
+ }
+ return (new Object[] { userid, pwbytes });
+ }
+ catch (IOException e)
+ {
+ throw new SaslException("Cannot get password", e);
+ }
+ catch (UnsupportedCallbackException e)
+ {
+ throw new SaslException("Cannot get userid/password", e);
+ }
+ }
+}
diff --git a/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/sasl/SaslProvider.java b/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/sasl/SaslProvider.java
new file mode 100644
index 0000000000..2917de8740
--- /dev/null
+++ b/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/sasl/SaslProvider.java
@@ -0,0 +1,35 @@
+/*
+ *
+ * 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.management.ui.sasl;
+
+import java.security.Provider;
+
+public class SaslProvider extends Provider
+{
+ private static final long serialVersionUID = -6978096016899676466L;
+
+ public SaslProvider()
+ {
+ super("SaslClientFactory", 1.0, "SASL PLAIN CLIENT MECHANISM");
+ put("SaslClientFactory.PLAIN", "ClientSaslFactory");
+ }
+
+}
diff --git a/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/sasl/UserPasswordCallbackHandler.java b/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/sasl/UserPasswordCallbackHandler.java
new file mode 100644
index 0000000000..1602229c85
--- /dev/null
+++ b/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/sasl/UserPasswordCallbackHandler.java
@@ -0,0 +1,73 @@
+/*
+ * 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.management.ui.sasl;
+
+import java.io.*;
+import javax.security.auth.callback.*;
+
+public class UserPasswordCallbackHandler implements CallbackHandler
+{
+ private String user;
+ private char[] pwchars;
+
+ public UserPasswordCallbackHandler(String user, String password)
+ {
+ this.user = user;
+ this.pwchars = password.toCharArray();
+ }
+
+ public void handle(Callback[] callbacks) throws IOException, UnsupportedCallbackException
+ {
+ for (int i = 0; i < callbacks.length; i++)
+ {
+ if (callbacks[i] instanceof NameCallback)
+ {
+ NameCallback ncb = (NameCallback) callbacks[i];
+ ncb.setName(user);
+ }
+ else if (callbacks[i] instanceof PasswordCallback)
+ {
+ PasswordCallback pcb = (PasswordCallback) callbacks[i];
+ pcb.setPassword(pwchars);
+ }
+ else
+ {
+ throw new UnsupportedCallbackException(callbacks[i]);
+ }
+ }
+ }
+
+ private void clearPassword()
+ {
+ if (pwchars != null)
+ {
+ for (int i = 0 ; i < pwchars.length ; i++)
+ {
+ pwchars[i] = 0;
+ }
+ pwchars = null;
+ }
+ }
+
+ protected void finalize()
+ {
+ clearPassword();
+ }
+}
diff --git a/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/sasl/UsernameHashedPasswordCallbackHandler.java b/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/sasl/UsernameHashedPasswordCallbackHandler.java
new file mode 100644
index 0000000000..f4e3d2661e
--- /dev/null
+++ b/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/sasl/UsernameHashedPasswordCallbackHandler.java
@@ -0,0 +1,82 @@
+/*
+ *
+ * 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.management.ui.sasl;
+
+import java.io.IOException;
+
+import javax.security.auth.callback.Callback;
+import javax.security.auth.callback.CallbackHandler;
+import javax.security.auth.callback.NameCallback;
+import javax.security.auth.callback.PasswordCallback;
+import javax.security.auth.callback.UnsupportedCallbackException;
+
+import org.apache.qpid.management.ui.views.ViewUtility;
+
+public class UsernameHashedPasswordCallbackHandler implements CallbackHandler
+{
+ private String user;
+ private char[] pwchars;
+
+ public UsernameHashedPasswordCallbackHandler(String user, String password) throws Exception
+ {
+ this.user = user;
+ this.pwchars = ViewUtility.getHash(password);
+ }
+
+ public void handle(Callback[] callbacks) throws IOException, UnsupportedCallbackException
+ {
+ for (int i = 0; i < callbacks.length; i++)
+ {
+ if (callbacks[i] instanceof NameCallback)
+ {
+ NameCallback ncb = (NameCallback) callbacks[i];
+ ncb.setName(user);
+ }
+ else if (callbacks[i] instanceof PasswordCallback)
+ {
+ PasswordCallback pcb = (PasswordCallback) callbacks[i];
+ pcb.setPassword(pwchars);
+ }
+ else
+ {
+ throw new UnsupportedCallbackException(callbacks[i]);
+ }
+ }
+ }
+
+
+ private void clearPassword()
+ {
+ if (pwchars != null)
+ {
+ for (int i = 0 ; i < pwchars.length ; i++)
+ {
+ pwchars[i] = 0;
+ }
+ pwchars = null;
+ }
+ }
+
+ protected void finalize()
+ {
+ clearPassword();
+ }
+}
diff --git a/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/AttributesTabControl.java b/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/AttributesTabControl.java
index 437afeeda1..a7e8bbfc4c 100644
--- a/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/AttributesTabControl.java
+++ b/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/AttributesTabControl.java
@@ -596,7 +596,7 @@ public class AttributesTabControl extends TabControl
}
// Refresh from the server registry
- private void refresh()
+ public void refresh()
{
JMXServerRegistry serverRegistry = (JMXServerRegistry)ApplicationRegistry.getServerRegistry(_mbean);
ManagedAttributeModel attributesList = serverRegistry.getAttributeModel(_mbean);
diff --git a/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/MBeanView.java b/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/MBeanView.java
index 59b9fe3aaa..344c3c4e7f 100644
--- a/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/MBeanView.java
+++ b/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/MBeanView.java
@@ -62,6 +62,7 @@ public class MBeanView extends ViewPart
private FormToolkit _toolkit = null;
private Form _form = null;
+ private String _formText = APPLICATION_NAME;
private static ManagedServer _server = null;
private TreeObject _selectedNode = null;
private ManagedBean _mbean = null;
@@ -73,6 +74,8 @@ public class MBeanView extends ViewPart
// TabFolder to list all the mbeans for a given mbeantype(eg Connection, Queue, Exchange)
private TabFolder typeTabFolder = null;
+
+ private TabFolder notificationTabFolder = null;
/*
* Listener for the selection events in the navigation view
*/
@@ -91,16 +94,41 @@ public class MBeanView extends ViewPart
// an mbeantype. For mbeantype selection(eg Connection, Queue, Exchange) _mbean will remain null.
_mbean = null;
setInvisible();
- _form.setText(APPLICATION_NAME);
- // If a selected node(mbean) gets unregistered from mbena server, mbenaview should should
+ // If a selected node(mbean) gets unregistered from mbean server, mbeanview should
// make the tabfolber for that mbean invisible
if (_selectedNode == null)
return;
setServer();
refreshMBeanView();
+ setFormTitle();
+ }
+ }
+
+ private void setFormTitle()
+ {
+ if (_mbean != null)
+ {
+ _formText = _mbean.getType();
+ if ((_mbean.getVirtualHostName() != null) && (!DEFAULT_VH.equals(_mbean.getVirtualHostName())) )
+ {
+ _formText = _formText.replaceFirst(VIRTUAL_HOST, _mbean.getVirtualHostName());
+ if (_mbean.getName() != null && _mbean.getName().length() != 0)
+ {
+ _formText = _formText + ": " + _mbean.getName();
+ }
+ }
+ }
+ else if ((_selectedNode.getVirtualHost() != null) && (!DEFAULT_VH.equals(_selectedNode.getVirtualHost())))
+ {
+ _formText = _selectedNode.getVirtualHost();
}
+ else
+ {
+ _formText = APPLICATION_NAME;
+ }
+ _form.setText(_formText);
}
public void refreshMBeanView()
@@ -121,10 +149,16 @@ public class MBeanView extends ViewPart
{
refreshTypeTabFolder(_selectedNode.getName());
}
- else
+ else if (NOTIFICATIONS.equals(_selectedNode.getType()))
+ {
+ refreshNotificationPage();
+ }
+ else if (MBEAN.equals(_selectedNode.getType()))
{
+ _mbean = (ManagedBean)_selectedNode.getManagedObject();
showSelectedMBean();
}
+
_form.layout(true);
_form.getBody().layout(true, true);
}
@@ -174,20 +208,7 @@ public class MBeanView extends ViewPart
}
private void showSelectedMBean() throws Exception
- {
- if (NOTIFICATION.equals(_selectedNode.getType()))
- {
- _mbean = (ManagedBean)_selectedNode.getParent().getManagedObject();
- }
- else if (MBEAN.equals(_selectedNode.getType()))
- {
- _mbean = (ManagedBean)_selectedNode.getManagedObject();
- }
- else
- {
- return;
- }
-
+ {
try
{
MBeanUtility.getMBeanInfo(_mbean);
@@ -213,14 +234,8 @@ public class MBeanView extends ViewPart
tabFolder = createMBeanTabFolder();
}
- String text = _mbean.getType();
- if (_mbean.getName() != null && _mbean.getName().length() != 0)
- {
- text = text + ": " + _mbean.getName();
- }
- _form.setText(text);
int tabIndex = 0;
- if (NOTIFICATION.equals(_selectedNode.getType()))
+ if (NOTIFICATIONS.equals(_selectedNode.getType()))
{
tabIndex = tabFolder.getItemCount() -1;
}
@@ -247,6 +262,8 @@ public class MBeanView extends ViewPart
// Add mbeantype TabFolder. This will list all the mbeans under a mbeantype (eg Queue, Exchange).
// Using this list mbeans will be added in the navigation view
createMBeanTypeTabFolder();
+
+ createNotificationsTabFolder();
}
private TabFolder createMBeanTabFolder()
@@ -345,7 +362,7 @@ public class MBeanView extends ViewPart
NotificationsTabControl controller = new NotificationsTabControl(tabFolder);
TabItem tab = new TabItem(tabFolder, SWT.NONE);
- tab.setText(NOTIFICATION);
+ tab.setText(NOTIFICATIONS);
tab.setData(CONTROLLER, controller);
tab.setControl(controller.getControl());
}
@@ -432,6 +449,32 @@ public class MBeanView extends ViewPart
});
}
+ private void createNotificationsTabFolder()
+ {
+ notificationTabFolder = new TabFolder(_form.getBody(), SWT.NONE);
+ FormData layoutData = new FormData();
+ layoutData.left = new FormAttachment(0);
+ layoutData.top = new FormAttachment(0);
+ layoutData.right = new FormAttachment(100);
+ layoutData.bottom = new FormAttachment(100);
+ notificationTabFolder.setLayoutData(layoutData);
+ notificationTabFolder.setVisible(false);
+
+ VHNotificationsTabControl controller = new VHNotificationsTabControl(notificationTabFolder);
+ TabItem tab = new TabItem(notificationTabFolder, SWT.NONE);
+ tab.setText(NOTIFICATIONS);
+ tab.setData(CONTROLLER, controller);
+ tab.setControl(controller.getControl());
+ }
+
+ private void refreshNotificationPage()
+ {
+ TabItem tab = notificationTabFolder.getItem(0);
+ VHNotificationsTabControl controller = (VHNotificationsTabControl)tab.getData(CONTROLLER);
+ controller.refresh();
+ notificationTabFolder.setVisible(true);
+ }
+
/**
* Refreshes the Selected mbeantype tab. The control lists all the available mbeans
* for an mbeantype(eg Queue, Exchange etc)
@@ -492,6 +535,11 @@ public class MBeanView extends ViewPart
{
typeTabFolder.setVisible(false);
}
+
+ if (notificationTabFolder != null)
+ {
+ notificationTabFolder.setVisible(false);
+ }
}
}
diff --git a/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/NavigationView.java b/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/NavigationView.java
index a861405d30..68f95e01f0 100644
--- a/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/NavigationView.java
+++ b/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/NavigationView.java
@@ -244,7 +244,8 @@ public class NavigationView extends ViewPart
List<TreeObject> list = _serversRootNode.getChildren();
for (TreeObject node : list)
{
- if (url.equals(node.getUrl()))
+ ManagedServer nodeServer = (ManagedServer)node.getManagedObject();
+ if (url.equals(nodeServer.getUrl()))
{
// Server is already in the list of added servers, so now connect it.
// Set the server node as selected and then connect it.
@@ -266,7 +267,6 @@ public class NavigationView extends ViewPart
// Server connection is successful. Now add the server in the tree
TreeObject serverNode = new TreeObject(serverAddress, NODE_TYPE_SERVER);
- serverNode.setUrl(url);
serverNode.setManagedObject(managedServer);
_serversRootNode.addChild(serverNode);
@@ -504,6 +504,11 @@ public class NavigationView extends ViewPart
typeChild = new TreeObject(QUEUE, NODE_TYPE_MBEANTYPE);
typeChild.setParent(parent);
typeChild.setVirtualHost(parent.getVirtualHost());
+
+ // Add common notification node for virtual host
+ TreeObject notificationNode = new TreeObject(NOTIFICATIONS, NOTIFICATIONS);
+ notificationNode.setParent(parent);
+ notificationNode.setVirtualHost(parent.getVirtualHost());
}
/**
@@ -585,7 +590,10 @@ public class NavigationView extends ViewPart
// create a node for "type"
typeNode = createTypeNode(parentNode, type);
- typeNode.setVirtualHost(mbean.getVirtualHostName());
+ if (!type.equals(VIRTUAL_HOST))
+ {
+ typeNode.setVirtualHost(mbean.getVirtualHostName());
+ }
}
// now type node create becomes the parent node for next node in hierarchy
@@ -641,8 +649,8 @@ public class NavigationView extends ViewPart
// Add notification node
// TODO: show this only if the mbean sends any notification
- TreeObject notificationNode = new TreeObject(NOTIFICATION, NOTIFICATION);
- notificationNode.setParent(mbeanNode);
+ //TreeObject notificationNode = new TreeObject(NOTIFICATION, NOTIFICATION);
+ //notificationNode.setParent(mbeanNode);
}
private TreeObject createTypeNode(TreeObject parent, String name)
@@ -1044,7 +1052,7 @@ public class NavigationView extends ViewPart
public Image getImage(Object element)
{
TreeObject node = (TreeObject) element;
- if (node.getType().equals(NOTIFICATION))
+ if (node.getType().equals(NOTIFICATIONS))
{
return ApplicationRegistry.getImage(NOTIFICATION_IMAGE);
}
@@ -1107,8 +1115,11 @@ public class NavigationView extends ViewPart
{
return 1;
}
-
- return 2;
+ if (node.getType().equals(NOTIFICATIONS))
+ {
+ return 2;
+ }
+ return 3;
}
}
diff --git a/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/NotificationsTabControl.java b/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/NotificationsTabControl.java
index 4f0acde1b4..6894080859 100644
--- a/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/NotificationsTabControl.java
+++ b/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/NotificationsTabControl.java
@@ -20,29 +20,28 @@
*/
package org.apache.qpid.management.ui.views;
-import java.util.ArrayList;
+import static org.apache.qpid.management.ui.Constants.BUTTON_CLEAR;
+import static org.apache.qpid.management.ui.Constants.BUTTON_REFRESH;
+import static org.apache.qpid.management.ui.Constants.DESCRIPTION;
+import static org.apache.qpid.management.ui.Constants.FONT_BOLD;
+import static org.apache.qpid.management.ui.Constants.FONT_BUTTON;
+import static org.apache.qpid.management.ui.Constants.FONT_ITALIC;
+import static org.apache.qpid.management.ui.Constants.SUBSCRIBE_BUTTON;
+import static org.apache.qpid.management.ui.Constants.UNSUBSCRIBE_BUTTON;
+
import java.util.List;
-import static org.apache.qpid.management.ui.Constants.*;
import org.apache.qpid.management.ui.ApplicationRegistry;
import org.apache.qpid.management.ui.ManagedBean;
import org.apache.qpid.management.ui.ServerRegistry;
import org.apache.qpid.management.ui.jmx.MBeanUtility;
import org.apache.qpid.management.ui.model.NotificationInfoModel;
import org.apache.qpid.management.ui.model.NotificationObject;
-import org.eclipse.jface.viewers.DoubleClickEvent;
-import org.eclipse.jface.viewers.IDoubleClickListener;
-import org.eclipse.jface.viewers.ILabelProviderListener;
-import org.eclipse.jface.viewers.IStructuredContentProvider;
-import org.eclipse.jface.viewers.ITableLabelProvider;
-import org.eclipse.jface.viewers.StructuredSelection;
-import org.eclipse.jface.viewers.TableViewer;
-import org.eclipse.jface.viewers.Viewer;
+import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.events.SelectionListener;
-import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.layout.FormAttachment;
import org.eclipse.swt.layout.FormData;
import org.eclipse.swt.layout.FormLayout;
@@ -52,71 +51,35 @@ import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Combo;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
-import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Label;
-import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.TabFolder;
-import org.eclipse.swt.widgets.Table;
-import org.eclipse.swt.widgets.TableColumn;
-import org.eclipse.swt.widgets.Text;
-import org.eclipse.ui.forms.widgets.Form;
-import org.eclipse.ui.forms.widgets.FormToolkit;
/**
* Creates control composite for Notifications tab
* @author Bhupendra Bhardwaj
*/
-public class NotificationsTabControl extends TabControl
-{
- private FormToolkit _toolkit;
- private Form _form;
- private Table table = null;
- private TableViewer _tableViewer = null;
-
- private IStructuredContentProvider contentProvider = new ContentProviderImpl();
- private SelectionListener selectionListener = new SelectionListenerImpl();
- private SelectionListener comboListener = new ComboSelectionListener();
-
- private Thread worker = null;
-
- private List<NotificationObject> _notifications = null;
- private static final String COLUMN_SEQ = "Sequence No";
- private static final String COLUMN_TIME = "TimeStamp";
- private static final String COLUMN_TYPE = "Type";
- private static final String COLUMN_MSG = "Notification Message";
- private static final String[] _tableTitles = new String [] {
- COLUMN_SEQ,
- COLUMN_TIME,
- COLUMN_TYPE,
- COLUMN_MSG
- };
+public class NotificationsTabControl extends VHNotificationsTabControl
+{
+ private static final String SELECT_NOTIFICATIONNAME = "Select Notification";
+ private static final String SELECT_NOTIFICATIONTYPE = "Select Type";
+ private SelectionListener selectionListener;
+ private SelectionListener comboListener;
private Combo notificationNameCombo = null;
private Combo typesCombo = null;
private Label descriptionLabel = null;
private Button _subscribeButton = null;
private Button _unsubscribeButton = null;
- private Button _clearButton = null;
- private Button _refreshButton = null;
-
public NotificationsTabControl(TabFolder tabFolder)
{
super(tabFolder);
- _toolkit = new FormToolkit(_tabFolder.getDisplay());
- _form = _toolkit.createForm(_tabFolder);
- GridLayout gridLayout = new GridLayout();
- gridLayout.marginWidth = 0;
- gridLayout.marginHeight = 0;
- _form.getBody().setLayout(gridLayout);
-
- createWidgets();
- worker = new Thread(new Worker());
- worker.start();
}
- private void createWidgets()
+ protected void createWidgets()
{
+ selectionListener = new SelectionListenerImpl();
+ comboListener = new ComboSelectionListener();
createNotificationInfoComposite();
//addFilterComposite();
addButtons();
@@ -124,14 +87,6 @@ public class NotificationsTabControl extends TabControl
}
/**
- * @see TabControl#getControl()
- */
- public Control getControl()
- {
- return _form;
- }
-
- /**
* Creates composite and populates for displaying Notification Information (name, type, description)
* and creates buttons for subscribing or unsubscribing for notifications
*/
@@ -205,7 +160,7 @@ public class NotificationsTabControl extends TabControl
/**
* Creates clear buttin and refresh button
*/
- private void addButtons()
+ protected void addButtons()
{
Composite composite = _toolkit.createComposite(_form.getBody(), SWT.NONE);
composite.setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, false));
@@ -224,8 +179,9 @@ public class NotificationsTabControl extends TabControl
if (_mbean == null)
return;
+ IStructuredSelection ss = (IStructuredSelection)_tableViewer.getSelection();
ServerRegistry serverRegistry = ApplicationRegistry.getServerRegistry(_mbean);
- serverRegistry.clearNotifications(_mbean);
+ serverRegistry.clearNotifications(_mbean, ss.toList());
refresh();
}
});
@@ -247,155 +203,13 @@ public class NotificationsTabControl extends TabControl
}
});
}
-
- /**
- * Creates table to display notifications
- */
- private void createTable()
- {
- table = _toolkit.createTable(_form.getBody(), SWT.FULL_SELECTION);
- table.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
-
- TableColumn column = new TableColumn(table, SWT.NONE);
- column.setText(_tableTitles[0]);
- column.pack(); //column.setWidth(200);
-
- column = new TableColumn(table, SWT.NONE);
- column.setText(_tableTitles[1]);
- column.setWidth(150);
-
- column = new TableColumn(table, SWT.NONE);
- column.setText(_tableTitles[2]);
- column.setWidth(100);
-
- column = new TableColumn(table, SWT.NONE);
- column.setText(_tableTitles[3]);
- column.setWidth(500);
-
- table.setHeaderVisible(true);
- table.setLinesVisible(true);
- }
-
- /**
- * Creates JFace viewer for the notifications table
- */
- protected void createTableViewer()
- {
- createTable();
- _tableViewer = new TableViewer(table);
- //_tableViewer.getControl().setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
- _tableViewer.setUseHashlookup(true);
- _tableViewer.setContentProvider(contentProvider);
- _tableViewer.setLabelProvider(new LabelProviderImpl());
- _tableViewer.setColumnProperties(_tableTitles);
- /*
- CellEditor[] cellEditors = new CellEditor[_tableTitles.length];
- TextCellEditor textEditor = new TextCellEditor(table);
- cellEditors[0] = textEditor;
- textEditor = new TextCellEditor(table);
- cellEditors[1] = textEditor;
- textEditor = new TextCellEditor(table);
- cellEditors[2] = textEditor;
- textEditor = new TextCellEditor(table);
- cellEditors[3] = textEditor;
-
- // Assign the cell editors to the viewer
- _tableViewer.setCellEditors(cellEditors);
- _tableViewer.setCellModifier(new TableCellModifier());
- */
-
- addTableListeners();
-
- //_tableViewer.addSelectionChangedListener(new );
-
- //_notificationDetails = new Composite(_tabControl, SWT.BORDER);
- //_notificationDetails.setLayoutData(new GridData(GridData.FILL_BOTH));
-
- //_tabControl.layout();
- //viewerComposite.layout();
- }
-
- /**
- * Adds listeners to the viewer for displaying notification details
- */
- private void addTableListeners()
- {
- _tableViewer.addDoubleClickListener(new IDoubleClickListener()
- {
- Display display = null;
- Shell shell = null;
- public void doubleClick(DoubleClickEvent event)
- {
- display = Display.getCurrent();
- shell = new Shell(display, SWT.BORDER | SWT.CLOSE | SWT.MIN |
- SWT.MAX | SWT.RESIZE);
- shell.setText("Notification");
-
- int x = display.getBounds().width;
- int y = display.getBounds().height;
- shell.setBounds(x/4, y/4, x/2, y/3);
- StructuredSelection selection = (StructuredSelection)event.getSelection();
- createPopupContents((NotificationObject)selection.getFirstElement());
- shell.open();
- while (!shell.isDisposed()) {
- if (!display.readAndDispatch()) {
- display.sleep();
- }
- }
-
- //If you create it, you dispose it.
- shell.dispose();
- }
-
- private void createPopupContents(NotificationObject obj)
- {
- shell.setLayout(new GridLayout());
-
- Composite parent = new Composite(shell, SWT.NONE);
- parent.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
- GridLayout layout = new GridLayout(4, true);
- parent.setLayout(layout);
-
- Label key = new Label(parent, SWT.TRAIL);
- key.setText(COLUMN_SEQ);
- GridData layoutData = new GridData(SWT.TRAIL, SWT.TOP, false, false,1,1);
- key.setLayoutData(layoutData);
- Text value = new Text(parent, SWT.BEGINNING | SWT.BORDER |SWT.READ_ONLY);
- value.setText(""+obj.getSequenceNo());
- value.setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, false,3,1));
-
- // Time row
- key = new Label(parent, SWT.TRAIL);
- key.setText(COLUMN_TIME);
- key.setLayoutData(new GridData(SWT.TRAIL, SWT.TOP, true, false,1,1));
- value = new Text(parent, SWT.BEGINNING | SWT.BORDER | SWT.READ_ONLY);
- value.setText(""+obj.getTimeStamp());
- value.setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, false,3,1));
-
- key = new Label(parent, SWT.TRAIL);
- key.setText(COLUMN_TYPE);
- key.setLayoutData(new GridData(SWT.TRAIL, SWT.TOP, true, false,1,1));
- value = new Text(parent, SWT.BEGINNING | SWT.BORDER | SWT.READ_ONLY);
- value.setText(""+obj.getType());
- value.setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, false,3,1));
-
- key = new Label(parent, SWT.TRAIL);
- key.setText(COLUMN_MSG);
- key.setLayoutData(new GridData(SWT.TRAIL, SWT.TOP, true, false,1,1));
- value = new Text(parent, SWT.MULTI | SWT.WRAP| SWT.BORDER | SWT.V_SCROLL | SWT.READ_ONLY);
- value.setText(""+obj.getMessage());
- GridData gridData = new GridData(SWT.FILL, SWT.FILL, true, true, 3, 1);
- gridData.heightHint = 100;
- value.setLayoutData(gridData);
- }
- });
- }
-
+
@Override
public void refresh(ManagedBean mbean)
{
_mbean = mbean;
_notifications = null;
+ _table.deselectAll();
_tableViewer.getTable().clearAll();
if (_mbean == null)
@@ -431,9 +245,10 @@ public class NotificationsTabControl extends TabControl
_form.getBody().layout(true, true);
}
- private void refresh()
+ public void refresh()
{
_notifications = null;
+ _table.deselectAll();
_tableViewer.getTable().clearAll();
}
@@ -444,7 +259,11 @@ public class NotificationsTabControl extends TabControl
{
notificationNameCombo.removeAll();
NotificationInfoModel[] items = MBeanUtility.getNotificationInfo(_mbean);
- notificationNameCombo.add("Select Notification");
+ if (items.length > 1)
+ {
+ notificationNameCombo.add(SELECT_NOTIFICATIONNAME);
+ }
+
for (int i = 0; i < items.length; i++)
{
notificationNameCombo.add(items[i].getName());
@@ -457,6 +276,7 @@ public class NotificationsTabControl extends TabControl
typesCombo.select(0);
typesCombo.setEnabled(false);
+ populateNotificationType(notificationNameCombo.getItem(0));
checkForEnablingButtons();
}
@@ -466,7 +286,8 @@ public class NotificationsTabControl extends TabControl
private void checkForEnablingButtons()
{
int nameIndex = notificationNameCombo.getSelectionIndex();
- if (nameIndex == 0)
+ int itemCount = notificationNameCombo.getItems().length;
+ if ((itemCount > 1) && (nameIndex == 0))
{
_subscribeButton.setEnabled(false);
_unsubscribeButton.setEnabled(false);
@@ -475,7 +296,8 @@ public class NotificationsTabControl extends TabControl
}
int typeIndex = typesCombo.getSelectionIndex();
- if (typeIndex == 0)
+ itemCount = typesCombo.getItems().length;
+ if ((itemCount > 1) && (typeIndex == 0))
{
_subscribeButton.setEnabled(false);
_unsubscribeButton.setEnabled(false);
@@ -560,164 +382,38 @@ public class NotificationsTabControl extends TabControl
Combo combo = (Combo)e.getSource();
if (combo == notificationNameCombo)
{
- if (combo.getSelectionIndex() == 0)
- {
- descriptionLabel.setText("");
- typesCombo.select(0);
- typesCombo.setEnabled(false);
- return;
- }
- String index = combo.getItem(combo.getSelectionIndex());
- NotificationInfoModel data = (NotificationInfoModel)combo.getData(index);
- descriptionLabel.setText(data.getDescription());
- typesCombo.removeAll();
- typesCombo.setItems(data.getTypes());
- typesCombo.add("Select Type", 0);
- typesCombo.select(0);
- typesCombo.setEnabled(true);
+ String selectedItem = combo.getItem(combo.getSelectionIndex());
+ populateNotificationType(selectedItem);
}
checkForEnablingButtons();
}
}
- /**
- * Content provider class for the table viewer
- */
- private class ContentProviderImpl implements IStructuredContentProvider, INotificationViewer
+ private void populateNotificationType(String notificationName)
{
- public void inputChanged(Viewer v, Object oldInput, Object newInput)
+ NotificationInfoModel data = (NotificationInfoModel)notificationNameCombo.getData(notificationName);
+ if (data == null)
{
-
- }
- public void dispose()
- {
-
- }
- public Object[] getElements(Object parent)
- {
- return _notifications.toArray(new NotificationObject[0]);
- }
- public void addNotification(NotificationObject notification)
- {
- _tableViewer.add(notification);
- }
-
- public void addNotification(List<NotificationObject> notificationList)
- {
- _tableViewer.add(notificationList.toArray(new NotificationObject[0]));
- }
- }
-
- /**
- * Label provider for the table viewer
- */
- private class LabelProviderImpl implements ITableLabelProvider
- {
- List<ILabelProviderListener> listeners = new ArrayList<ILabelProviderListener>();
- public void addListener(ILabelProviderListener listener)
- {
- listeners.add(listener);
- }
-
- public void dispose(){
-
- }
-
- public Image getColumnImage(Object element, int columnIndex)
- {
- return null;
- }
-
- public String getColumnText(Object element, int columnIndex)
- {
- String result = null;
- NotificationObject t = (NotificationObject)element;
- switch(columnIndex)
- {
- case 0 :
- result = String.valueOf(t.getSequenceNo());
- break;
- case 1 :
- result = String.valueOf(t.getTimeStamp());
- break;
- case 2 :
- result = t.getType();
- break;
- case 3 :
- result = t.getMessage();
- break;
- default :
- result = "";
- }
-
- return result;
- }
-
- public boolean isLabelProperty(Object element, String property)
- {
- return false;
- }
-
- public void removeListener(ILabelProviderListener listener)
- {
- listeners.remove(listener);
- }
- } // end of LabelProviderImpl
-
- private boolean workerRunning = false;
- private void setWorkerRunning(boolean running)
- {
- workerRunning = running;
- }
-
- /**
- * Worker class which keeps looking if there are new notifications coming from server for the selected mbean
- */
- private class Worker implements Runnable
- {
- public void run()
- {
- Display display = _tabFolder.getDisplay();
- while(true)
- {
- if (!workerRunning || _mbean == null || display == null)
- {
- sleep();
- continue;
- }
-
- display.syncExec(new Runnable()
- {
- public void run()
- {
- setWorkerRunning(_form.isVisible());
- if (!workerRunning) return;
-
- updateTableViewer();
- }
- });
-
- sleep();
- }
+ descriptionLabel.setText("");
+ typesCombo.select(0);
+ typesCombo.setEnabled(false);
+ return;
}
-
- private void sleep()
+ descriptionLabel.setText(data.getDescription());
+ typesCombo.removeAll();
+ typesCombo.setItems(data.getTypes());
+ if (typesCombo.getItemCount() > 1)
{
- try
- {
- Thread.sleep(2000);
- }
- catch(Exception ex)
- {
-
- }
+ typesCombo.add(SELECT_NOTIFICATIONTYPE, 0);
}
+ typesCombo.select(0);
+ typesCombo.setEnabled(true);
}
/**
* Updates the table with new notifications received from mbean server for the selected mbean
*/
- private void updateTableViewer()
+ protected void updateTableViewer()
{
ServerRegistry serverRegistry = ApplicationRegistry.getServerRegistry(_mbean);
List<NotificationObject> newList = serverRegistry.getNotifications(_mbean);
diff --git a/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/OperationTabControl.java b/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/OperationTabControl.java
index 49b61c0fc6..2ac037e4f0 100644
--- a/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/OperationTabControl.java
+++ b/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/OperationTabControl.java
@@ -20,10 +20,16 @@
*/
package org.apache.qpid.management.ui.views;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map.Entry;
+import javax.management.openmbean.CompositeData;
+import javax.management.openmbean.TabularDataSupport;
+
import static org.apache.qpid.management.ui.Constants.*;
import org.apache.qpid.management.ui.ApplicationRegistry;
import org.apache.qpid.management.ui.ManagedBean;
@@ -76,7 +82,7 @@ public class OperationTabControl extends TabControl
private SelectionListener operationExecutionListener = new OperationExecutionListener();
private SelectionListener refreshListener = new RefreshListener();
private SelectionListener parameterSelectionListener = new ParameterSelectionListener();
- private SelectionListener bolleanSelectionListener = new BooleanSelectionListener();
+ private SelectionListener booleanSelectionListener = new BooleanSelectionListener();
private VerifyListener verifyListener = new VerifyListenerImpl();
private KeyListener keyListener = new KeyListenerImpl();
private KeyListener headerBindingListener = new HeaderBindingKeyListener();
@@ -249,6 +255,8 @@ public class OperationTabControl extends TabControl
formData.top = new FormAttachment(0, parameterPositionOffset);
formData.left = new FormAttachment(label, 5);
formData.right = new FormAttachment(valueWidth);
+ // this will contain the list of items, if the list is to be made available to choose from
+ // e.g. the list of exchanges
String[] items = null;
if (param.getName().equals(QUEUE))
{
@@ -269,6 +277,15 @@ public class OperationTabControl extends TabControl
{
items = EXCHANGE_TYPE_VALUES;
}
+ else if (_mbean.isAdmin() && param.getName().equals(OPERATION_PARAM_USERNAME)
+ && !_opData.getName().equals(OPERATION_CREATEUSER))
+ {
+ List<String> list = ApplicationRegistry.getServerRegistry(_mbean).getUsernames();
+ if (list != null && !list.isEmpty())
+ {
+ items = list.toArray(new String[0]);
+ }
+ }
if (items != null)
{
@@ -295,12 +312,17 @@ public class OperationTabControl extends TabControl
Button booleanButton = _toolkit.createButton(_paramsComposite, "", SWT.CHECK);
booleanButton.setLayoutData(formData);
booleanButton.setData(param);
- booleanButton.addSelectionListener(bolleanSelectionListener);
+ booleanButton.addSelectionListener(booleanSelectionListener);
valueInCombo = true;
}
else
{
- Text text = _toolkit.createText(_paramsComposite, "", SWT.NONE);
+ int style = SWT.NONE;
+ if (PASSWORD.equalsIgnoreCase(param.getName()))
+ {
+ style = SWT.PASSWORD;
+ }
+ Text text = _toolkit.createText(_paramsComposite, "", style);
formData = new FormData();
formData.top = new FormAttachment(0, parameterPositionOffset);
formData.left = new FormAttachment(label, 5);
@@ -530,6 +552,8 @@ public class OperationTabControl extends TabControl
((org.eclipse.swt.widgets.List)controls[i]).deselectAll();
else if (controls[i] instanceof Text)
((Text)controls[i]).setText("");
+ else if (controls[i] instanceof Button)
+ ((Button)controls[i]).setSelection(false);
else if (controls[i] instanceof Composite)
clearParameterValues((Composite)controls[i]);
}
@@ -557,6 +581,21 @@ public class OperationTabControl extends TabControl
}
// End of custom code
+
+ // customized for passwords
+ if (PASSWORD.equalsIgnoreCase(param.getName()))
+ {
+ try
+ {
+ param.setValueFromString(ViewUtility.getHashedString(param.getValue()));
+ }
+ catch (Exception ex)
+ {
+ MBeanUtility.handleException(_mbean, ex);
+ return;
+ }
+ }
+ // end of customization
ViewUtility.popupInfoMessage(_form.getText(),
"Please select the " + ViewUtility.getDisplayText(param.getName()));
@@ -609,6 +648,17 @@ public class OperationTabControl extends TabControl
return;
}
+ // Custom code for Admin mbean operation
+ /* These custome codes here are to make the GUI look more user friendly.
+ * Here we are adding the users to a list, which will be used to list username to be selected on
+ * pages like "delete user", "set password" instead of typing the username
+ */
+ if (_mbean.isAdmin() && _opData.getName().equals(OPERATION_VIEWUSERS))
+ {
+ ApplicationRegistry.getServerRegistry(_mbean).setUserList(extractUserList(result));
+ }
+ // end of custom code
+
// Some mbeans have only "type" and no "name".
String title = _mbean.getType();
if (_mbean.getName() != null && _mbean.getName().length() != 0)
@@ -616,9 +666,15 @@ public class OperationTabControl extends TabControl
title = _mbean.getName();
}
- if (_opData.getReturnType().equals("void") || _opData.getReturnType().equals("java.lang.Void"))
+ if (_opData.isReturnTypeVoid())
+ {
+ ViewUtility.popupInfoMessage(title, OPERATION_SUCCESSFUL);
+ }
+ else if (_opData.isReturnTypeBoolean())
{
- ViewUtility.popupInfoMessage(title, "Operation successful");
+ boolean success = Boolean.parseBoolean(result.toString());
+ String message = success ? OPERATION_SUCCESSFUL : OPERATION_UNSUCCESSFUL;
+ ViewUtility.popupInfoMessage(title, message);
}
else if (_opData.getParameters() != null && !_opData.getParameters().isEmpty())
{
@@ -634,6 +690,24 @@ public class OperationTabControl extends TabControl
}
+ private List<String> extractUserList(Object result)
+ {
+ if (!(result instanceof TabularDataSupport))
+ {
+ return null;
+ }
+
+ TabularDataSupport tabularData = (TabularDataSupport)result;
+ Collection<CompositeData> records = tabularData.values();
+ List<String> list = new ArrayList<String>();
+ for (CompositeData data : records)
+ {
+ list.add(data.get(USERNAME).toString());
+ }
+ Collections.sort(list);
+ return list;
+ }
+
/**
* Listener class for the operation parameters widget
*/
diff --git a/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/TabControl.java b/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/TabControl.java
index 0793e33538..c13c92066c 100644
--- a/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/TabControl.java
+++ b/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/TabControl.java
@@ -69,7 +69,18 @@ public abstract class TabControl
return null;
}
- public abstract void refresh(ManagedBean mbean);
+ public void refresh(ManagedBean mbean)
+ {
+ if (mbean == null)
+ {
+ refresh();
+ }
+ }
+
+ public void refresh()
+ {
+
+ }
public void refresh(ManagedBean mbean, OperationData opData)
{
diff --git a/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/TreeObject.java b/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/TreeObject.java
index 511c2d7150..9545ed9876 100644
--- a/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/TreeObject.java
+++ b/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/TreeObject.java
@@ -31,7 +31,6 @@ public class TreeObject
{
private String _name;
private String _type;
- private String _url;
private String _virtualHost;
private TreeObject _parent;
private List<TreeObject> _children = new ArrayList<TreeObject>();
@@ -88,16 +87,6 @@ public class TreeObject
{
return _type;
}
-
- public String getUrl()
- {
- return _url;
- }
-
- public void setUrl(String url)
- {
- this._url = url;
- }
public String getVirtualHost()
{
@@ -131,7 +120,6 @@ public class TreeObject
if (parent != null)
{
- this._url = parent.getUrl();
parent.addChild(this);
}
}
diff --git a/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/VHNotificationsTabControl.java b/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/VHNotificationsTabControl.java
new file mode 100644
index 0000000000..258f5ce02a
--- /dev/null
+++ b/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/VHNotificationsTabControl.java
@@ -0,0 +1,462 @@
+package org.apache.qpid.management.ui.views;
+
+import static org.apache.qpid.management.ui.Constants.BUTTON_CLEAR;
+import static org.apache.qpid.management.ui.Constants.BUTTON_REFRESH;
+import static org.apache.qpid.management.ui.Constants.CONSOLE_IMAGE;
+import static org.apache.qpid.management.ui.Constants.FONT_BUTTON;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.qpid.management.ui.ApplicationRegistry;
+import org.apache.qpid.management.ui.ServerRegistry;
+import org.apache.qpid.management.ui.model.NotificationObject;
+import org.eclipse.jface.viewers.DoubleClickEvent;
+import org.eclipse.jface.viewers.IDoubleClickListener;
+import org.eclipse.jface.viewers.ILabelProviderListener;
+import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.jface.viewers.IStructuredContentProvider;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.jface.viewers.ITableLabelProvider;
+import org.eclipse.jface.viewers.StructuredSelection;
+import org.eclipse.jface.viewers.TableViewer;
+import org.eclipse.jface.viewers.Viewer;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.SelectionAdapter;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.swt.widgets.TabFolder;
+import org.eclipse.swt.widgets.Table;
+import org.eclipse.swt.widgets.TableColumn;
+import org.eclipse.swt.widgets.Text;
+import org.eclipse.ui.forms.widgets.Form;
+import org.eclipse.ui.forms.widgets.FormToolkit;
+
+public class VHNotificationsTabControl extends TabControl
+{
+ protected FormToolkit _toolkit;
+ protected Form _form;
+ protected Table _table = null;
+ protected TableViewer _tableViewer = null;
+
+ protected Thread worker = null;
+
+ protected List<NotificationObject> _notifications = null;
+
+ private static final String COLUMN_OBJ = "Object Name";
+ private static final String COLUMN_SEQ = "Sequence No";
+ private static final String COLUMN_TIME = "TimeStamp";
+ private static final String COLUMN_TYPE = "Type";
+ private static final String COLUMN_MSG = "Notification Message";
+ protected static final String[] _tableTitles = new String [] {
+ COLUMN_OBJ,
+ COLUMN_SEQ,
+ COLUMN_TIME,
+ COLUMN_TYPE,
+ COLUMN_MSG
+ };
+
+ protected Button _clearButton = null;
+ protected Button _refreshButton = null;
+
+ public VHNotificationsTabControl(TabFolder tabFolder)
+ {
+ super(tabFolder);
+ _toolkit = new FormToolkit(_tabFolder.getDisplay());
+ _form = _toolkit.createForm(_tabFolder);
+ GridLayout gridLayout = new GridLayout();
+ gridLayout.marginWidth = 0;
+ gridLayout.marginHeight = 0;
+ _form.getBody().setLayout(gridLayout);
+
+ worker = new Thread(new Worker());
+ worker.start();
+ }
+
+ protected void createWidgets()
+ {
+ addButtons();
+ createTableViewer();
+ }
+
+ /**
+ * @see TabControl#getControl()
+ */
+ public Control getControl()
+ {
+ if (_table == null)
+ {
+ createWidgets();
+ }
+ return _form;
+ }
+
+ /**
+ * Creates clear buttin and refresh button
+ */
+ protected void addButtons()
+ {
+ Composite composite = _toolkit.createComposite(_form.getBody(), SWT.NONE);
+ composite.setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, false));
+ composite.setLayout(new GridLayout(2, true));
+
+ // Add Clear Button
+ _clearButton = _toolkit.createButton(composite, BUTTON_CLEAR, SWT.PUSH | SWT.CENTER);
+ _clearButton.setFont(ApplicationRegistry.getFont(FONT_BUTTON));
+ GridData gridData = new GridData(SWT.LEAD, SWT.TOP, true, false);
+ gridData.widthHint = 80;
+ _clearButton.setLayoutData(gridData);
+ _clearButton.addSelectionListener(new SelectionAdapter()
+ {
+ public void widgetSelected(SelectionEvent e)
+ {
+ //TODO : Get selected rows and clear those
+ IStructuredSelection ss = (IStructuredSelection)_tableViewer.getSelection();
+ ServerRegistry serverRegistry = ApplicationRegistry.getServerRegistry(MBeanView.getServer());
+ serverRegistry.clearNotifications(null, ss.toList());
+ refresh();
+ }
+ });
+
+ // Add Refresh Button
+ _refreshButton = _toolkit.createButton(composite, BUTTON_REFRESH, SWT.PUSH | SWT.CENTER);
+ _refreshButton.setFont(ApplicationRegistry.getFont(FONT_BUTTON));
+ gridData = new GridData(SWT.TRAIL, SWT.TOP, true, false);
+ gridData.widthHint = 80;
+ _refreshButton.setLayoutData(gridData);
+ _refreshButton.addSelectionListener(new SelectionAdapter()
+ {
+ public void widgetSelected(SelectionEvent e)
+ {
+ refresh();
+ }
+ });
+ }
+
+ /**
+ * Creates table to display notifications
+ */
+ private void createTable()
+ {
+ _table = _toolkit.createTable(_form.getBody(), SWT.MULTI | SWT.FULL_SELECTION);
+ _table.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
+
+ TableColumn column = new TableColumn(_table, SWT.NONE);
+ column.setText(_tableTitles[0]);
+ column.setWidth(100);
+
+ column = new TableColumn(_table, SWT.NONE);
+ column.setText(_tableTitles[1]);
+ column.setWidth(100);
+
+ column = new TableColumn(_table, SWT.NONE);
+ column.setText(_tableTitles[2]);
+ column.setWidth(130);
+
+ column = new TableColumn(_table, SWT.NONE);
+ column.setText(_tableTitles[3]);
+ column.setWidth(100);
+
+ column = new TableColumn(_table, SWT.NONE);
+ column.setText(_tableTitles[4]);
+ column.setWidth(500);
+
+ _table.setHeaderVisible(true);
+ _table.setLinesVisible(true);
+ }
+
+ /**
+ * Creates JFace viewer for the notifications table
+ */
+ protected void createTableViewer()
+ {
+ createTable();
+ _tableViewer = new TableViewer(_table);
+ //_tableViewer.getControl().setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
+ _tableViewer.setUseHashlookup(true);
+ _tableViewer.setContentProvider(new ContentProviderImpl());
+ _tableViewer.setLabelProvider(new LabelProviderImpl());
+ _tableViewer.setColumnProperties(_tableTitles);
+ /*
+ CellEditor[] cellEditors = new CellEditor[_tableTitles.length];
+ TextCellEditor textEditor = new TextCellEditor(table);
+ cellEditors[0] = textEditor;
+ textEditor = new TextCellEditor(table);
+ cellEditors[1] = textEditor;
+ textEditor = new TextCellEditor(table);
+ cellEditors[2] = textEditor;
+ textEditor = new TextCellEditor(table);
+ cellEditors[3] = textEditor;
+
+ // Assign the cell editors to the viewer
+ _tableViewer.setCellEditors(cellEditors);
+ _tableViewer.setCellModifier(new TableCellModifier());
+ */
+
+ addTableListeners();
+
+ //_tableViewer.addSelectionChangedListener(new );
+
+ //_notificationDetails = new Composite(_tabControl, SWT.BORDER);
+ //_notificationDetails.setLayoutData(new GridData(GridData.FILL_BOTH));
+
+ //_tabControl.layout();
+ //viewerComposite.layout();
+ }
+
+ /**
+ * Adds listeners to the viewer for displaying notification details
+ */
+ protected void addTableListeners()
+ {
+ _tableViewer.addDoubleClickListener(new IDoubleClickListener()
+ {
+ Display display = null;
+ Shell shell = null;
+ public void doubleClick(DoubleClickEvent event)
+ {
+ display = Display.getCurrent();
+ shell = new Shell(display, SWT.BORDER | SWT.CLOSE | SWT.MIN | SWT.MAX | SWT.RESIZE);
+ shell.setText("Notification");
+ shell.setImage(ApplicationRegistry.getImage(CONSOLE_IMAGE));
+
+ int x = display.getBounds().width;
+ int y = display.getBounds().height;
+ shell.setBounds(x/4, y/4, x/2, y/3);
+ StructuredSelection selection = (StructuredSelection)event.getSelection();
+ createPopupContents((NotificationObject)selection.getFirstElement());
+ shell.open();
+ while (!shell.isDisposed()) {
+ if (!display.readAndDispatch()) {
+ display.sleep();
+ }
+ }
+
+ //If you create it, you dispose it.
+ shell.dispose();
+ }
+
+ private void createPopupContents(NotificationObject obj)
+ {
+ shell.setLayout(new GridLayout());
+
+ Composite parent = _toolkit.createComposite(shell, SWT.NONE);
+ parent.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
+ GridLayout layout = new GridLayout(4, true);
+ parent.setLayout(layout);
+
+ // Object name record
+ Label key = _toolkit.createLabel(parent, COLUMN_OBJ, SWT.TRAIL);
+ GridData layoutData = new GridData(SWT.TRAIL, SWT.TOP, false, false,1,1);
+ key.setLayoutData(layoutData);
+ Text value = _toolkit.createText(parent, obj.getSourceName(), SWT.BEGINNING | SWT.BORDER |SWT.READ_ONLY);
+ value.setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, false,3,1));
+
+ // Sequence no record
+ key = _toolkit.createLabel(parent, COLUMN_SEQ, SWT.TRAIL);
+ layoutData = new GridData(SWT.TRAIL, SWT.TOP, false, false,1,1);
+ key.setLayoutData(layoutData);
+ value = _toolkit.createText(parent, ""+obj.getSequenceNo(), SWT.BEGINNING | SWT.BORDER |SWT.READ_ONLY);
+ value.setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, false,3,1));
+
+ // Time row
+ key = _toolkit.createLabel(parent, COLUMN_TIME, SWT.TRAIL);
+ key.setLayoutData(new GridData(SWT.TRAIL, SWT.TOP, true, false,1,1));
+ value = _toolkit.createText(parent, obj.getTimeStamp(), SWT.BEGINNING | SWT.BORDER | SWT.READ_ONLY);
+ value.setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, false,3,1));
+
+ key = _toolkit.createLabel(parent, COLUMN_TYPE, SWT.TRAIL);
+ key.setLayoutData(new GridData(SWT.TRAIL, SWT.TOP, true, false,1,1));
+ value = _toolkit.createText(parent, obj.getType(), SWT.BEGINNING | SWT.BORDER | SWT.READ_ONLY);
+ value.setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, false,3,1));
+
+ key = _toolkit.createLabel(parent, COLUMN_MSG, SWT.TRAIL);
+ key.setLayoutData(new GridData(SWT.TRAIL, SWT.TOP, true, false,1,1));
+ value = _toolkit.createText(parent, obj.getMessage(), SWT.MULTI | SWT.WRAP| SWT.BORDER | SWT.V_SCROLL | SWT.READ_ONLY);
+ GridData gridData = new GridData(SWT.FILL, SWT.FILL, true, true, 3, 1);
+ gridData.heightHint = 100;
+ value.setLayoutData(gridData);
+ }
+ });
+ }
+
+ public void refresh()
+ {
+ _notifications = null;
+ _table.deselectAll();
+ _tableViewer.getTable().clearAll();
+
+ Control[] children = _form.getBody().getChildren();
+ for (int i = 0; i < children.length; i++)
+ {
+ children[i].setVisible(true);
+ }
+
+ workerRunning = true;
+ _form.layout(true);
+ _form.getBody().layout(true, true);
+ }
+
+ /**
+ * Content provider class for the table viewer
+ */
+ protected class ContentProviderImpl implements IStructuredContentProvider, INotificationViewer
+ {
+ public void inputChanged(Viewer v, Object oldInput, Object newInput)
+ {
+
+ }
+ public void dispose()
+ {
+
+ }
+ public Object[] getElements(Object parent)
+ {
+ return _notifications.toArray(new NotificationObject[0]);
+ }
+ public void addNotification(NotificationObject notification)
+ {
+ _tableViewer.add(notification);
+ }
+
+ public void addNotification(List<NotificationObject> notificationList)
+ {
+ _tableViewer.add(notificationList.toArray(new NotificationObject[0]));
+ }
+ }
+
+ /**
+ * Label provider for the table viewer
+ */
+ protected class LabelProviderImpl implements ITableLabelProvider
+ {
+ List<ILabelProviderListener> listeners = new ArrayList<ILabelProviderListener>();
+ public void addListener(ILabelProviderListener listener)
+ {
+ listeners.add(listener);
+ }
+
+ public void dispose(){
+
+ }
+
+ public Image getColumnImage(Object element, int columnIndex)
+ {
+ return null;
+ }
+
+ public String getColumnText(Object element, int columnIndex)
+ {
+ String result = null;
+ NotificationObject t = (NotificationObject)element;
+ switch(columnIndex)
+ {
+ case 0 :
+ result = t.getSourceName();
+ break;
+ case 1 :
+ result = String.valueOf(t.getSequenceNo());
+ break;
+ case 2 :
+ result = String.valueOf(t.getTimeStamp());
+ break;
+ case 3 :
+ result = t.getType();
+ break;
+ case 4 :
+ result = t.getMessage();
+ break;
+ default :
+ result = "";
+ }
+
+ return result;
+ }
+
+ public boolean isLabelProperty(Object element, String property)
+ {
+ return false;
+ }
+
+ public void removeListener(ILabelProviderListener listener)
+ {
+ listeners.remove(listener);
+ }
+ } // end of LabelProviderImpl
+
+ protected boolean workerRunning = false;
+ protected void setWorkerRunning(boolean running)
+ {
+ workerRunning = running;
+ }
+
+ /**
+ * Worker class which keeps looking if there are new notifications coming from server for the selected mbean
+ */
+ private class Worker implements Runnable
+ {
+ public void run()
+ {
+ Display display = _tabFolder.getDisplay();
+ while(true)
+ {
+ if (!workerRunning || display == null)
+ {
+ sleep();
+ continue;
+ }
+
+ display.syncExec(new Runnable()
+ {
+ public void run()
+ {
+ if (_form == null || _form.isDisposed())
+ return;
+ setWorkerRunning(_form.isVisible());
+ if (!workerRunning) return;
+
+ updateTableViewer();
+ }
+ });
+
+ sleep();
+ }
+ }
+
+ private void sleep()
+ {
+ try
+ {
+ Thread.sleep(2000);
+ }
+ catch(Exception ex)
+ {
+
+ }
+ }
+ }
+
+ /**
+ * Updates the table with new notifications received from mbean server for all mbeans
+ */
+ protected void updateTableViewer()
+ {
+ ServerRegistry serverRegistry = ApplicationRegistry.getServerRegistry(MBeanView.getServer());
+ List<NotificationObject> newList = serverRegistry.getNotifications(null);
+ if (newList == null)
+ return;
+
+ _notifications = newList;
+ _tableViewer.setInput(_notifications);
+ _tableViewer.refresh();
+ }
+
+}
diff --git a/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/ViewUtility.java b/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/ViewUtility.java
index 9625a58f20..9b5cddd342 100644
--- a/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/ViewUtility.java
+++ b/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/ViewUtility.java
@@ -20,8 +20,13 @@
*/
package org.apache.qpid.management.ui.views;
+import java.io.UnsupportedEncodingException;
import java.nio.charset.Charset;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
import java.util.List;
import java.util.Map;
import java.util.Set;
@@ -70,6 +75,8 @@ public class ViewUtility
public static final String PREV = "Previous";
public static final String INDEX = "Index";
+ private static final Comparator tabularDataComparator = new TabularDataComparator();
+
private static List<String> SUPPORTED_ARRAY_DATATYPES = new ArrayList<String>();
static
{
@@ -121,6 +128,9 @@ public class ViewUtility
text.setLayoutData(layoutData);
return;
}
+
+ Collections.sort(list, tabularDataComparator);
+
// Attach the tabular record to be retrieved and shown later when record is traversed
// using first/next/previous/last buttons
composite.setData(list);
@@ -549,4 +559,63 @@ public class ViewUtility
oldControls[i].dispose();
}
}
+
+ public static String getHashedString(Object text) throws NoSuchAlgorithmException, UnsupportedEncodingException
+ {
+ char[] chars = getHash((String)text);
+ return new String(chars);
+ }
+
+ public static char[] getHash(String text) throws NoSuchAlgorithmException, UnsupportedEncodingException
+ {
+ byte[] data = text.getBytes("utf-8");
+
+ MessageDigest md = MessageDigest.getInstance("MD5");
+
+ for (byte b : data)
+ {
+ md.update(b);
+ }
+
+ byte[] digest = md.digest();
+
+ char[] hash = new char[digest.length ];
+
+ int index = 0;
+ for (byte b : digest)
+ {
+ hash[index++] = (char) b;
+ }
+
+ return hash;
+ }
+
+ private static class TabularDataComparator implements java.util.Comparator<Map.Entry>
+ {
+ public int compare(Map.Entry data1, Map.Entry data2)
+ {
+ if (data1.getKey() instanceof List)
+ {
+ Object obj1 = ((List)data1.getKey()).get(0);
+ Object obj2 = ((List)data2.getKey()).get(0);
+ String str1 = obj1.toString();
+ String str2 = obj2.toString();
+ if (obj1 instanceof String)
+ {
+ return str1.compareTo(str2);
+ }
+
+ try
+ {
+ return Long.valueOf(str1).compareTo(Long.valueOf(str2));
+ }
+ catch (Exception ex)
+ {
+ return -1;
+ }
+ }
+
+ return -1;
+ }
+ }
}
diff --git a/qpid/java/management/eclipse-plugin/src/main/resources/sasl/MANIFEST.MF b/qpid/java/management/eclipse-plugin/src/main/resources/sasl/MANIFEST.MF
new file mode 100644
index 0000000000..7a9e5caaaf
--- /dev/null
+++ b/qpid/java/management/eclipse-plugin/src/main/resources/sasl/MANIFEST.MF
@@ -0,0 +1,19 @@
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-Name: Jmxmp Plug-in
+Bundle-SymbolicName: jmxremote.optional
+Bundle-Version: 1.0.1
+Bundle-ClassPath: .
+Bundle-Vendor:
+Bundle-Localization: plugin
+Export-Package: com.sun.jmx.remote.generic,
+ com.sun.jmx.remote.opt.internal,
+ com.sun.jmx.remote.opt.security,
+ com.sun.jmx.remote.opt.util,
+ com.sun.jmx.remote.profile.sasl,
+ com.sun.jmx.remote.profile.tls,
+ com.sun.jmx.remote.protocol.jmxmp,
+ com.sun.jmx.remote.socket,
+ javax.management.remote.generic,
+ javax.management.remote.jmxmp,
+ javax.management.remote.message
diff --git a/qpid/java/management/eclipse-plugin/src/main/resources/win32/configuration/config.ini b/qpid/java/management/eclipse-plugin/src/main/resources/win32/configuration/config.ini
index dbe3f23fe9..1762840aff 100644
--- a/qpid/java/management/eclipse-plugin/src/main/resources/win32/configuration/config.ini
+++ b/qpid/java/management/eclipse-plugin/src/main/resources/win32/configuration/config.ini
@@ -22,5 +22,5 @@
osgi.splashPath=platform:/base/plugins/org.apache.qpid.management.ui
eclipse.product=org.apache.qpid.management.ui.product
eclipse.application=org.apache.qpid.management.ui.application
-osgi.bundles=org.eclipse.equinox.common@2:start,org.eclipse.core.runtime@start,com.ibm.icu,org.apache.qpid.management.ui,org.eclipse.core.commands,org.eclipse.core.contenttype,org.eclipse.core.expressions,org.eclipse.core.jobs,org.eclipse.core.runtime.compatibility.auth,org.eclipse.core.runtime.compatibility.registry,org.eclipse.equinox.preferences,org.eclipse.equinox.registry,org.eclipse.help,org.eclipse.jface,org.eclipse.swt,org.eclipse.swt.win32.win32.x86,org.eclipse.ui,org.eclipse.ui.forms,org.eclipse.ui.workbench
+osgi.bundles=org.eclipse.equinox.common@2:start,org.eclipse.core.runtime@start,com.ibm.icu,org.apache.qpid.management.ui,org.eclipse.core.commands,org.eclipse.core.contenttype,org.eclipse.core.expressions,org.eclipse.core.jobs,org.eclipse.core.runtime.compatibility.auth,org.eclipse.core.runtime.compatibility.registry,org.eclipse.equinox.preferences,org.eclipse.equinox.registry,org.eclipse.help,org.eclipse.jface,org.eclipse.swt,org.eclipse.swt.win32.win32.x86,org.eclipse.ui,org.eclipse.ui.forms,jmxremote.optional,org.eclipse.ui.workbench
osgi.bundles.defaultStartLevel=4
diff --git a/qpid/java/perftests/etc/scripts/BDB-Qpid-4.sh b/qpid/java/perftests/etc/scripts/BDB-Qpid-4.sh
new file mode 100755
index 0000000000..f54c057640
--- /dev/null
+++ b/qpid/java/perftests/etc/scripts/BDB-Qpid-4.sh
@@ -0,0 +1,28 @@
+#!/bin/bash
+
+if [ -z QPID_HOME ] ; then
+
+echo "QPID_HOME must be set"
+exit 0
+fi
+
+configs=`pwd`
+
+pushd $QPID_HOME/bin/
+
+echo "Starting qpid server - device config"
+./qpid-server -c $configs/bdb-qpid-4/device.xml
+
+echo "Starting qpid server - filepath config"
+./qpid-server -c $configs/bdb-qpid-4/filepath.xml
+
+echo "Starting qpid server - none existent path config"
+./qpid-server -c $configs/bdb-qpid-4/noneexistantpath.xml
+
+echo "Starting qpid server - no permission config"
+./qpid-server -c $configs/bdb-qpid-4/nopermission.xml
+
+echo "Starting qpid server - Star in path config"
+./qpid-server -c $configs/bdb-qpid-4/starpath.xml
+
+popd
diff --git a/qpid/java/perftests/etc/scripts/BDB-Qpid.sh b/qpid/java/perftests/etc/scripts/BDB-Qpid.sh
new file mode 100755
index 0000000000..8ff233dc6d
--- /dev/null
+++ b/qpid/java/perftests/etc/scripts/BDB-Qpid.sh
@@ -0,0 +1,12 @@
+#!/bin/bash
+
+# Parse arguements taking all - prefixed args as JAVA_OPTS
+for arg in "$@"; do
+ if [[ $arg == -java:* ]]; then
+ JAVA_OPTS="${JAVA_OPTS}-`echo $arg|cut -d ':' -f 2` "
+ else
+ ARGS="${ARGS}$arg "
+ fi
+done
+
+java -Xms256m -Dlog4j.configuration=perftests.log4j -Xmx256m -Dbadger.level=warn -Damqj.test.logging.level=warn -Damqj.logging.level=warn ${JAVA_OPTS} -cp qpid-perftests-1.0-incubating-M2-SNAPSHOT-all-test-deps.jar org.apache.qpid.ping.PingDurableClient -o $QPID_WORK/results ${ARGS}
diff --git a/qpid/java/perftests/etc/scripts/CTQ-Qpid-1.sh b/qpid/java/perftests/etc/scripts/CTQ-Qpid-1.sh
new file mode 100755
index 0000000000..518b06aac4
--- /dev/null
+++ b/qpid/java/perftests/etc/scripts/CTQ-Qpid-1.sh
@@ -0,0 +1 @@
+./PQ-Qpid-1.sh $@ & ./PQ-Qpid-1-P.sh $@
diff --git a/qpid/java/perftests/etc/scripts/CTQ-Qpid-2.sh b/qpid/java/perftests/etc/scripts/CTQ-Qpid-2.sh
new file mode 100755
index 0000000000..bbe5d75cd3
--- /dev/null
+++ b/qpid/java/perftests/etc/scripts/CTQ-Qpid-2.sh
@@ -0,0 +1 @@
+./PQ-Qpid-2.sh $@ & ./PQ-Qpid-2-P.sh $@
diff --git a/qpid/java/perftests/etc/scripts/CTQ-Qpid-3.sh b/qpid/java/perftests/etc/scripts/CTQ-Qpid-3.sh
new file mode 100755
index 0000000000..7e9430c8a3
--- /dev/null
+++ b/qpid/java/perftests/etc/scripts/CTQ-Qpid-3.sh
@@ -0,0 +1 @@
+./PQ-Qpid-3.sh $@ & ./PQ-Qpid-3-P.sh $@
diff --git a/qpid/java/perftests/etc/scripts/CTQ-Qpid-4.sh b/qpid/java/perftests/etc/scripts/CTQ-Qpid-4.sh
new file mode 100755
index 0000000000..720ca35fe1
--- /dev/null
+++ b/qpid/java/perftests/etc/scripts/CTQ-Qpid-4.sh
@@ -0,0 +1 @@
+./PQ-Qpid-4.sh $@ & ./PQ-Qpid-4-P.sh $@
diff --git a/qpid/java/perftests/etc/scripts/CTQ-Qpid-5.sh b/qpid/java/perftests/etc/scripts/CTQ-Qpid-5.sh
new file mode 100755
index 0000000000..fe19f6a513
--- /dev/null
+++ b/qpid/java/perftests/etc/scripts/CTQ-Qpid-5.sh
@@ -0,0 +1 @@
+./PQ-Qpid-5.sh $@ & ./PQ-Qpid-5-P.sh $@
diff --git a/qpid/java/perftests/etc/scripts/CTQ-Qpid-6.sh b/qpid/java/perftests/etc/scripts/CTQ-Qpid-6.sh
new file mode 100755
index 0000000000..09df5ce25a
--- /dev/null
+++ b/qpid/java/perftests/etc/scripts/CTQ-Qpid-6.sh
@@ -0,0 +1 @@
+./PQ-Qpid-6.sh $@ & ./PQ-Qpid-6-P.sh $@
diff --git a/qpid/java/perftests/etc/scripts/PT-Qpid-13.sh b/qpid/java/perftests/etc/scripts/PT-Qpid-13.sh
new file mode 100755
index 0000000000..630aa22ca3
--- /dev/null
+++ b/qpid/java/perftests/etc/scripts/PT-Qpid-13.sh
@@ -0,0 +1,24 @@
+#!/bin/bash
+
+# Parse arguements taking all - prefixed args as JAVA_OPTS
+for arg in "$@"; do
+ if [[ $arg == -java:* ]]; then
+ JAVA_OPTS="${JAVA_OPTS}-`echo $arg|cut -d ':' -f 2` "
+ else
+ ARGS="${ARGS}$arg "
+ fi
+done
+
+echo "Starting 6 parallel tests"
+java -Xms256m -Dlog4j.configuration=perftests.log4j -Xmx3072m -Dbadger.level=warn -Damqj.test.logging.level=info -Damqj.logging.level=warn ${JAVA_OPTS} -cp qpid-perftests-1.0-incubating-M2-SNAPSHOT-all-test-deps.jar uk.co.thebadgerset.junit.extensions.TKTestRunner -n PT-Qpid-13.1 -s [250] -c[200] -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf pubsub=true messageSize=256 destinationName=newd1 uniqueDests=true batchSize=250 transacted=true commitBatchSize=50 -o $QPID_WORK/results ${ARGS} &
+
+java -Xms256m -Dlog4j.configuration=perftests.log4j -Xmx3072m -Dbadger.level=warn -Damqj.test.logging.level=info -Damqj.logging.level=warn ${JAVA_OPTS} -cp qpid-perftests-1.0-incubating-M2-SNAPSHOT-all-test-deps.jar uk.co.thebadgerset.junit.extensions.TKTestRunner -n PT-Qpid-13.2 -s [250] -c[200] -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf pubsub=true messageSize=256 destinationName=newd2 uniqueDests=true batchSize=250 transacted=true commitBatchSize=50 -o $QPID_WORK/results ${ARGS} &
+
+java -Xms256m -Dlog4j.configuration=perftests.log4j -Xmx3072m -Dbadger.level=warn -Damqj.test.logging.level=info -Damqj.logging.level=warn ${JAVA_OPTS} -cp qpid-perftests-1.0-incubating-M2-SNAPSHOT-all-test-deps.jar uk.co.thebadgerset.junit.extensions.TKTestRunner -n PT-Qpid-13.3 -s [250] -c[200] -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf pubsub=true messageSize=256 destinationName=newd3 uniqueDests=true batchSize=250 transacted=true commitBatchSize=50 -o $QPID_WORK/results ${ARGS} &
+
+java -Xms256m -Dlog4j.configuration=perftests.log4j -Xmx3072m -Dbadger.level=warn -Damqj.test.logging.level=info -Damqj.logging.level=warn ${JAVA_OPTS} -cp qpid-perftests-1.0-incubating-M2-SNAPSHOT-all-test-deps.jar uk.co.thebadgerset.junit.extensions.TKTestRunner -n PT-Qpid-13.4 -s [250] -c[200] -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf pubsub=true messageSize=256 destinatioNname=newd4 uniqueDests=true batchSize=250 transacted=true commitBatchSize=50 -o $QPID_WORK/results ${ARGS} &
+
+java -Xms256m -Dlog4j.configuration=perftests.log4j -Xmx3072m -Dbadger.level=warn -Damqj.test.logging.level=info -Damqj.logging.level=warn ${JAVA_OPTS} -cp qpid-perftests-1.0-incubating-M2-SNAPSHOT-all-test-deps.jar uk.co.thebadgerset.junit.extensions.TKTestRunner -n PT-Qpid-13.5 -s [250] -c[100] -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf pubsub=true messageSize=256 destinationName=newd5 uniqueDests=true batchSize=250 transacted=true commitBatchSize=50 -o $QPID_WORK/results ${ARGS} &
+
+java -Xms256m -Dlog4j.configuration=perftests.log4j -Xmx3072m -Dbadger.level=warn -Damqj.test.logging.level=info -Damqj.logging.level=warn ${JAVA_OPTS} -cp qpid-perftests-1.0-incubating-M2-SNAPSHOT-all-test-deps.jar uk.co.thebadgerset.junit.extensions.TKTestRunner -n PT-Qpid-13.6 -s [250] -c[100] -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf pubsub=true messageSize=256 destinationName=newd6 uniqueDests=true batchSize=250 transacted=true commitBatchSize=50 -o $QPID_WORK/results ${ARGS}
+
diff --git a/qpid/java/perftests/etc/scripts/PT-Qpid-14.sh b/qpid/java/perftests/etc/scripts/PT-Qpid-14.sh
new file mode 100755
index 0000000000..7499eedda4
--- /dev/null
+++ b/qpid/java/perftests/etc/scripts/PT-Qpid-14.sh
@@ -0,0 +1,23 @@
+#!/bin/bash
+
+# Parse arguements taking all - prefixed args as JAVA_OPTS
+for arg in "$@"; do
+ if [[ $arg == -java:* ]]; then
+ JAVA_OPTS="${JAVA_OPTS}-`echo $arg|cut -d ':' -f 2` "
+ else
+ ARGS="${ARGS}$arg "
+ fi
+done
+echo "Starting 6 parallel tests"
+
+java -Xms256m -Dlog4j.configuration=perftests.log4j -Xmx3072m -Dbadger.level=warn -Damqj.test.logging.level=info -Damqj.logging.level=warn ${JAVA_OPTS} -cp qpid-perftests-1.0-incubating-M2-SNAPSHOT-all-test-deps.jar uk.co.thebadgerset.junit.extensions.TKTestRunner -n PT-Qpid-14 -s [250] -c[200] -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf pubsub=true messageSize=256 destinationName=ping1 batchSize=250 -o $QPID_WORK/results ${ARGS} &
+
+java -Xms256m -Dlog4j.configuration=perftests.log4j -Xmx3072m -Dbadger.level=warn -Damqj.test.logging.level=info -Damqj.logging.level=warn ${JAVA_OPTS} -cp qpid-perftests-1.0-incubating-M2-SNAPSHOT-all-test-deps.jar uk.co.thebadgerset.junit.extensions.TKTestRunner -n PT-Qpid-14 -s [250] -c[200] -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf pubsub=true messageSize=256 destinationName=ping2 batchSize=250 -o $QPID_WORK/results ${ARGS} &
+
+java -Xms256m -Dlog4j.configuration=perftests.log4j -Xmx3072m -Dbadger.level=warn -Damqj.test.logging.level=info -Damqj.logging.level=warn ${JAVA_OPTS} -cp qpid-perftests-1.0-incubating-M2-SNAPSHOT-all-test-deps.jar uk.co.thebadgerset.junit.extensions.TKTestRunner -n PT-Qpid-14 -s [250] -c[200] -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf pubsub=true messageSize=256 destinationName=ping3 batchSize=250 -o $QPID_WORK/results ${ARGS} &
+
+java -Xms256m -Dlog4j.configuration=perftests.log4j -Xmx3072m -Dbadger.level=warn -Damqj.test.logging.level=info -Damqj.logging.level=warn ${JAVA_OPTS} -cp qpid-perftests-1.0-incubating-M2-SNAPSHOT-all-test-deps.jar uk.co.thebadgerset.junit.extensions.TKTestRunner -n PT-Qpid-14 -s [250] -c[200] -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf pubsub=true messageSize=256destinationname=ping4 batchSize=250 -o $QPID_WORK/results ${ARGS} &
+
+java -Xms256m -Dlog4j.configuration=perftests.log4j -Xmx3072m -Dbadger.level=warn -Damqj.test.logging.level=info -Damqj.logging.level=warn ${JAVA_OPTS} -cp qpid-perftests-1.0-incubating-M2-SNAPSHOT-all-test-deps.jar uk.co.thebadgerset.junit.extensions.TKTestRunner -n PT-Qpid-14 -s [250] -c[100] -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf pubsub=true messageSize=256 destinationName=ping5 batchSize=250 -o $QPID_WORK/results ${ARGS} &
+
+java -Xms256m -Dlog4j.configuration=perftests.log4j -Xmx3072m -Dbadger.level=warn -Damqj.test.logging.level=info -Damqj.logging.level=warn ${JAVA_OPTS} -cp qpid-perftests-1.0-incubating-M2-SNAPSHOT-all-test-deps.jar uk.co.thebadgerset.junit.extensions.TKTestRunner -n PT-Qpid-14 -s [250] -c[100] -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf pubsub=true messageSize=256 destinationName=ping6 batchSize=250 -o $QPID_WORK/results ${ARGS}
diff --git a/qpid/java/perftests/etc/scripts/bdb-qpid-4/device.xml b/qpid/java/perftests/etc/scripts/bdb-qpid-4/device.xml
new file mode 100644
index 0000000000..a052f85167
--- /dev/null
+++ b/qpid/java/perftests/etc/scripts/bdb-qpid-4/device.xml
@@ -0,0 +1,98 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<!--
+ -
+ - 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.
+ -
+ -->
+<broker>
+ <prefix>${QPID_HOME}</prefix>
+ <work>${QPID_WORK}</work>
+ <conf>${prefix}/etc</conf>
+ <userhome>$HOME</userhome>
+ <connector>
+ <!-- Uncomment out this block and edit the keystorePath and keystorePassword
+ to enable SSL support
+ <ssl>
+ <enabled>true</enabled>
+ <sslOnly>true</sslOnly>
+ <keystorePath>/path/to/keystore.ks</keystorePath>
+ <keystorePassword>keystorepass</keystorePassword>
+ </ssl>-->
+ <qpidnio>true</qpidnio>
+ <transport>nio</transport>
+ <port>5672</port>
+ <sslport>8672</sslport>
+ <socketReceiveBuffer>32768</socketReceiveBuffer>
+ <socketSendBuffer>32768</socketSendBuffer>
+ </connector>
+ <management>
+ <enabled>true</enabled>
+ </management>
+ <advanced>
+ <filterchain enableExecutorPool="true"/>
+ <enablePooledAllocator>false</enablePooledAllocator>
+ <enableDirectBuffers>false</enableDirectBuffers>
+ <framesize>65535</framesize>
+ <compressBufferOnQueue>false</compressBufferOnQueue>
+ </advanced>
+
+ <security>
+ <principal-databases>
+ <principal-database>
+ <name>passwordfile</name>
+ <class>org.apache.qpid.server.security.auth.database.PlainPasswordVhostFilePrincipalDatabase</class>
+ <attributes>
+ <attribute>
+ <name>passwordFile</name>
+ <value>${conf}/passwdVhost</value>
+ </attribute>
+ </attributes>
+ </principal-database>
+ </principal-databases>
+
+ <access>
+ <class>org.apache.qpid.server.security.access.AllowAll</class>
+ </access>
+ </security>
+
+ <virtualhosts>
+ <virtualhost>
+ <name>device</name>
+ <device>
+ <store>
+ <!-- /dev/null give it a device -->
+ <class>org.apache.qpid.server.store.berkeleydb.BDBMessageStore</class>
+ <environment-path>/dev/null</environment-path>
+ </store>
+ </device>
+ </virtualhost>
+
+
+ </virtualhosts>
+ <heartbeat>
+ <delay>0</delay>
+ <timeoutFactor>2.0</timeoutFactor>
+ </heartbeat>
+ <queue>
+ <auto_register>true</auto_register>
+ </queue>
+
+ <virtualhosts>${conf}/virtualhosts.xml</virtualhosts>
+</broker>
+
+
diff --git a/qpid/java/perftests/etc/scripts/bdb-qpid-4/filepath.xml b/qpid/java/perftests/etc/scripts/bdb-qpid-4/filepath.xml
new file mode 100644
index 0000000000..ebce10cb95
--- /dev/null
+++ b/qpid/java/perftests/etc/scripts/bdb-qpid-4/filepath.xml
@@ -0,0 +1,97 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<!--
+ -
+ - 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.
+ -
+ -->
+<broker>
+ <prefix>${QPID_HOME}</prefix>
+ <work>${QPID_WORK}</work>
+ <conf>${prefix}/etc</conf>
+ <userhome>$HOME</userhome>
+ <connector>
+ <!-- Uncomment out this block and edit the keystorePath and keystorePassword
+ to enable SSL support
+ <ssl>
+ <enabled>true</enabled>
+ <sslOnly>true</sslOnly>
+ <keystorePath>/path/to/keystore.ks</keystorePath>
+ <keystorePassword>keystorepass</keystorePassword>
+ </ssl>-->
+ <qpidnio>true</qpidnio>
+ <transport>nio</transport>
+ <port>5672</port>
+ <sslport>8672</sslport>
+ <socketReceiveBuffer>32768</socketReceiveBuffer>
+ <socketSendBuffer>32768</socketSendBuffer>
+ </connector>
+ <management>
+ <enabled>true</enabled>
+ </management>
+ <advanced>
+ <filterchain enableExecutorPool="true"/>
+ <enablePooledAllocator>false</enablePooledAllocator>
+ <enableDirectBuffers>false</enableDirectBuffers>
+ <framesize>65535</framesize>
+ <compressBufferOnQueue>false</compressBufferOnQueue>
+ </advanced>
+
+ <security>
+ <principal-databases>
+ <principal-database>
+ <name>passwordfile</name>
+ <class>org.apache.qpid.server.security.auth.database.PlainPasswordVhostFilePrincipalDatabase</class>
+ <attributes>
+ <attribute>
+ <name>passwordFile</name>
+ <value>${conf}/passwdVhost</value>
+ </attribute>
+ </attributes>
+ </principal-database>
+ </principal-databases>
+
+ <access>
+ <class>org.apache.qpid.server.security.access.AllowAll</class>
+ </access>
+ </security>
+
+ <virtualhosts>
+ <virtualhost>
+ <name>pathToAFile</name>
+ <pathToAFile>
+ <store>
+ <!-- ${conf}/config.xml give the path to a file -->
+ <class>org.apache.qpid.server.store.berkeleydb.BDBMessageStore</class>
+ <environment-path>${conf}/config.xml</environment-path>
+ </store>
+ </pathToAFile>
+ </virtualhost>
+
+ </virtualhosts>
+ <heartbeat>
+ <delay>0</delay>
+ <timeoutFactor>2.0</timeoutFactor>
+ </heartbeat>
+ <queue>
+ <auto_register>true</auto_register>
+ </queue>
+
+ <virtualhosts>${conf}/virtualhosts.xml</virtualhosts>
+</broker>
+
+
diff --git a/qpid/java/perftests/etc/scripts/bdb-qpid-4/noneexistantpath.xml b/qpid/java/perftests/etc/scripts/bdb-qpid-4/noneexistantpath.xml
new file mode 100644
index 0000000000..c20beb1c92
--- /dev/null
+++ b/qpid/java/perftests/etc/scripts/bdb-qpid-4/noneexistantpath.xml
@@ -0,0 +1,97 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<!--
+ -
+ - 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.
+ -
+ -->
+<broker>
+ <prefix>${QPID_HOME}</prefix>
+ <work>${QPID_WORK}</work>
+ <conf>${prefix}/etc</conf>
+ <userhome>$HOME</userhome>
+ <connector>
+ <!-- Uncomment out this block and edit the keystorePath and keystorePassword
+ to enable SSL support
+ <ssl>
+ <enabled>true</enabled>
+ <sslOnly>true</sslOnly>
+ <keystorePath>/path/to/keystore.ks</keystorePath>
+ <keystorePassword>keystorepass</keystorePassword>
+ </ssl>-->
+ <qpidnio>true</qpidnio>
+ <transport>nio</transport>
+ <port>5672</port>
+ <sslport>8672</sslport>
+ <socketReceiveBuffer>32768</socketReceiveBuffer>
+ <socketSendBuffer>32768</socketSendBuffer>
+ </connector>
+ <management>
+ <enabled>true</enabled>
+ </management>
+ <advanced>
+ <filterchain enableExecutorPool="true"/>
+ <enablePooledAllocator>false</enablePooledAllocator>
+ <enableDirectBuffers>false</enableDirectBuffers>
+ <framesize>65535</framesize>
+ <compressBufferOnQueue>false</compressBufferOnQueue>
+ </advanced>
+
+ <security>
+ <principal-databases>
+ <principal-database>
+ <name>passwordfile</name>
+ <class>org.apache.qpid.server.security.auth.database.PlainPasswordVhostFilePrincipalDatabase</class>
+ <attributes>
+ <attribute>
+ <name>passwordFile</name>
+ <value>${conf}/passwdVhost</value>
+ </attribute>
+ </attributes>
+ </principal-database>
+ </principal-databases>
+
+ <access>
+ <class>org.apache.qpid.server.security.access.AllowAll</class>
+ </access>
+ </security>
+
+ <virtualhosts>
+ <virtualhost>
+ <name>nonExistentPath</name>
+ <nonExistentPath>
+ <store>
+ <!-- Path to a location that doesn't exist -->
+ <class>org.apache.qpid.server.store.berkeleydb.BDBMessageStore</class>
+ <environment-path>${work}/bdb-qpid-5/1/localhost-store</environment-path>
+ </store>
+ </nonExistentPath>
+ </virtualhost>
+
+ </virtualhosts>
+ <heartbeat>
+ <delay>0</delay>
+ <timeoutFactor>2.0</timeoutFactor>
+ </heartbeat>
+ <queue>
+ <auto_register>true</auto_register>
+ </queue>
+
+ <virtualhosts>${conf}/virtualhosts.xml</virtualhosts>
+</broker>
+
+
diff --git a/qpid/java/perftests/etc/scripts/bdb-qpid-4/nopermission.xml b/qpid/java/perftests/etc/scripts/bdb-qpid-4/nopermission.xml
new file mode 100644
index 0000000000..958a19cda2
--- /dev/null
+++ b/qpid/java/perftests/etc/scripts/bdb-qpid-4/nopermission.xml
@@ -0,0 +1,98 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<!--
+ -
+ - 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.
+ -
+ -->
+<broker>
+ <prefix>${QPID_HOME}</prefix>
+ <work>${QPID_WORK}</work>
+ <conf>${prefix}/etc</conf>
+ <userhome>$HOME</userhome>
+ <connector>
+ <!-- Uncomment out this block and edit the keystorePath and keystorePassword
+ to enable SSL support
+ <ssl>
+ <enabled>true</enabled>
+ <sslOnly>true</sslOnly>
+ <keystorePath>/path/to/keystore.ks</keystorePath>
+ <keystorePassword>keystorepass</keystorePassword>
+ </ssl>-->
+ <qpidnio>true</qpidnio>
+ <transport>nio</transport>
+ <port>5672</port>
+ <sslport>8672</sslport>
+ <socketReceiveBuffer>32768</socketReceiveBuffer>
+ <socketSendBuffer>32768</socketSendBuffer>
+ </connector>
+ <management>
+ <enabled>true</enabled>
+ </management>
+ <advanced>
+ <filterchain enableExecutorPool="true"/>
+ <enablePooledAllocator>false</enablePooledAllocator>
+ <enableDirectBuffers>false</enableDirectBuffers>
+ <framesize>65535</framesize>
+ <compressBufferOnQueue>false</compressBufferOnQueue>
+ </advanced>
+
+ <security>
+ <principal-databases>
+ <principal-database>
+ <name>passwordfile</name>
+ <class>org.apache.qpid.server.security.auth.database.PlainPasswordVhostFilePrincipalDatabase</class>
+ <attributes>
+ <attribute>
+ <name>passwordFile</name>
+ <value>${conf}/passwdVhost</value>
+ </attribute>
+ </attributes>
+ </principal-database>
+ </principal-databases>
+
+ <access>
+ <class>org.apache.qpid.server.security.access.AllowAll</class>
+ </access>
+ </security>
+
+ <virtualhosts>
+ <virtualhost>
+ <name>noPermissions</name>
+ <noPermissions>
+ <store>
+ <!-- /etc/bdb-qpid-5 give it somewhere it doesn't have permission -->
+ <class>org.apache.qpid.server.store.berkeleydb.BDBMessageStore</class>
+ <environment-path>/etc/bdb-qpid-5/</environment-path>
+ </store>
+ </noPermissions>
+ </virtualhost>
+
+
+ </virtualhosts>
+ <heartbeat>
+ <delay>0</delay>
+ <timeoutFactor>2.0</timeoutFactor>
+ </heartbeat>
+ <queue>
+ <auto_register>true</auto_register>
+ </queue>
+
+ <virtualhosts>${conf}/virtualhosts.xml</virtualhosts>
+</broker>
+
+
diff --git a/qpid/java/perftests/etc/scripts/bdb-qpid-4/starpath.xml b/qpid/java/perftests/etc/scripts/bdb-qpid-4/starpath.xml
new file mode 100644
index 0000000000..c795ec5202
--- /dev/null
+++ b/qpid/java/perftests/etc/scripts/bdb-qpid-4/starpath.xml
@@ -0,0 +1,98 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<!--
+ -
+ - 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.
+ -
+ -->
+<broker>
+ <prefix>${QPID_HOME}</prefix>
+ <work>${QPID_WORK}</work>
+ <conf>${prefix}/etc</conf>
+ <userhome>$HOME</userhome>
+ <connector>
+ <!-- Uncomment out this block and edit the keystorePath and keystorePassword
+ to enable SSL support
+ <ssl>
+ <enabled>true</enabled>
+ <sslOnly>true</sslOnly>
+ <keystorePath>/path/to/keystore.ks</keystorePath>
+ <keystorePassword>keystorepass</keystorePassword>
+ </ssl>-->
+ <qpidnio>true</qpidnio>
+ <transport>nio</transport>
+ <port>5672</port>
+ <sslport>8672</sslport>
+ <socketReceiveBuffer>32768</socketReceiveBuffer>
+ <socketSendBuffer>32768</socketSendBuffer>
+ </connector>
+ <management>
+ <enabled>true</enabled>
+ </management>
+ <advanced>
+ <filterchain enableExecutorPool="true"/>
+ <enablePooledAllocator>false</enablePooledAllocator>
+ <enableDirectBuffers>false</enableDirectBuffers>
+ <framesize>65535</framesize>
+ <compressBufferOnQueue>false</compressBufferOnQueue>
+ </advanced>
+
+ <security>
+ <principal-databases>
+ <principal-database>
+ <name>passwordfile</name>
+ <class>org.apache.qpid.server.security.auth.database.PlainPasswordVhostFilePrincipalDatabase</class>
+ <attributes>
+ <attribute>
+ <name>passwordFile</name>
+ <value>${conf}/passwdVhost</value>
+ </attribute>
+ </attributes>
+ </principal-database>
+ </principal-databases>
+
+ <access>
+ <class>org.apache.qpid.server.security.access.AllowAll</class>
+ </access>
+ </security>
+
+ <virtualhosts>
+
+ <virtualhost>
+ <name>pathWithStar</name>
+ <pathWithStar>
+ <store>
+ <!-- ${work}/bdbd-qpid-5/2/* have a * in path-->
+ <class>org.apache.qpid.server.store.berkeleydb.BDBMessageStore</class>
+ <environment-path>${work}/bdb-qpid-5/2/*-store</environment-path>
+ </store>
+ </pathWithStar>
+ </virtualhost>
+
+ </virtualhosts>
+ <heartbeat>
+ <delay>0</delay>
+ <timeoutFactor>2.0</timeoutFactor>
+ </heartbeat>
+ <queue>
+ <auto_register>true</auto_register>
+ </queue>
+
+ <virtualhosts>${conf}/virtualhosts.xml</virtualhosts>
+</broker>
+
+
diff --git a/qpid/java/perftests/pom.xml b/qpid/java/perftests/pom.xml
index c09d6a5a75..63edac1801 100644
--- a/qpid/java/perftests/pom.xml
+++ b/qpid/java/perftests/pom.xml
@@ -40,6 +40,18 @@
</properties>
<!-- Temporary local maven repo, whilst JUnit Toolkit is still reaching stable version to add to central maven repository. -->
+ <repositories>
+ <repository>
+ <id>junit-toolkit.snapshots</id>
+ <name>JUnit Toolkit SNAPSHOT Repository</name>
+ <url>http://junit-toolkit.svn.sourceforge.net/svnroot/junit-toolkit/snapshots/</url>
+ <snapshots>
+ <enabled>true</enabled>
+ </snapshots>
+ </repository>
+ </repositories>
+
+ <!-- Temporary local maven repo, whilst JUnit Toolkit is still reaching stable version to add to central maven repository. -->
<pluginRepositories>
<pluginRepository>
<id>junit-toolkit-plugin.snapshots</id>
@@ -86,18 +98,6 @@
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
</plugin>
- <plugin>
- <groupId>org.apache.maven.plugins</groupId>
- <artifactId>maven-jar-plugin</artifactId>
- <executions>
- <execution>
- <phase>package</phase>
- <goals>
- <goal>test-jar</goal>
- </goals>
- </execution>
- </executions>
- </plugin>
<!-- The JUnit Toolkit maven2 plugin is in the process of being added to the maven repository.
@@ -130,9 +130,16 @@
<configuration>
<scriptOutDirectory>target</scriptOutDirectory>
<testJar>${project.build.finalName}-all-test-deps.jar</testJar>
-
<systemproperties>
<property>
+ <name>-Xms</name>
+ <value>256m</value>
+ </property>
+ <property>
+ <name>-Xmx</name>
+ <value>3072m</value>
+ </property>
+ <property>
<name>log4j.configuration</name>
<value>${log4j.perftests}</value>
</property>
@@ -185,6 +192,267 @@
<Ping-Failover-After-Commit>
-n Ping-Failover-After-Commit -s [100] -o . -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf commitBatchSize=10 failAfterCommit=true
</Ping-Failover-After-Commit>
+
+ <!-- P2P Volume Tests. -->
+ <VT-Qpid-1>-n VT-Qpid-1 -d1H -s [1000] -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf pubsub=true messageSize=256 transacted=true -o $QPID_WORK/results</VT-Qpid-1>
+ <VT-Qpid-2>-n VT-Qpid-2 -d1H -s [1000] -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf pubsub=true commitBatchSize=100 messageSize=256 -o $QPID_WORK/results</VT-Qpid-2>
+ <!-- Setting sample to 3,000,000 will result in a log entry every 10 minutes so should have 144 data points for the run. -->
+ <VT-Qpid-3>-n VT-Qpid-3 -s [100000] -d 24H -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf pubsub=true rate=10000 messageSize=256 transacted=true -o $QPID_WORK/results commitBatchSize=100 batchSize=10000</VT-Qpid-3>
+ <VT-Qpid-4>-n VT-Qpid-4 -s [100000] -d 24H -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf pubsub=true rate=10000 messageSize=256 -o $QPID_WORK/results batchSize=10000</VT-Qpid-4>
+ <VT-Qpid-5>-n VT-Qpid-5 -s[1000] -c[1,32],samples=32 -d2M transacted=true commitBatchSize=100 persistent=false rate=1000 messageSize=256</VT-Qpid-5>
+ <VT-Qpid-6>-n VT-Qpid-6 -s[100] -c[1,32],samples=32 -d2M transacted=true commitBatchSize=100 persistent=true rate=100 messageSize=256</VT-Qpid-6>
+
+ <!-- P2P Scalability Tests. -->
+ <!-- 250,000 Total, 1P-1T-1C -->
+ <PT-Qpid-1>-n PT-Qpid-1 -d 10M -s [1000] -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf pubsub=true messageSize=256 -o $QPID_WORK/results commitBatchSize=100 transacted=true</PT-Qpid-1>
+ <PT-Qpid-2>-n PT-Qpid-2 -d 10M -s [1000] -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf pubsub=true messageSize=256 -o $QPID_WORK/results</PT-Qpid-2>
+
+ <!-- 25000 Msgs * 10 Brokers = 250,000 Total, 10P-1Q-10C -->
+ <PT-Qpid-3>-n PT-Qpid-3 -d 10M -s [1000] -c[10] -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf pubsub=true messageSize=256 -o $QPID_WORK/results commitBatchSize=100 transacted=true</PT-Qpid-3>
+ <PT-Qpid-4>-n PT-Qpid-4 -d 10M -s [1000] -c[10] -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf pubsub=true messageSize=256 -o $QPID_WORK/results</PT-Qpid-4>
+
+ <!-- 25000 Msgs * 10 Brokers = 250,000 Tota,l 10P-10T-10C 10*(1P-1Q-1C) -->
+ <PT-Qpid-5>-n PT-Qpid-5 -d 10M -s [1000] -c[10] -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf pubsub=true messageSize=256 -o $QPID_WORK/results transacted=true commitBatchSize=100</PT-Qpid-5>
+ <PT-Qpid-6>-n PT-Qpid-6 -d 10M -s [1000] -c[10] -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf pubsub=true messageSize=256 -o $QPID_WORK/results</PT-Qpid-6>
+
+ <!-- 2500 Msgs * 10 Brokers * 10 Topics/Clients = 250,000 Total, 10P-100T-10C 10*(1P-10T-1C) -->
+ <PT-Qpid-7>-n PT-Qpid-7 -d 10M -s [1000] -c[10] -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf pubsub=true destinationsCount=10 transacted=true commitBatchSize=100 messageSize=256 -o $QPID_WORK/results</PT-Qpid-7>
+ <PT-Qpid-8>-n PT-Qpid-8 -d 10M -s [1000] -c[10] -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf pubsub=true destinationsCount=10 messageSize=256 -o $QPID_WORK/results</PT-Qpid-8>
+
+ <!-- 2500 Msgs * 100 Brokers = 250,000 Total, 100P-100T-100C 100*(1P-1T-1C) -->
+ <PT-Qpid-9>-n PT-Qpid-9 -d 10M -s [1000] -c[100] -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf pubsub=true messageSize=256 commitBatchSize=100 transacted=true -o $QPID_WORK/results</PT-Qpid-9>
+ <PT-Qpid-10>-n PT-Qpid-10 -d 10M -s [1000] -c[100] -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf pubsub=true messageSize=256 batchSize=250 -o $QPID_WORK/results</PT-Qpid-10>
+
+ <!-- 250 Msgs * 100 Brokers * 10 Clients = 250,000 Total, 100P-1000T-100C 100*(1P-10T-1C) -->
+ <PT-Qpid-11>-n PT-Qpid-11 -d 10M -s [1000] -c[100] -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf pubsub=true messageSize=256 destinationsCount=10 transacted=true commitBatchSize=100 -o $QPID_WORK/results</PT-Qpid-11>
+ <PT-Qpid-12>-n PT-Qpid-12 -d 10M -s [1000] -c[100] -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf pubsub=true messageSize=256 destinationsCount=10 -o $QPID_WORK/results</PT-Qpid-12>
+
+ <!-- 250 Msgs * 1000 Brokers = 250,000 Total, 1000P-1000T-1000C 1000*(1P-1T-1C) -->
+ <!-- PT-Qpid-13>-n PT-Qpid-13 -s [100] -c[1000] -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf pubsub=true messageSize=256 batchSize=100 transacted=true commitBatchSize=100 -o $QPID_WORK/results</PT-Qpid-13 -->
+ <!-- PT-Qpid-14>-n PT-Qpid-14 -s [100] -c[1000] -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf pubsub=true messageSize=256 batchSize=100 -o $QPID_WORK/results</PT-Qpid-14 -->
+
+ <!-- P2P Volume Tests. -->
+ <VQ-Qpid-1>-n VQ-Qpid-1 -d 10M -s [1000] -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf messageSize=256 commitBatchSize=100 transacted=true -o $QPID_WORK/results</VQ-Qpid-1>
+ <VQ-Qpid-2>-n VQ-Qpid-2 -d 10M -s [1000] -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf messageSize=256 commitBatchSize=100 -o $QPID_WORK/results</VQ-Qpid-2>
+ <!-- Setting sample to 3,000,000 will result in a log entry every 10 minutes so should have 144 data points for the run. -->
+ <VQ-Qpid-3>-n VQ-Qpid-3 -s [100000] -d 24H -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf rate=10000 messageSize=256 commitBatchSize=100 transacted=true batchSize=100000 -o $QPID_WORK/results</VQ-Qpid-3>
+ <VQ-Qpid-4>-n VQ-Qpid-4 -s [100000] -d 24H -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf rate=10000 messageSize=256 batchSize=100000 -o $QPID_WORK/results</VQ-Qpid-4>
+
+ <!-- P2P Scalability Tests. -->
+ <!-- 15,000 Total, 1P-1Q-1C -->
+ <PQ-Qpid-1>-n PQ-Qpid-1 -d 10M -s [1000] -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf transacted=true commitBatchSize=100 messageSize=256 -o $QPID_WORK/results</PQ-Qpid-1>
+ <PQ-Qpid-2>-n PQ-Qpid-2 -d 10M -s [1000] -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf messageSize=256 -o $QPID_WORK/results</PQ-Qpid-2>
+
+ <!-- 1500 Messages * 10 Brokers = 15,000 Total, 10P-1Q-10C -->
+ <PQ-Qpid-3>-n PQ-Qpid-3 -d 10M -s [1000] -c[10] -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf messageSize=256 destinationName=ping transacted=true commitBatchSize=100 -o $QPID_WORK/results</PQ-Qpid-3>
+ <PQ-Qpid-4>-n PQ-Qpid-4 -d 10M -s [1000] -c[10] -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf messageSize=256 destinationName=ping -o $QPID_WORK/results</PQ-Qpid-4>
+
+ <!-- 1500 Messages * 10 Brokers = 15,000 Total, 10P-10Q-10C 10*(1P-1Q-1C) -->
+ <PQ-Qpid-5>-n PQ-Qpid-5 -d 10M -s [1000] -c[10] -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf messageSize=256 transacted=true commitBatchSize=100 -o $QPID_WORK/results</PQ-Qpid-5>
+ <PQ-Qpid-6>-n PQ-Qpid-6 -d 10M -s [1000] -c[10] -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf messageSize=256 -o $QPID_WORK/results</PQ-Qpid-6>
+
+ <!-- 1500 Messages * 10 Brokers = 15,000 Total, 10P-100Q-10C 10*(1P-10Q-1C) -->
+ <PQ-Qpid-7>-n PQ-Qpid-7 -d 10M -s [1000] -c[10] -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf messageSize=256 commitBatchSize=100 destinationsCount=10 transacted=true -o $QPID_WORK/results</PQ-Qpid-7>
+ <PQ-Qpid-8>-n PQ-Qpid-8 -d 10M -s [1000] -c[10] -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf messageSize=256 destinationsCount=10 -o $QPID_WORK/results</PQ-Qpid-8>
+
+ <!-- 150 Messages * 100 Brokers = 15,000 Total, 100P-100Q-100C 100*(1P-1Q-1C) -->
+ <PQ-Qpid-9>-n PQ-Qpid-9 -d 20M -s [1000] -c[100] -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf messageSize=256 transacted=true commitBatchSize=100 -o $QPID_WORK/results</PQ-Qpid-9>
+ <PQ-Qpid-10>-n PQ-Qpid-10 -d 10M -s [1000] -c[100] -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf messageSize=256 -o $QPID_WORK/results</PQ-Qpid-10>
+
+
+ <!-- 150 Messages * 100 Brokers = 15,000 Total, 100P-1000Q-100C 100*(1P-10Q-1C) -->
+ <PQ-Qpid-11>-n PQ-Qpid-11 -d 10M -s [1000] -c[100] -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf messageSize=256 destinationsCount=10 transacted=true commitBatchSize=100 -o $QPID_WORK/results</PQ-Qpid-11>
+ <PQ-Qpid-12>-n PQ-Qpid-12 -d 10M -s [1000] -c[100] -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf messageSize=256 destinationsCount=10 -o $QPID_WORK/results</PQ-Qpid-12>
+
+ <!-- 15 Messages * 1000 Brokers = 15,000 Total, 1000P-1000Q-1000C 1000*(1P-1Q-1C) -->
+ <!--PQ-Qpid-13>-n PQ-Qpid-13 -d 10M -s [1000] -c[1000] -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf messageSize=256 transacted=true commitBatchSize=100 -o $QPID_WORK/results</PQ-Qpid-13>
+ <PQ-Qpid-14>-n PQ-Qpid-14 -d 10M -s [1000] -c[1000] -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf messageSize=256 batchSize=15 -o $QPID_WORK/results</PQ-Qpid-14-->
+
+ <!-- Increasing Message Payload Tests. -->
+ <!-- Topic Testing -->
+ <LT-Qpid-1-512b>-n LT-Qpid-1-512b -d 10M -s [1000] -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf pubsub=true messageSize=512 transacted=true commitBatchSize=100 -o $QPID_WORK/results</LT-Qpid-1-512b>
+ <LT-Qpid-2-512b>-n LT-Qpid-2-512b -d 10M -s [1000] -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf pubsub=true messageSize=512 -o $QPID_WORK/results</LT-Qpid-2-512b>
+
+ <LT-Qpid-1-1K>-n LT-Qpid-1-1K -d 10M -s [1000] -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf pubsub=true commitBatchSize=100 transacted=true messageSize=1024 -o $QPID_WORK/results</LT-Qpid-1-1K>
+ <LT-Qpid-2-1K>-n LT-Qpid-2-1K -d 10M -s [1000] -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf pubsub=true messageSize=1024 -o $QPID_WORK/results</LT-Qpid-2-1K>
+
+ <LT-Qpid-1-5K>-n LT-Qpid-1-5K -d 10M -s [1000] -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf pubsub=true commitBatchSize=100 messageSize=5120 transacted=true -o $QPID_WORK/results</LT-Qpid-1-5K>
+ <LT-Qpid-2-5K>-n LT-Qpid-2-5K -d 10M -s [1000] -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf pubsub=true messageSize=5120 -o $QPID_WORK/results</LT-Qpid-2-5K>
+
+ <LT-Qpid-1-10K>-n LT-Qpid-1-10K -d10M -s [1000] -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf pubsub=true commitBatchSize=100 messageSize=10240 transacted=true -o $QPID_WORK/results</LT-Qpid-1-10K>
+ <LT-Qpid-2-10K>-n LT-Qpid-2-10K -d10M -s [1000] -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf pubsub=true messageSize=10240 -o $QPID_WORK/results</LT-Qpid-2-10K>
+
+ <LT-Qpid-1-50K>-n LT-Qpid-1-50K -d10M -s [1000] -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf pubsub=true commitBatchSize=100 messageSize=51200 transacted=true -o $QPID_WORK/results</LT-Qpid-1-50K>
+ <LT-Qpid-2-50K>-n LT-Qpid-2-50K -d10M -s [1000] -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf pubsub=true messageSize=51200 -o $QPID_WORK/results</LT-Qpid-2-50K>
+
+ <LT-Qpid-1-100K>-n LT-Qpid-1-100K -d10M -s [1000] -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf pubsub=true commitBatchSize=100 messageSize=102400 transacted=true -o $QPID_WORK/results</LT-Qpid-1-100K>
+ <LT-Qpid-2-100K>-n LT-Qpid-2-100K -d10M -s [1000] -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf pubsub=true messageSize=102400 -o $QPID_WORK/results</LT-Qpid-2-100K>
+
+ <LT-Qpid-1-1M>-n LT-Qpid-1-1M -d10M -s [1000] -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf pubsub=true commitBatchSize=100 messageSize=1048576 transacted=true -o $QPID_WORK/results</LT-Qpid-1-1M>
+ <LT-Qpid-2-1M>-n LT-Qpid-2-1M -d10M -s [1000] -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf pubsub=true messageSize=1048476 -o $QPID_WORK/results</LT-Qpid-2-1M>
+
+ <!-- Queue Testing -->
+ <LT-Qpid-3-512b>-n LT-Qpid-3-512b -d10M -s [1000] -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf commitBatchSize=100 messageSize=512 transacted=true -o $QPID_WORK/results</LT-Qpid-3-512b>
+ <LT-Qpid-4-512b>-n LT-Qpid-4-512b -d10M -s [1000] -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf messageSize=512 -o $QPID_WORK/results</LT-Qpid-4-512b>
+
+ <LT-Qpid-3-1K>-n LT-Qpid-3-1K -d10M -s [1000] -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf commitBatchSize=100 messageSize=1024 transacted=true -o $QPID_WORK/results</LT-Qpid-3-1K>
+ <LT-Qpid-4-1K>-n LT-Qpid-4-1K -d10M -s [1000] -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPer messageSize=1024 -o $QPID_WORK/results</LT-Qpid-4-1K>
+
+ <LT-Qpid-3-5K>-n LT-Qpid-3-5K -d10M -s [1000] -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf commitBatchSize=100 messageSize=5120 transacted=true -o $QPID_WORK/results</LT-Qpid-3-5K>
+ <LT-Qpid-4-5K>-n LT-Qpid-4-5K -d10M -s [1000] -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf messageSize=5120 -o $QPID_WORK/results</LT-Qpid-4-5K>
+
+ <LT-Qpid-3-10K>-n LT-Qpid-3-10K -d10M -s [1000] -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf commitBatchSize=100 messageSize=10240 transacted=true -o $QPID_WORK/results</LT-Qpid-3-10K>
+ <LT-Qpid-4-10K>-n LT-Qpid-4-10K -d10M -s [1000] -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf messageSize=10240 -o $QPID_WORK/results</LT-Qpid-4-10K>
+
+ <LT-Qpid-3-50K>-n LT-Qpid-3-50K -d10M -s [1000] -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf commitBatchSize=100 messageSize=51200 transacted=true -o $QPID_WORK/results</LT-Qpid-3-50K>
+ <LT-Qpid-4-50K>-n LT-Qpid-4-50K -d10M -s [1000] -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf messageSize=51200 -o $QPID_WORK/results</LT-Qpid-4-50K>
+
+ <LT-Qpid-3-100K>-n LT-Qpid-3-100K -d10M -s [1000] -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf commitBatchSize=100 messageSize=102400 transacted=true -o $QPID_WORK/results</LT-Qpid-3-100K>
+ <LT-Qpid-4-100K>-n LT-Qpid-4-100K -d10M -s [1000] -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf messageSize=102400 -o $QPID_WORK/results</LT-Qpid-4-100K>
+
+ <LT-Qpid-3-1M>-n LT-Qpid-3-1M -d10M -s [1000] -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf commitBatchSize=100 messageSize=1048576 transacted=true -o $QPID_WORK/results</LT-Qpid-3-1M>
+ <LT-Qpid-4-1M>-n LT-Qpid-4-1M -d10M -s [1000] -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf messageSize=1048576 -o $QPID_WORK/results</LT-Qpid-4-1M>
+
+ <!-- Failover Tests. -->
+ <!-- Transactional -->
+ <FT-Qpid-1>-n FT-Qpid-1 -s [250000] -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf messageSize=256 batchSize=10000 transacted=true broker="tcp://10.0.0.1:5001;tcp://10.0.0.2:5002" FailBeforeSend=true -o $QPID_WORK/results</FT-Qpid-1>
+ <FT-Qpid-2>-n FT-Qpid-2 -s [250000] -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf messageSize=256 batchSize=10000 transacted=true broker="tcp://10.0.0.1:5001;tcp://10.0.0.2:5002" failAfterSend=true -o $QPID_WORK/results</FT-Qpid-2>
+ <FT-Qpid-3>-n FT-Qpid-3 -s [250000] -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf messageSize=256 batchSize=10000 transacted=true broker="tcp://10.0.0.1:5001;tcp://10.0.0.2:5002" failAfterCommit=true -o $QPID_WORK/results</FT-Qpid-3>
+
+ <!-- Non Transactional -->
+ <FT-Qpid-4>-n FT-Qpid-4 -s [250000] -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf messageSize=256 batchSize=10000 broker="tcp://10.0.0.1:5001;tcp://10.0.0.2:5002" transacted=false failBeforeSend=true -o $QPID_WORK/results</FT-Qpid-4>
+ <FT-Qpid-5>-n FT-Qpid-5 -s [250000] -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf messageSize=256 batchSize=10000 broker="tcp://10.0.0.1:5001;tcp://10.0.0.2:5002" transacted=false failAfterSend=true -o $QPID_WORK/results</FT-Qpid-5>
+
+
+ <!-- Persistent Tests -->
+
+ <!-- P2P Volume Tests. -->
+ <VT-Qpid-1-P>-n VT-Qpid-1 -d1H -s [1000] -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=true pubsub=true messageSize=256 commitBatchSize=100 transacted=true -o $QPID_WORK/results</VT-Qpid-1-P>
+ <VT-Qpid-2-P>-n VT-Qpid-2 -d1H -s [1000] -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=true pubsub=true messageSize=256 -o $QPID_WORK/results</VT-Qpid-2-P>
+ <!-- Setting sample to 3,000,000 will result in a log entry every 10 minutes so should have 144 data points for the run. -->
+ <VT-Qpid-3-P>-n VT-Qpid-3 -s [100000] -d 24H -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=true pubsub=true rate=1000 messageSize=256 commitBatchSize=100 transacted=true -o $QPID_WORK/results batchSize=10000</VT-Qpid-3-P>
+ <VT-Qpid-4-P>-n VT-Qpid-4 -s [100000] -d 24H -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=true pubsub=true rate=1000 messageSize=256 -o $QPID_WORK/results batchSize=10000</VT-Qpid-4-P>
+
+ <!-- P2P Scalability Tests. -->
+ <!-- 25,000 Total, 1P-1T-1C -->
+ <PT-Qpid-1-P>-n PT-Qpid-1-P -d10M -s [1000] -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=true pubsub=true messageSize=256 commitBatchSize=100 transacted=true -o $QPID_WORK/results</PT-Qpid-1-P>
+ <PT-Qpid-2-P>-n PT-Qpid-2-P -d10M -s [1000] -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=true pubsub=true messageSize=256 -o $QPID_WORK/results</PT-Qpid-2-P>
+
+ <!-- 2500 Msgs * 10 Brokers = 25,000 Total, 10P-1Q-10C -->
+ <PT-Qpid-3-P>-n PT-Qpid-3-P -d10M -s [1000] -c[10] -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=true pubsub=true messageSize=256 commitBatchSize=100 transacted=true -o $QPID_WORK/results</PT-Qpid-3-P>
+ <PT-Qpid-4-P>-n PT-Qpid-4-P -d10M -s [1000] -c[10] -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=true pubsub=true messageSize=256 -o $QPID_WORK/results</PT-Qpid-4-P>
+
+ <!-- 2500 Msgs * 10 Brokers = 25,000 Tota,l 10P-10T-10C 10*(1P-1Q-1C) -->
+ <PT-Qpid-5-P>-n PT-Qpid-5-P -d10M -s [1000] -c[10] -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=true pubsub=true transacted=true messageSize=256 commitBatchSize=100 -o $QPID_WORK/results</PT-Qpid-5-P>
+ <PT-Qpid-6-P>-n PT-Qpid-6-P -d10M -s [1000] -c[10] -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=true pubsub=true messageSize=256 -o $QPID_WORK/results</PT-Qpid-6-P>
+
+ <!-- 250 Msgs * 10 Brokers * 10 Topics/Clients = 250,000 Total, 10P-100T-10C 10*(1P-10T-1C) -->
+ <PT-Qpid-7-P>-n PT-Qpid-7-P -d10M -s [1000] -c[10] -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=true pubsub=true destinationsCount=10 transacted=true messageSize=256 commitBatchSize=100 -o $QPID_WORK/results</PT-Qpid-7-P>
+ <PT-Qpid-8-P>-n PT-Qpid-8-P -d10M -s [1000] -c[10] -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=true pubsub=true destinationsCount=10 messageSize=256 -o $QPID_WORK/results</PT-Qpid-8-P>
+
+ <!-- 250 Msgs * 100 Brokers = 25,000 Total, 100P-100T-100C 100*(1P-1T-1C) -->
+ <PT-Qpid-9-P>-n PT-Qpid-9-P -d10M -s [1000] -c[100] -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=true pubsub=true messageSize=256 commitBatchSize=100 transacted=true -o $QPID_WORK/results</PT-Qpid-9-P>
+ <PT-Qpid-10-P>-n PT-Qpid-10-P -d10M -s [1000] -c[100] -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=true pubsub=true messageSize=256 batchSize=250 -o $QPID_WORK/results</PT-Qpid-10-P>
+
+ <!-- 25 Msgs * 100 Brokers * 10 Clients = 250,000 Total, 100P-1000T-100C 100*(1P-10T-1C) -->
+ <PT-Qpid-11-P>-n PT-Qpid-11-P -d10M -s [1000] -c[100] -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=true pubsub=true messageSize=256 destinationsCount=10 transacted=true commitBatchSize=100 -o $QPID_WORK/results</PT-Qpid-11-P>
+ <PT-Qpid-12-P>-n PT-Qpid-12-P -d10M -s [1000] -c[100] -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=true pubsub=true messageSize=256 destinationsCount=10 -o $QPID_WORK/results</PT-Qpid-12-P>
+
+ <!-- 25 Msgs * 1000 Brokers = 25,000 Total, 1000P-1000T-1000C 1000*(1P-1T-1C) -->
+ <!--PT-Qpid-13-P>-n PT-Qpid-13-P -d10M -s [1000] -c[1000] -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=true pubsub=true messageSize=256 transacted=true commitBatchSize=100 -o $QPID_WORK/results</PT-Qpid-13-P-->
+ <!--PT-Qpid-14-P>-n PT-Qpid-14-P -d10M -s [1000] -c[1000] -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=true pubsub=true messageSize=256 -o $QPID_WORK/results</PT-Qpid-14-P-->
+
+ <!-- P2P Volume Tests. -->
+ <VQ-Qpid-1-P>-n VQ-Qpid-1-P -d1H -s [1000] -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=true messageSize=256 commitBatchSize=100 transacted=true -o $QPID_WORK/results</VQ-Qpid-1-P>
+ <VQ-Qpid-2-P>-n VQ-Qpid-2-P -d1H -s [1000] -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=true messageSize=256 -o $QPID_WORK/results</VQ-Qpid-2-P>
+ <!-- Setting sample to 3,000,000 will result in a log entry every 10 minutes so should have 144 data points for the run. -->
+ <VQ-Qpid-3-P>-n VQ-Qpid-3-P -s [100000] -d 24H -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=true rate=10000 messageSize=256 commitBatchSize=100 transacted=true -o $QPID_WORK/results batchSize=100000</VQ-Qpid-3-P>
+ <VQ-Qpid-4-P>-n VQ-Qpid-4-P -s [100000] -d 24H -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=true rate=10000 messageSize=256 -o $QPID_WORK/results batchSize=100000</VQ-Qpid-4-P>
+
+ <!-- P2P Scalability Tests. -->
+ <!-- 1500 Total, 1P-1Q-1C -->
+ <PQ-Qpid-1-P>-n PQ-Qpid-1-P -d10M -s [1000] -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=true transacted=true commitBatchSize=100 messageSize=256 -o $QPID_WORK/results</PQ-Qpid-1-P>
+ <PQ-Qpid-2-P>-n PQ-Qpid-2-P -d10M -s [100] -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=true messageSize=256 -o $QPID_WORK/results</PQ-Qpid-2-P>
+
+ <!-- 150 Messages * 10 Brokers = 15,000 Total, 10P-1Q-10C -->
+ <PQ-Qpid-3-P>-n PQ-Qpid-3-P -d10M -s [1000] -c[10] -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=true messageSize=256 destinationName=ping transacted=true commitBatchSize=100 -o $QPID_WORK/results</PQ-Qpid-3-P>
+ <PQ-Qpid-4-P>-n PQ-Qpid-4-P -d10M -s [100] -c[10] -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=true messageSize=256 destinationName=ping -o $QPID_WORK/results</PQ-Qpid-4-P>
+
+ <!-- 150 Messages * 10 Brokers = 15,000 Total, 10P-10Q-10C 10*(1P-1Q-1C) -->
+ <PQ-Qpid-5-P>-n PQ-Qpid-5-P -d10M -s [1000] -c[10] -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=true messageSize=256 transacted=true commitBatchSize=100 -o $QPID_WORK/results</PQ-Qpid-5-P>
+ <PQ-Qpid-6-P>-n PQ-Qpid-6-P -d10M -s [100] -c[10] -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=true messageSize=256 -o $QPID_WORK/results</PQ-Qpid-6-P>
+
+ <!-- 150 Messages * 10 Brokers = 15,000 Total, 10P-100Q-10C 10*(1P-10Q-1C) -->
+ <PQ-Qpid-7-P>-n PQ-Qpid-7-P -d10M -s [1000] -c[10] -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=true messageSize=256 batchSize=100 destinationsCount=10 transacted=true commitBatchSize=100 -o $QPID_WORK/results</PQ-Qpid-7-P>
+ <PQ-Qpid-8-P>-n PQ-Qpid-8-P -d10M -s [100] -c[10] -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=true messageSize=256 destinationsCount=10 -o $QPID_WORK/results rate=200</PQ-Qpid-8-P>
+
+ <!-- 15 Messages * 100 Brokers = 15,000 Total, 100P-100Q-100C 100*(1P-1Q-1C) -->
+ <PQ-Qpid-9-P>-n PQ-Qpid-9-P -d10M -s [1000] -c[100] -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=true messageSize=256 batchSize=50 transacted=true commitBatchSize=100 -o $QPID_WORK/results</PQ-Qpid-9-P>
+ <PQ-Qpid-10-P>-n PQ-Qpid-10-P -d10M -s [100] -c[100] -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=true messageSize=256 -o $QPID_WORK/results</PQ-Qpid-10-P>
+
+ <!-- 15 Messages * 100 Brokers = 15,000 Total, 100P-1000Q-100C 100*(1P-10Q-1C) -->
+ <PQ-Qpid-11-P>-n PQ-Qpid-11-P -d10M -s [100] -c[100] -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=true messageSize=256 destinationsCount=10 transacted=true commitBatchSize=100 -o $QPID_WORK/results</PQ-Qpid-11-P>
+ <PQ-Qpid-12-P>-n PQ-Qpid-12-P -d10M -s [100] -c[100] -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=true messageSize=256 destinationsCount=10 -o $QPID_WORK/results</PQ-Qpid-12-P>
+
+ <!-- 2 Messages * 1000 Brokers = 2,000 Total, 1000P-1000Q-1000C 1000*(1P-1Q-1C) -->
+ <!--PQ-Qpid-13-P>-n PQ-Qpid-13-P -d10M -s [1000] -c[1000] -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=true messageSize=256 transacted=true commitBatchSize=100 -o $QPID_WORK/results</PQ-Qpid-13-P>
+ <PQ-Qpid-14-P>-n PQ-Qpid-14-P -d10M -s [1000] -c[1000] -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=true messageSize=256 -o $QPID_WORK/results</PQ-Qpid-14-P-->
+
+ <!-- Increasing Message Payload Tests. -->
+ <!-- Topic Testing -->
+ <LT-Qpid-1-512b-P>-n LT-Qpid-1-512b-P -d10M -s [1000] -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=true pubsub=true messageSize=512 transacted=true commitBatchSize=100 -o $QPID_WORK/results</LT-Qpid-1-512b-P>
+ <LT-Qpid-2-512b-P>-n LT-Qpid-2-512b-P -d10M -s [100] -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=true pubsub=true messageSize=512 -o $QPID_WORK/results</LT-Qpid-2-512b-P>
+
+ <LT-Qpid-1-1K-P>-n LT-Qpid-1-1K-P -d10M -s [1000] -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=true pubsub=true commitBatchSize=100 transacted=true messageSize=1024 -o $QPID_WORK/results</LT-Qpid-1-1K-P>
+ <LT-Qpid-2-1K-P>-n LT-Qpid-2-1K-P -d10M -s [100] -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=true pubsub=true messageSize=1024 -o $QPID_WORK/results</LT-Qpid-2-1K-P>
+
+ <LT-Qpid-1-5K-P>-n LT-Qpid-1-5K-P -d10M -s [1000] -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=true pubsub=true messageSize=5120 transacted=true -o $QPID_WORK/results</LT-Qpid-1-5K-P>
+ <LT-Qpid-2-5K-P>-n LT-Qpid-2-5K-P -d10M -s [100] -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=true pubsub=true messageSize=5120 -o $QPID_WORK/results</LT-Qpid-2-5K-P>
+
+ <LT-Qpid-1-10K-P>-n LT-Qpid-1-10K-P -d10M -s [1000] -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=true pubsub=true commitBatchSize=100 messageSize=10240 transacted=true -o $QPID_WORK/results</LT-Qpid-1-10K-P>
+ <LT-Qpid-2-10K-P>-n LT-Qpid-2-10K-P -d10M -s [100] -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=true pubsub=true messageSize=10240 -o $QPID_WORK/results</LT-Qpid-2-10K-P>
+
+ <LT-Qpid-1-50K-P>-n LT-Qpid-1-50K-P -d10M -s [1000] -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=true pubsub=true messageSize=51200 commitBatchSize=100 transacted=true -o $QPID_WORK/results</LT-Qpid-1-50K-P>
+ <LT-Qpid-2-50K-P>-n LT-Qpid-2-50K-P -d10M -s [100] -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=true pubsub=true messageSize=51200 -o $QPID_WORK/results</LT-Qpid-2-50K-P>
+
+ <LT-Qpid-1-100K-P>-n LT-Qpid-1-100K-P -d10M -s [1000] -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=true pubsub=true commitBatchSize=100 messageSize=102400 transacted=true -o $QPID_WORK/results</LT-Qpid-1-100K-P>
+ <LT-Qpid-2-100K-P>-n LT-Qpid-2-100K-P -d10M -s [100] -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=true pubsub=true messageSize=102400 -o $QPID_WORK/results</LT-Qpid-2-100K-P>
+
+ <LT-Qpid-1-1M-P>-n LT-Qpid-1-1M-P -d10M -s [1000] -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=true pubsub=true commitBatchSize=100 messageSize=1048576 transacted=true -o $QPID_WORK/results</LT-Qpid-1-1M-P>
+ <LT-Qpid-2-1M-P>-n LT-Qpid-2-1M-P -d10M -s [100] -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=true pubsub=true messageSize=1048476 -o $QPID_WORK/results</LT-Qpid-2-1M-P>
+
+ <!-- Queue Testing -->
+ <LT-Qpid-3-512b-P>-n LT-Qpid-3-512b-P -d10M -s [1000] -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=true commitBatchSize=100 messageSize=512 transacted=true -o $QPID_WORK/results</LT-Qpid-3-512b-P>
+ <LT-Qpid-4-512b-P>-n LT-Qpid-4-512b-P -d10M -s [100] -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=true messageSize=512 -o $QPID_WORK/results</LT-Qpid-4-512b-P>
+
+ <LT-Qpid-3-1K-P>-n LT-Qpid-3-1K-P -d10M -s [1000] -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=true commitBatchSize=100 transacted=true messageSize=1024 -o $QPID_WORK/results</LT-Qpid-3-1K-P>
+ <LT-Qpid-4-1K-P>-n LT-Qpid-4-1K-P -d10M -s [100] -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=true messageSize=1024 -o $QPID_WORK/results</LT-Qpid-4-1K-P>
+
+ <LT-Qpid-3-5K-P>-n LT-Qpid-3-5K-P -d10M -s [1000] -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=true commitBatchSize=100 messageSize=5120 transacted=true -o $QPID_WORK/results</LT-Qpid-3-5K-P>
+ <LT-Qpid-4-5K-P>-n LT-Qpid-4-5K-P -d10M -s [100] -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=true messageSize=5120 -o $QPID_WORK/results</LT-Qpid-4-5K-P>
+
+ <LT-Qpid-3-10K-P>-n LT-Qpid-3-10K-P -d10M -s [1000] -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=true commitBatchSize=100 messageSize=10240 transacted=true -o $QPID_WORK/results</LT-Qpid-3-10K-P>
+ <LT-Qpid-4-10K-P>-n LT-Qpid-4-10K-P -d10M -s [100] -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=true messageSize=10240 -o $QPID_WORK/results</LT-Qpid-4-10K-P>
+
+ <LT-Qpid-3-50K-P>-n LT-Qpid-3-50K-P -d10M -s [1000] -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=true commitBatchSize=100 messageSize=51200 transacted=true -o $QPID_WORK/results</LT-Qpid-3-50K-P>
+ <LT-Qpid-4-50K-P>-n LT-Qpid-4-50K-P -d10M -s [100] -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=true messageSize=51200 -o $QPID_WORK/results</LT-Qpid-4-50K-P>
+
+ <LT-Qpid-3-100K-P>-n LT-Qpid-3-100K-P -d10M -s [1000] -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=true commitBatchSize=100 messageSize=102400 transacted=true -o $QPID_WORK/results</LT-Qpid-3-100K-P>
+ <LT-Qpid-4-100K-P>-n LT-Qpid-4-100K-P -d10M -s [100] -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=true messageSize=102400 -o $QPID_WORK/results</LT-Qpid-4-100K-P>
+
+ <LT-Qpid-3-1M-P>-n LT-Qpid-3-1M-P -d10M -s [1000] -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=true commitBatchSize=100 messageSize=1048576 transacted=true -o $QPID_WORK/results</LT-Qpid-3-1M-P>
+ <LT-Qpid-4-1M-P>-n LT-Qpid-4-1M-P -d10M -s [100] -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=true messageSize=1048576 -o $QPID_WORK/results</LT-Qpid-4-1M-P>
+
+ <!-- Failover Tests. -->
+ <!-- Transactional -->
+ <FT-Qpid-1-P>-n FT-Qpid-1-P -s [25000] -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=true messageSize=256 batchSize=10000 transacted=true broker="tcp://10.0.0.1:5001;tcp://10.0.0.2:5002" failBeforeSend=true -o $QPID_WORK/results</FT-Qpid-1-P>
+ <FT-Qpid-2-P>-n FT-Qpid-2-P -s [25000] -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=true messageSize=256 batchSize=10000 transacted=true broker="tcp://10.0.0.1:5001;tcp://10.0.0.2:5002" failAfterSend=true -o $QPID_WORK/results</FT-Qpid-2-P>
+ <FT-Qpid-3-P>-n FT-Qpid-3-P -s [25000] -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=true messageSize=256 batchSize=10000 transacted=true broker="tcp://10.0.0.1:5001;tcp://10.0.0.2:5002" failAfterCommit=true -o $QPID_WORK/results</FT-Qpid-3-P>
+
+ <!-- Non Transactional -->
+ <FT-Qpid-4-P>-n FT-Qpid-4-P -s [250] -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=true messageSize=256 broker="tcp://10.0.0.1:5001;tcp://10.0.0.2:5002" transacted=false failBeforeSend=true -o $QPID_WORK/results</FT-Qpid-4-P>
+ <FT-Qpid-5-P>-n FT-Qpid-5-P -s [250] -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=true messageSize=256 broker="tcp://10.0.0.1:5001;tcp://10.0.0.2:5002" transacted=false failAfterSend=true -o $QPID_WORK/results</FT-Qpid-5-P>
+
</commands>
</configuration>
diff --git a/qpid/java/perftests/src/main/java/org/apache/qpid/client/message/TestMessageFactory.java b/qpid/java/perftests/src/main/java/org/apache/qpid/client/message/TestMessageFactory.java
index c0f236b833..eeb4021f34 100644
--- a/qpid/java/perftests/src/main/java/org/apache/qpid/client/message/TestMessageFactory.java
+++ b/qpid/java/perftests/src/main/java/org/apache/qpid/client/message/TestMessageFactory.java
@@ -103,7 +103,7 @@ public class TestMessageFactory
{
StringBuffer buf = new StringBuffer(size);
int count = 0;
- while (count < size)
+ while (count <= (size - MESSAGE_DATA_BYTES.length()))
{
buf.append(MESSAGE_DATA_BYTES);
count += MESSAGE_DATA_BYTES.length();
diff --git a/qpid/java/perftests/src/main/java/org/apache/qpid/config/AbstractConfig.java b/qpid/java/perftests/src/main/java/org/apache/qpid/config/AbstractConfig.java
index 04381d66a0..14db74438f 100644
--- a/qpid/java/perftests/src/main/java/org/apache/qpid/config/AbstractConfig.java
+++ b/qpid/java/perftests/src/main/java/org/apache/qpid/config/AbstractConfig.java
@@ -49,7 +49,7 @@ public abstract class AbstractConfig
}
catch(NumberFormatException e)
{
- throw new RuntimeException(msg + ": " + i);
+ throw new RuntimeException(msg + ": " + i, e);
}
}
@@ -61,7 +61,7 @@ public abstract class AbstractConfig
}
catch(NumberFormatException e)
{
- throw new RuntimeException(msg + ": " + i);
+ throw new RuntimeException(msg + ": " + i, e);
}
}
diff --git a/qpid/java/perftests/src/main/java/org/apache/qpid/config/JBossConnectionFactoryInitialiser.java b/qpid/java/perftests/src/main/java/org/apache/qpid/config/JBossConnectionFactoryInitialiser.java
index 44285efd96..a0248a8f79 100644
--- a/qpid/java/perftests/src/main/java/org/apache/qpid/config/JBossConnectionFactoryInitialiser.java
+++ b/qpid/java/perftests/src/main/java/org/apache/qpid/config/JBossConnectionFactoryInitialiser.java
@@ -22,6 +22,7 @@ package org.apache.qpid.config;
import org.apache.qpid.config.ConnectionFactoryInitialiser;
import org.apache.qpid.config.ConnectorConfig;
+import org.apache.qpid.client.JMSAMQException;
import javax.jms.ConnectionFactory;
import javax.jms.JMSException;
@@ -63,11 +64,11 @@ public class JBossConnectionFactoryInitialiser implements ConnectionFactoryIniti
}
catch (NamingException e)
{
- throw new JMSException("Unable to lookup object: " + e);
+ throw new JMSAMQException("Unable to lookup object: " + e, e);
}
catch (Exception e)
{
- throw new JMSException("Error creating topic: " + e);
+ throw new JMSAMQException("Error creating topic: " + e, e);
}
}
diff --git a/qpid/java/perftests/src/main/java/org/apache/qpid/ping/PingDurableClient.java b/qpid/java/perftests/src/main/java/org/apache/qpid/ping/PingDurableClient.java
index 82e43e542f..0e832ef100 100644
--- a/qpid/java/perftests/src/main/java/org/apache/qpid/ping/PingDurableClient.java
+++ b/qpid/java/perftests/src/main/java/org/apache/qpid/ping/PingDurableClient.java
@@ -1,3 +1,4 @@
+/* Copyright Rupert Smith, 2005 to 2006, all rights reserved. */
/*
*
* Licensed to the Apache Software Foundation (ASF) under one
@@ -178,6 +179,7 @@ public class PingDurableClient extends PingPongProducer implements ExceptionList
// Run the test procedure.
int sent = pingProducer.send();
+ pingProducer.closeConnection();
pingProducer.waitForUser("Press return to begin receiving the pings.");
pingProducer.receive(sent);
@@ -302,6 +304,13 @@ public class PingDurableClient extends PingPongProducer implements ExceptionList
System.out.println("Messages sent: " + messagesSent + ", Messages Committed = " + messagesCommitted
+ ", Messages not Committed = " + messagesNotCommitted);
+
+
+ return messagesSent;
+ }
+
+ protected void closeConnection()
+ {
// Clean up the connection.
try
{
@@ -309,10 +318,11 @@ public class PingDurableClient extends PingPongProducer implements ExceptionList
}
catch (JMSException e)
{
+ log.debug("There was an error whilst closing the connection: " + e, e);
+ System.out.println("There was an error whilst closing the connection.");
+
// Ignore as did best could manage to clean up.
}
-
- return messagesSent;
}
protected void receive(int messagesSent) throws Exception
@@ -354,6 +364,32 @@ public class PingDurableClient extends PingPongProducer implements ExceptionList
}
}
+ // Ensure messages received are committed.
+ if (_transacted)
+ {
+ try
+ {
+ _consumerSession.commit();
+ System.out.println("Committed for all messages received.");
+ }
+ catch (JMSException e)
+ {
+ log.debug("Error during commit: " + e, e);
+ System.out.println("Error during commit.");
+ try
+ {
+ _consumerSession.rollback();
+ System.out.println("Rolled back on all messages received.");
+ }
+ catch (JMSException e2)
+ {
+ log.debug("Error during rollback: " + e, e);
+ System.out.println("Error on roll back of all messages received.");
+ }
+
+ }
+ }
+
log.debug("messagesReceived = " + messagesReceived);
System.out.println("Messages received: " + messagesReceived);
diff --git a/qpid/java/perftests/src/main/java/org/apache/qpid/ping/PingSendOnlyClient.java b/qpid/java/perftests/src/main/java/org/apache/qpid/ping/PingSendOnlyClient.java
new file mode 100644
index 0000000000..7cf5e4516f
--- /dev/null
+++ b/qpid/java/perftests/src/main/java/org/apache/qpid/ping/PingSendOnlyClient.java
@@ -0,0 +1,57 @@
+/* Copyright Rupert Smith, 2005 to 2006, all rights reserved. */
+package org.apache.qpid.ping;
+
+import java.util.Properties;
+
+import org.apache.log4j.Logger;
+
+import org.apache.qpid.util.CommandLineParser;
+
+/**
+ * <p><table id="crc"><caption>CRC Card</caption>
+ * <tr><th> Responsibilities <th> Collaborations
+ * </table>
+ */
+public class PingSendOnlyClient extends PingDurableClient
+{
+ private static final Logger log = Logger.getLogger(PingSendOnlyClient.class);
+
+ public PingSendOnlyClient(Properties overrides) throws Exception
+ {
+ super(overrides);
+ }
+
+ /**
+ * Starts the ping/wait/receive process.
+ *
+ * @param args The command line arguments.
+ */
+ public static void main(String[] args)
+ {
+ 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[][] {}));
+ PingDurableClient pingProducer = new PingSendOnlyClient(options);
+
+ // Create a shutdown hook to terminate the ping-pong producer.
+ Runtime.getRuntime().addShutdownHook(pingProducer.getShutdownHook());
+
+ // Ensure that the ping pong producer is registered to listen for exceptions on the connection too.
+ // pingProducer.getConnection().setExceptionListener(pingProducer);
+
+ // Run the test procedure.
+ int sent = pingProducer.send();
+ pingProducer.waitForUser("Press return to close connection and quit.");
+ pingProducer.closeConnection();
+
+ System.exit(0);
+ }
+ catch (Exception e)
+ {
+ System.err.println(e.getMessage());
+ log.error("Top level handler caught execption.", e);
+ System.exit(1);
+ }
+ }
+}
diff --git a/qpid/java/perftests/src/main/java/org/apache/qpid/requestreply/PingPongProducer.java b/qpid/java/perftests/src/main/java/org/apache/qpid/requestreply/PingPongProducer.java
index 913685bca2..ecaf27167f 100644
--- a/qpid/java/perftests/src/main/java/org/apache/qpid/requestreply/PingPongProducer.java
+++ b/qpid/java/perftests/src/main/java/org/apache/qpid/requestreply/PingPongProducer.java
@@ -116,7 +116,7 @@ import uk.co.thebadgerset.junit.extensions.util.ParsedProperties;
* by the PPP that it is atteched to.
*
* @todo Use read/write lock in the onmessage, not for reading writing but to make use of a shared and exlcusive lock pair.
- * Obtian read lock on all messages, before decrementing the message count. At the end of the on message method add a
+ * Obtain read lock on all messages, before decrementing the message count. At the end of the on message method add a
* block that obtains the write lock for the very last message, releases any waiting producer. Means that the last
* message waits until all other messages have been handled before releasing producers but allows messages to be
* processed concurrently, unlike the current synchronized block.
@@ -725,6 +725,8 @@ public class PingPongProducer implements Runnable, MessageListener, ExceptionLis
log.debug("public void createReplyConsumers(Collection<Destination> destinations = " + destinations
+ ", String selector = " + selector + "): called");
+ log.debug("Creating " + destinations.size() + " reply consumers.");
+
for (Destination destination : destinations)
{
// Create a consumer for the destination and set this pinger to listen to its messages.
@@ -732,6 +734,8 @@ public class PingPongProducer implements Runnable, MessageListener, ExceptionLis
_consumerSession.createConsumer(destination, PREFETCH_DEFAULT, NO_LOCAL_DEFAULT, EXCLUSIVE_DEFAULT,
selector);
_consumer.setMessageListener(this);
+
+ log.debug("Set this to listen to replies sent to destination: " + destination);
}
}
@@ -743,13 +747,13 @@ public class PingPongProducer implements Runnable, MessageListener, ExceptionLis
*/
public void onMessage(Message message)
{
- log.debug("public void onMessage(Message message): called");
+ // log.debug("public void onMessage(Message message): called");
try
{
// Extract the messages correlation id.
String correlationID = message.getJMSCorrelationID();
- log.debug("correlationID = " + correlationID);
+ // log.debug("correlationID = " + correlationID);
// Countdown on the traffic light if there is one for the matching correlation id.
PerCorrelationId perCorrelationId = perCorrelationIds.get(correlationID);
@@ -761,7 +765,7 @@ public class PingPongProducer implements Runnable, MessageListener, ExceptionLis
// Restart the timeout timer on every message.
perCorrelationId.timeOutStart = System.nanoTime();
- log.debug("Reply was expected, decrementing the latch for the id, " + correlationID);
+ // log.debug("Reply was expected, decrementing the latch for the id, " + correlationID);
// Decrement the countdown latch. Before this point, it is possible that two threads might enter this
// method simultanesouly with the same correlation id. Decrementing the latch in a synchronized block
@@ -776,8 +780,8 @@ public class PingPongProducer implements Runnable, MessageListener, ExceptionLis
trueCount = trafficLight.getCount();
remainingCount = trueCount - 1;
- log.debug("remainingCount = " + remainingCount);
- log.debug("trueCount = " + trueCount);
+ // log.debug("remainingCount = " + remainingCount);
+ // log.debug("trueCount = " + trueCount);
// Commit on transaction batch size boundaries. At this point in time the waiting producer remains
// blocked, even on the last message.
@@ -806,23 +810,23 @@ public class PingPongProducer implements Runnable, MessageListener, ExceptionLis
}
// Print out ping times for every message in verbose mode only.
- if (_verbose)
+ /*if (_verbose)
{
Long timestamp = message.getLongProperty(MESSAGE_TIMESTAMP_PROPNAME);
if (timestamp != null)
{
long diff = System.nanoTime() - timestamp;
- log.trace("Time for round trip (nanos): " + diff);
+ //log.trace("Time for round trip (nanos): " + diff);
}
- }
+ }*/
}
catch (JMSException e)
{
log.warn("There was a JMSException: " + e.getMessage(), e);
}
- log.debug("public void onMessage(Message message): ending");
+ // log.debug("public void onMessage(Message message): ending");
}
/**
@@ -955,16 +959,16 @@ public class PingPongProducer implements Runnable, MessageListener, ExceptionLis
committed = false;
// Re-timestamp the message.
- message.setLongProperty(MESSAGE_TIMESTAMP_PROPNAME, System.nanoTime());
+ // message.setLongProperty(MESSAGE_TIMESTAMP_PROPNAME, System.nanoTime());
// Send the message, passing in the message count.
committed = sendMessage(i, message);
// Spew out per message timings on every message sonly in verbose mode.
- if (_verbose)
+ /*if (_verbose)
{
log.info(timestampFormatter.format(new Date()) + ": Pinged at with correlation id, " + messageCorrelationId);
- }
+ }*/
}
// Call commit if the send loop finished before reaching a batch size boundary so there may still be uncommitted messages.
@@ -1003,7 +1007,7 @@ public class PingPongProducer implements Runnable, MessageListener, ExceptionLis
_failBeforeSend = false;
}
- log.trace("Failing Before Send");
+ // log.trace("Failing Before Send");
waitForUser(KILL_BROKER_PROMPT);
}
@@ -1176,6 +1180,7 @@ public class PingPongProducer implements Runnable, MessageListener, ExceptionLis
if (_connection != null)
{
_connection.close();
+ log.debug("Close connection.");
}
}
finally
@@ -1213,20 +1218,20 @@ public class PingPongProducer implements Runnable, MessageListener, ExceptionLis
*/
protected boolean commitTx(Session session) throws JMSException
{
- log.debug("protected void commitTx(Session session): called");
+ // log.debug("protected void commitTx(Session session): called");
boolean committed = false;
- log.trace("Batch time reached");
+ // log.trace("Batch time reached");
if (_failAfterSend)
{
- log.trace("Batch size reached");
+ // log.trace("Batch size reached");
if (_failOnce)
{
_failAfterSend = false;
}
- log.trace("Failing After Send");
+ // log.trace("Failing After Send");
waitForUser(KILL_BROKER_PROMPT);
}
@@ -1241,14 +1246,14 @@ public class PingPongProducer implements Runnable, MessageListener, ExceptionLis
_failBeforeCommit = false;
}
- log.trace("Failing Before Commit");
+ // log.trace("Failing Before Commit");
waitForUser(KILL_BROKER_PROMPT);
}
- long l = System.nanoTime();
+ // long l = System.nanoTime();
session.commit();
committed = true;
- log.debug("Time taken to commit :" + ((System.nanoTime() - l) / 1000000f) + " ms");
+ // log.debug("Time taken to commit :" + ((System.nanoTime() - l) / 1000000f) + " ms");
if (_failAfterCommit)
{
@@ -1257,15 +1262,15 @@ public class PingPongProducer implements Runnable, MessageListener, ExceptionLis
_failAfterCommit = false;
}
- log.trace("Failing After Commit");
+ // log.trace("Failing After Commit");
waitForUser(KILL_BROKER_PROMPT);
}
- log.trace("Session Commited.");
+ // log.trace("Session Commited.");
}
catch (JMSException e)
{
- log.trace("JMSException on commit:" + e.getMessage(), e);
+ log.debug("JMSException on commit:" + e.getMessage(), e);
// Warn that the bounce back client is not available.
if (e.getLinkedException() instanceof AMQNoConsumersException)
@@ -1276,11 +1281,11 @@ public class PingPongProducer implements Runnable, MessageListener, ExceptionLis
try
{
session.rollback();
- log.trace("Message rolled back.");
+ log.debug("Message rolled back.");
}
catch (JMSException jmse)
{
- log.trace("JMSE on rollback:" + jmse.getMessage(), jmse);
+ log.debug("JMSE on rollback:" + jmse.getMessage(), jmse);
// Both commit and rollback failed. Throw the rollback exception.
throw jmse;
@@ -1296,7 +1301,7 @@ public class PingPongProducer implements Runnable, MessageListener, ExceptionLis
*
* @param prompt The prompt to display on the console.
*/
- protected void waitForUser(String prompt)
+ public void waitForUser(String prompt)
{
System.out.println(prompt);
diff --git a/qpid/java/perftests/src/main/java/org/apache/qpid/topic/Config.java b/qpid/java/perftests/src/main/java/org/apache/qpid/topic/Config.java
index 342b28ca17..d5c0979399 100644
--- a/qpid/java/perftests/src/main/java/org/apache/qpid/topic/Config.java
+++ b/qpid/java/perftests/src/main/java/org/apache/qpid/topic/Config.java
@@ -221,7 +221,7 @@ public class Config extends AbstractConfig implements ConnectorConfig
}
catch(NumberFormatException e)
{
- throw new RuntimeException("Bad port number: " + value);
+ throw new RuntimeException("Bad port number: " + value, e);
}
}
else if("-payload".equalsIgnoreCase(key))
diff --git a/qpid/java/perftests/src/test/java/org/apache/qpid/ping/PingAsyncTestPerf.java b/qpid/java/perftests/src/test/java/org/apache/qpid/ping/PingAsyncTestPerf.java
index 3b8e670f8f..6c7f22c19a 100644
--- a/qpid/java/perftests/src/test/java/org/apache/qpid/ping/PingAsyncTestPerf.java
+++ b/qpid/java/perftests/src/test/java/org/apache/qpid/ping/PingAsyncTestPerf.java
@@ -133,12 +133,13 @@ public class PingAsyncTestPerf extends PingTestPerf implements TimingControllerA
*/
public void testAsyncPingOk(int numPings) throws Exception
{
- _logger.debug("public void testAsyncPingOk(int numPings): called");
+ // _logger.debug("public void testAsyncPingOk(int numPings): called");
// Ensure that at least one ping was requeusted.
if (numPings == 0)
{
_logger.error("Number of pings requested was zero.");
+ fail("Number of pings requested was zero.");
}
// Get the per thread test setup to run the test through.
@@ -147,8 +148,8 @@ public class PingAsyncTestPerf extends PingTestPerf implements TimingControllerA
// Advance the correlation id of messages to send, to make it unique for this run.
perThreadSetup._correlationId = Long.toString(corellationIdGenerator.incrementAndGet());
- String messageCorrelationId = perThreadSetup._correlationId;
- _logger.debug("messageCorrelationId = " + messageCorrelationId);
+ // String messageCorrelationId = perThreadSetup._correlationId;
+ // _logger.debug("messageCorrelationId = " + messageCorrelationId);
// Initialize the count and timing controller for the new correlation id.
PerCorrelationId perCorrelationId = new PerCorrelationId();
@@ -246,9 +247,9 @@ public class PingAsyncTestPerf extends PingTestPerf implements TimingControllerA
// Extract the correlation id from the message.
String correlationId = message.getJMSCorrelationID();
- _logger.debug("public void onMessage(Message message, int remainingCount = " + remainingCount
+ /*_logger.debug("public void onMessage(Message message, int remainingCount = " + remainingCount
+ "): called on batch boundary for message id: " + correlationId + " with thread id: "
- + Thread.currentThread().getId());
+ + Thread.currentThread().getId());*/
// Get the details for the correlation id and check that they are not null. They can become null
// if a test times out.
diff --git a/qpid/java/systests/src/main/java/org/apache/qpid/server/AMQBrokerManagerMBeanTest.java b/qpid/java/systests/src/main/java/org/apache/qpid/server/AMQBrokerManagerMBeanTest.java
index 7c14de23a6..20de0d5df0 100644
--- a/qpid/java/systests/src/main/java/org/apache/qpid/server/AMQBrokerManagerMBeanTest.java
+++ b/qpid/java/systests/src/main/java/org/apache/qpid/server/AMQBrokerManagerMBeanTest.java
@@ -44,9 +44,9 @@ public class AMQBrokerManagerMBeanTest extends TestCase
VirtualHost vHost = ApplicationRegistry.getInstance().getVirtualHostRegistry().getVirtualHost("test");
ManagedBroker mbean = new AMQBrokerManagerMBean((VirtualHost.VirtualHostMBean)vHost.getManagedObject());
- mbean.createNewExchange(exchange1,"direct",false, false);
- mbean.createNewExchange(exchange2,"topic",false, false);
- mbean.createNewExchange(exchange3,"headers",false, false);
+ mbean.createNewExchange(exchange1,"direct",false);
+ mbean.createNewExchange(exchange2,"topic",false);
+ mbean.createNewExchange(exchange3,"headers",false);
assertTrue(_exchangeRegistry.getExchange(new AMQShortString(exchange1)) != null);
assertTrue(_exchangeRegistry.getExchange(new AMQShortString(exchange2)) != null);
@@ -70,7 +70,7 @@ public class AMQBrokerManagerMBeanTest extends TestCase
assertTrue(_queueRegistry.getQueue(new AMQShortString(queueName)) == null);
- mbean.createNewQueue(queueName, "test", false, true);
+ mbean.createNewQueue(queueName, "test", false);
assertTrue(_queueRegistry.getQueue(new AMQShortString(queueName)) != null);
mbean.deleteQueue(queueName);
diff --git a/qpid/java/systests/src/main/java/org/apache/qpid/server/failure/HeapExhaustion.java b/qpid/java/systests/src/main/java/org/apache/qpid/server/failure/HeapExhaustion.java
new file mode 100644
index 0000000000..52eb5414ff
--- /dev/null
+++ b/qpid/java/systests/src/main/java/org/apache/qpid/server/failure/HeapExhaustion.java
@@ -0,0 +1,208 @@
+package org.apache.qpid.server.failure;
+
+import junit.framework.TestCase;
+import org.apache.qpid.testutil.QpidClientConnection;
+import org.apache.qpid.client.failover.FailoverException;
+import org.apache.qpid.AMQException;
+import org.apache.qpid.protocol.AMQConstant;
+import org.apache.log4j.Logger;
+
+import javax.jms.JMSException;
+import java.io.IOException;
+
+
+/** Test Case provided by client Non-functional Test NF101: heap exhaustion behaviour */
+public class HeapExhaustion extends TestCase
+{
+ private static final Logger _logger = Logger.getLogger(HeapExhaustion.class);
+
+ protected QpidClientConnection conn;
+ protected final String BROKER = "localhost";
+ protected final String vhost = "/test";
+ protected final String queue = "direct://amq.direct//queue";
+
+ protected String hundredK;
+ protected String megabyte;
+
+ protected String generatePayloadOfSize(Integer numBytes)
+ {
+ return new String(new byte[numBytes]);
+ }
+
+ protected void setUp() throws Exception
+ {
+ conn = new QpidClientConnection(BROKER);
+ conn.setVirtualHost(vhost);
+
+ conn.connect();
+ // clear queue
+ _logger.debug("setup: clearing test queue");
+ conn.consume(queue, 2000);
+
+ hundredK = generatePayloadOfSize(1024 * 100);
+ megabyte = generatePayloadOfSize(1024 * 1024);
+ }
+
+ protected void tearDown() throws Exception
+ {
+ conn.disconnect();
+ }
+
+
+ /**
+ * PUT at maximum rate (although we commit after each PUT) until failure
+ *
+ * @throws Exception on error
+ */
+ public void testUntilFailure() throws Exception
+ {
+ int copies = 0;
+ int total = 0;
+ String payload = hundredK;
+ int size = payload.getBytes().length;
+ while (true)
+ {
+ conn.put(queue, payload, 1);
+ copies++;
+ total += size;
+ _logger.info("put copy " + copies + " OK for total bytes: " + total);
+ }
+ }
+
+ /**
+ * PUT at lower rate (5 per second) until failure
+ *
+ * @throws Exception on error
+ */
+ public void testUntilFailureWithDelays() throws Exception
+ {
+ int copies = 0;
+ int total = 0;
+ String payload = hundredK;
+ int size = payload.getBytes().length;
+ while (true)
+ {
+ conn.put(queue, payload, 1);
+ copies++;
+ total += size;
+ _logger.debug("put copy " + copies + " OK for total bytes: " + total);
+ Thread.sleep(200);
+ }
+ }
+
+ public static void noDelay()
+ {
+ HeapExhaustion he = new HeapExhaustion();
+
+ try
+ {
+ he.setUp();
+ }
+ catch (Exception e)
+ {
+ _logger.info("Unable to connect");
+ System.exit(0);
+ }
+
+ try
+ {
+ _logger.info("Running testUntilFailure");
+ try
+ {
+ he.testUntilFailure();
+ }
+ catch (FailoverException fe)
+ {
+ _logger.error("Caught failover:" + fe);
+ }
+ _logger.info("Finishing Connection ");
+
+ try
+ {
+ he.tearDown();
+ }
+ catch (JMSException jmse)
+ {
+ if (((AMQException) jmse.getLinkedException()).getErrorCode() == AMQConstant.REQUEST_TIMEOUT)
+ {
+ _logger.info("Successful test of testUntilFailure");
+ }
+ else
+ {
+ _logger.error("Test Failed due to:" + jmse);
+ }
+ }
+ }
+ catch (Exception e)
+ {
+ _logger.error("Test Failed due to:" + e);
+ }
+ }
+
+ public static void withDelay()
+ {
+ HeapExhaustion he = new HeapExhaustion();
+
+ try
+ {
+ he.setUp();
+ }
+ catch (Exception e)
+ {
+ _logger.info("Unable to connect");
+ System.exit(0);
+ }
+
+ try
+ {
+ _logger.info("Running testUntilFailure");
+ try
+ {
+ he.testUntilFailureWithDelays();
+ }
+ catch (FailoverException fe)
+ {
+ _logger.error("Caught failover:" + fe);
+ }
+ _logger.info("Finishing Connection ");
+
+ try
+ {
+ he.tearDown();
+ }
+ catch (JMSException jmse)
+ {
+ if (((AMQException) jmse.getLinkedException()).getErrorCode() == AMQConstant.REQUEST_TIMEOUT)
+ {
+ _logger.info("Successful test of testUntilFailure");
+ }
+ else
+ {
+ _logger.error("Test Failed due to:" + jmse);
+ }
+ }
+ }
+ catch (Exception e)
+ {
+ _logger.error("Test Failed due to:" + e);
+ }
+ }
+
+ public static void main(String args[])
+ {
+ noDelay();
+
+
+ try
+ {
+ System.out.println("Restart failed broker now to retest broker with delays in send.");
+ System.in.read();
+ }
+ catch (IOException e)
+ {
+ _logger.info("Continuing");
+ }
+
+ withDelay();
+ }
+}
diff --git a/qpid/java/systests/src/main/java/org/apache/qpid/server/queue/MockProtocolSession.java b/qpid/java/systests/src/main/java/org/apache/qpid/server/queue/MockProtocolSession.java
index 8795adbc55..0ad6502755 100644
--- a/qpid/java/systests/src/main/java/org/apache/qpid/server/queue/MockProtocolSession.java
+++ b/qpid/java/systests/src/main/java/org/apache/qpid/server/queue/MockProtocolSession.java
@@ -35,6 +35,7 @@ import org.apache.qpid.server.store.MessageStore;
import javax.security.sasl.SaslServer;
import java.util.HashMap;
import java.util.Map;
+import java.security.Principal;
/**
* A protocol session that can be used for testing purposes.
@@ -177,12 +178,12 @@ public class MockProtocolSession implements AMQProtocolSession
return ProtocolOutputConverterRegistry.getConverter(this);
}
- public void setAuthorizedID(String authorizedID)
+ public void setAuthorizedID(Principal authorizedID)
{
//To change body of implemented methods use File | Settings | File Templates.
}
- public String getAuthorizedID()
+ public Principal getAuthorizedID()
{
return null; //To change body of implemented methods use File | Settings | File Templates.
}
diff --git a/qpid/java/systests/src/main/java/org/apache/qpid/server/queue/PersistentTest.java b/qpid/java/systests/src/main/java/org/apache/qpid/server/queue/PersistentTest.java
new file mode 100644
index 0000000000..4ad10b68ff
--- /dev/null
+++ b/qpid/java/systests/src/main/java/org/apache/qpid/server/queue/PersistentTest.java
@@ -0,0 +1,276 @@
+/*
+ * 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.queue;
+
+import org.apache.qpid.client.AMQConnection;
+import org.apache.qpid.client.AMQSession;
+import org.apache.qpid.AMQException;
+import org.apache.qpid.AMQChannelClosedException;
+import org.apache.qpid.AMQConnectionClosedException;
+import org.apache.qpid.util.CommandLineParser;
+import org.apache.qpid.url.URLSyntaxException;
+import org.apache.log4j.Logger;
+
+import javax.jms.Session;
+import javax.jms.JMSException;
+import javax.jms.Queue;
+import javax.jms.MessageProducer;
+import javax.jms.TextMessage;
+import java.io.IOException;
+import java.util.Properties;
+
+public class PersistentTest
+{
+ private static final Logger _logger = Logger.getLogger(PersistentTest.class);
+
+
+ private static final String QUEUE = "direct://amq.direct//PersistentTest-Queue2?durable='true',exclusive='true'";
+
+ protected AMQConnection _connection;
+
+ protected Session _session;
+
+ protected Queue _queue;
+ private Properties properties;
+
+ private String _brokerDetails;
+ private String _username;
+ private String _password;
+ private String _virtualpath;
+
+ public PersistentTest(Properties overrides)
+ {
+ properties = new Properties(defaults);
+ properties.putAll(overrides);
+
+ _brokerDetails = properties.getProperty(BROKER_PROPNAME);
+ _username = properties.getProperty(USERNAME_PROPNAME);
+ _password = properties.getProperty(PASSWORD_PROPNAME);
+ _virtualpath = properties.getProperty(VIRTUAL_HOST_PROPNAME);
+
+ createConnection();
+ }
+
+ protected void createConnection()
+ {
+ try
+ {
+ _connection = new AMQConnection(_brokerDetails, _username, _password, "PersistentTest", _virtualpath);
+
+ _session = _connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
+
+ _connection.start();
+ }
+ catch (Exception e)
+ {
+ _logger.error("Unable to create test class due to:" + e.getMessage(), e);
+ System.exit(0);
+ }
+ }
+
+ public void test() throws AMQException, URLSyntaxException
+ {
+
+ //Create the Durable Queue
+ try
+ {
+ _session.createConsumer(_session.createQueue(QUEUE)).close();
+ }
+ catch (JMSException e)
+ {
+ _logger.error("Unable to create Queue due to:" + e.getMessage(), e);
+ System.exit(0);
+ }
+
+ try
+ {
+ if (testQueue())
+ {
+ // close connection
+ _connection.close();
+ // wait
+ System.out.println("Restart Broker Now");
+ try
+ {
+ System.in.read();
+ }
+ catch (IOException e)
+ {
+ //
+ }
+ finally
+ {
+ System.out.println("Continuing....");
+ }
+
+ //Test queue is still there.
+ AMQConnection connection = new AMQConnection(_brokerDetails, _username, _password, "DifferentClientID", _virtualpath);
+
+ AMQSession session = (AMQSession) connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
+
+ try
+ {
+ session.createConsumer(session.createQueue(QUEUE));
+ _logger.error("Create consumer succeeded." +
+ " This shouldn't be allowed as this means the queue didn't exist when it should");
+
+ connection.close();
+
+ exit();
+ }
+ catch (JMSException e)
+ {
+ try
+ {
+ connection.close();
+ }
+ catch (JMSException cce)
+ {
+ if (cce.getLinkedException() instanceof AMQConnectionClosedException)
+ {
+ _logger.error("Channel Close Bug still present QPID-432, should see an 'Error closing session'");
+ }
+ else
+ {
+ exit(cce);
+ }
+ }
+
+ if (e.getLinkedException() instanceof AMQChannelClosedException)
+ {
+ _logger.info("AMQChannelClosedException received as expected");
+ }
+ else
+ {
+ exit(e);
+ }
+ }
+ }
+ }
+ catch (JMSException e)
+ {
+ _logger.error("Unable to test Queue due to:" + e.getMessage(), e);
+ System.exit(0);
+ }
+ }
+
+ private void exit(JMSException e)
+ {
+ _logger.error("JMSException received:" + e.getMessage());
+ e.printStackTrace();
+ exit();
+ }
+
+ private void exit()
+ {
+ try
+ {
+ _connection.close();
+ }
+ catch (JMSException e)
+ {
+ //
+ }
+ System.exit(0);
+ }
+
+ private boolean testQueue() throws JMSException
+ {
+ String TEST_TEXT = "init";
+
+ //Create a new session to send producer
+ Session session = _connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
+
+ Queue q = session.createQueue(QUEUE);
+ MessageProducer producer = session.createProducer(q);
+
+ producer.send(session.createTextMessage(TEST_TEXT));
+
+ //create a new consumer on the original session
+ TextMessage m = (TextMessage) _session.createConsumer(q).receive();
+
+
+ if ((m != null) && m.getText().equals(TEST_TEXT))
+ {
+ return true;
+ }
+ else
+ {
+ _logger.error("Incorrect values returned from Queue Test:" + m);
+ System.exit(0);
+ return false;
+ }
+ }
+
+ /** Holds the name of the property to get the test broker url from. */
+ public static final String BROKER_PROPNAME = "broker";
+
+ /** Holds the default broker url for the test. */
+ public static final String BROKER_DEFAULT = "tcp://localhost:5672";
+
+ /** Holds the name of the property to get the test broker virtual path. */
+ public static final String VIRTUAL_HOST_PROPNAME = "virtualHost";
+
+ /** Holds the default virtual path for the test. */
+ public static final String VIRTUAL_HOST_DEFAULT = "";
+
+ /** Holds the name of the property to get the broker access username from. */
+ public static final String USERNAME_PROPNAME = "username";
+
+ /** Holds the default broker log on username. */
+ public static final String USERNAME_DEFAULT = "guest";
+
+ /** Holds the name of the property to get the broker access password from. */
+ public static final String PASSWORD_PROPNAME = "password";
+
+ /** Holds the default broker log on password. */
+ public static final String PASSWORD_DEFAULT = "guest";
+
+ /** Holds the default configuration properties. */
+ public static Properties defaults = new Properties();
+
+ static
+ {
+ defaults.setProperty(BROKER_PROPNAME, BROKER_DEFAULT);
+ defaults.setProperty(USERNAME_PROPNAME, USERNAME_DEFAULT);
+ defaults.setProperty(PASSWORD_PROPNAME, PASSWORD_DEFAULT);
+ defaults.setProperty(VIRTUAL_HOST_PROPNAME, VIRTUAL_HOST_DEFAULT);
+ }
+
+ public static void main(String[] args)
+ {
+ PersistentTest test;
+
+ Properties options = CommandLineParser.processCommandLine(args, new CommandLineParser(new String[][]{}));
+
+
+ test = new PersistentTest(options);
+ try
+ {
+ test.test();
+ System.out.println("Test was successfull.");
+ }
+ catch (Exception e)
+ {
+ _logger.error("Unable to test due to:" + e.getMessage(), e);
+ }
+ }
+}
diff --git a/qpid/java/systests/src/main/java/org/apache/qpid/testutil/QpidClientConnection.java b/qpid/java/systests/src/main/java/org/apache/qpid/testutil/QpidClientConnection.java
new file mode 100644
index 0000000000..80773c102d
--- /dev/null
+++ b/qpid/java/systests/src/main/java/org/apache/qpid/testutil/QpidClientConnection.java
@@ -0,0 +1,268 @@
+package org.apache.qpid.testutil;
+
+import org.apache.qpid.client.AMQConnectionFactory;
+import org.apache.qpid.client.AMQConnectionURL;
+import org.apache.qpid.client.AMQConnection;
+import org.apache.qpid.client.JMSAMQException;
+import org.apache.qpid.url.URLSyntaxException;
+import org.apache.log4j.Logger;
+
+import javax.jms.ExceptionListener;
+import javax.jms.Session;
+import javax.jms.Connection;
+import javax.jms.JMSException;
+import javax.jms.Queue;
+import javax.jms.MessageProducer;
+import javax.jms.Message;
+import javax.jms.MessageConsumer;
+import javax.jms.TextMessage;
+
+public class QpidClientConnection implements ExceptionListener
+{
+
+ private static final Logger _logger = Logger.getLogger(QpidClientConnection.class);
+
+ private boolean transacted = true;
+ private int ackMode = Session.CLIENT_ACKNOWLEDGE;
+ private Connection connection;
+
+ private String virtualHost;
+ private String brokerlist;
+ private int prefetch;
+ protected Session session;
+ protected boolean connected;
+
+ public QpidClientConnection(String broker)
+ {
+ super();
+ setVirtualHost("/test");
+ setBrokerList(broker);
+ setPrefetch(5000);
+ }
+
+
+ public void connect() throws JMSException
+ {
+ if (!connected)
+ {
+ /*
+ * amqp://[user:pass@][clientid]/virtualhost?
+ * brokerlist='[transport://]host[:port][?option='value'[&option='value']];'
+ * [&failover='method[?option='value'[&option='value']]']
+ * [&option='value']"
+ */
+ String brokerUrl = "amqp://guest:guest@" + virtualHost + "?brokerlist='" + brokerlist + "'";
+ try
+ {
+ AMQConnectionFactory factory = new AMQConnectionFactory(new AMQConnectionURL(brokerUrl));
+ _logger.info("connecting to Qpid :" + brokerUrl);
+ connection = factory.createConnection();
+
+ // register exception listener
+ connection.setExceptionListener(this);
+
+ session = ((AMQConnection) connection).createSession(transacted, ackMode, prefetch);
+
+
+ _logger.info("starting connection");
+ connection.start();
+
+ connected = true;
+ }
+ catch (URLSyntaxException e)
+ {
+ throw new JMSAMQException("URL syntax error in [" + brokerUrl + "]: " + e.getMessage(), e);
+ }
+ }
+ }
+
+ public void disconnect() throws JMSException
+ {
+ if (connected)
+ {
+ session.commit();
+ session.close();
+ connection.close();
+ connected = false;
+ _logger.info("disconnected");
+ }
+ }
+
+ public void disconnectWithoutCommit() throws JMSException
+ {
+ if (connected)
+ {
+ session.close();
+ connection.close();
+ connected = false;
+ _logger.info("disconnected without commit");
+ }
+ }
+
+ public String getBrokerList()
+ {
+ return brokerlist;
+ }
+
+ public void setBrokerList(String brokerlist)
+ {
+ this.brokerlist = brokerlist;
+ }
+
+ public String getVirtualHost()
+ {
+ return virtualHost;
+ }
+
+ public void setVirtualHost(String virtualHost)
+ {
+ this.virtualHost = virtualHost;
+ }
+
+ public void setPrefetch(int prefetch)
+ {
+ this.prefetch = prefetch;
+ }
+
+
+ /** override as necessary */
+ public void onException(JMSException exception)
+ {
+ _logger.info("ExceptionListener event: error " + exception.getErrorCode() + ", message: " + exception.getMessage());
+ }
+
+ public boolean isConnected()
+ {
+ return connected;
+ }
+
+ public Session getSession()
+ {
+ return session;
+ }
+
+ /**
+ * Put a String as a text messages, repeat n times. A null payload will result in a null message.
+ *
+ * @param queueName The queue name to put to
+ * @param payload the content of the payload
+ * @param copies the number of messages to put
+ *
+ * @throws javax.jms.JMSException any exception that occurs
+ */
+ public void put(String queueName, String payload, int copies) throws JMSException
+ {
+ if (!connected)
+ {
+ connect();
+ }
+
+ _logger.info("putting to queue " + queueName);
+ Queue queue = session.createQueue(queueName);
+
+ final MessageProducer sender = session.createProducer(queue);
+
+ for (int i = 0; i < copies; i++)
+ {
+ Message m = session.createTextMessage(payload + i);
+ m.setIntProperty("index", i + 1);
+ sender.send(m);
+ }
+
+ session.commit();
+ sender.close();
+ _logger.info("put " + copies + " copies");
+ }
+
+ /**
+ * GET the top message on a queue. Consumes the message. Accepts timeout value.
+ *
+ * @param queueName The quename to get from
+ * @param readTimeout The timeout to use
+ *
+ * @return the content of the text message if any
+ *
+ * @throws javax.jms.JMSException any exception that occured
+ */
+ public Message getNextMessage(String queueName, long readTimeout) throws JMSException
+ {
+ if (!connected)
+ {
+ connect();
+ }
+
+ Queue queue = session.createQueue(queueName);
+
+ final MessageConsumer consumer = session.createConsumer(queue);
+
+ Message message = consumer.receive(readTimeout);
+ session.commit();
+ consumer.close();
+
+ Message result;
+
+ // all messages we consume should be TextMessages
+ if (message instanceof TextMessage)
+ {
+ result = ((TextMessage) message);
+ }
+ else if (null == message)
+ {
+ result = null;
+ }
+ else
+ {
+ _logger.info("warning: received non-text message");
+ result = message;
+ }
+
+ return result;
+ }
+
+ /**
+ * GET the top message on a queue. Consumes the message.
+ *
+ * @param queueName The Queuename to get from
+ *
+ * @return The string content of the text message, if any received
+ *
+ * @throws javax.jms.JMSException any exception that occurs
+ */
+ public Message getNextMessage(String queueName) throws JMSException
+ {
+ return getNextMessage(queueName, 0);
+ }
+
+ /**
+ * Completely clears a queue. For readTimeout behaviour see Javadocs for javax.jms.MessageConsumer.
+ *
+ * @param queueName The Queue name to consume from
+ * @param readTimeout The timeout for each consume
+ *
+ * @throws javax.jms.JMSException Any exception that occurs during the consume
+ * @throws InterruptedException If the consume thread was interrupted during a consume.
+ */
+ public void consume(String queueName, int readTimeout) throws JMSException, InterruptedException
+ {
+ if (!connected)
+ {
+ connect();
+ }
+
+ _logger.info("consuming queue " + queueName);
+ Queue queue = session.createQueue(queueName);
+
+ final MessageConsumer consumer = session.createConsumer(queue);
+ int messagesReceived = 0;
+
+ _logger.info("consuming...");
+ while ((consumer.receive(readTimeout)) != null)
+ {
+ messagesReceived++;
+ }
+
+ session.commit();
+ consumer.close();
+ _logger.info("consumed: " + messagesReceived);
+ }
+}