Initial check-in of new Apache.NMS.XMS provider implementation.
Big thanks to Stéphane Ramet for the implementation!
Fixes [AMQNET-185]. (See https://issues.apache.org/jira/browse/AMQNET-185)
diff --git a/Apache.NMS.XMS.Test.nunit b/Apache.NMS.XMS.Test.nunit
new file mode 100644
index 0000000..54bccec
--- /dev/null
+++ b/Apache.NMS.XMS.Test.nunit
@@ -0,0 +1,7 @@
+<NUnitProject>
+ <Settings activeconfig="Default" />
+ <Config name="Default" binpathtype="Auto">
+ <!--<assembly path="Apache.NMS.Test.dll" />-->
+ <assembly path="Apache.NMS.XMS.Test.dll" />
+ </Config>
+</NUnitProject>
\ No newline at end of file
diff --git a/LICENSE.txt b/LICENSE.txt
new file mode 100644
index 0000000..6f22588
--- /dev/null
+++ b/LICENSE.txt
@@ -0,0 +1,764 @@
+
+ Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
+
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+ 1. Definitions.
+
+ "License" shall mean the terms and conditions for use, reproduction,
+ and distribution as defined by Sections 1 through 9 of this document.
+
+ "Licensor" shall mean the copyright owner or entity authorized by
+ the copyright owner that is granting the License.
+
+ "Legal Entity" shall mean the union of the acting entity and all
+ other entities that control, are controlled by, or are under common
+ control with that entity. For the purposes of this definition,
+ "control" means (i) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ outstanding shares, or (iii) beneficial ownership of such entity.
+
+ "You" (or "Your") shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+
+ "Source" form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
+
+ "Object" form shall mean any form resulting from mechanical
+ transformation or translation of a Source form, including but
+ not limited to compiled object code, generated documentation,
+ and conversions to other media types.
+
+ "Work" shall mean the work of authorship, whether in Source or
+ Object form, made available under the License, as indicated by a
+ copyright notice that is included in or attached to the work
+ (an example is provided in the Appendix below).
+
+ "Derivative Works" shall mean any work, whether in Source or Object
+ form, that is based on (or derived from) the Work and for which the
+ editorial revisions, annotations, elaborations, or other modifications
+ represent, as a whole, an original work of authorship. For the purposes
+ of this License, Derivative Works shall not include works that remain
+ separable from, or merely link (or bind by name) to the interfaces of,
+ the Work and Derivative Works thereof.
+
+ "Contribution" shall mean any work of authorship, including
+ the original version of the Work and any modifications or additions
+ to that Work or Derivative Works thereof, that is intentionally
+ submitted to Licensor for inclusion in the Work by the copyright owner
+ or by an individual or Legal Entity authorized to submit on behalf of
+ the copyright owner. For the purposes of this definition, "submitted"
+ means any form of electronic, verbal, or written communication sent
+ to the Licensor or its representatives, including but not limited to
+ communication on electronic mailing lists, source code control systems,
+ and issue tracking systems that are managed by, or on behalf of, the
+ Licensor for the purpose of discussing and improving the Work, but
+ excluding communication that is conspicuously marked or otherwise
+ designated in writing by the copyright owner as "Not a Contribution."
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity
+ on behalf of whom a Contribution has been received by Licensor and
+ subsequently incorporated within the Work.
+
+ 2. Grant of Copyright License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ copyright license to reproduce, prepare Derivative Works of,
+ publicly display, publicly perform, sublicense, and distribute the
+ Work and such Derivative Works in Source or Object form.
+
+ 3. Grant of Patent License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ (except as stated in this section) patent license to make, have made,
+ use, offer to sell, sell, import, and otherwise transfer the Work,
+ where such license applies only to those patent claims licensable
+ by such Contributor that are necessarily infringed by their
+ Contribution(s) alone or by combination of their Contribution(s)
+ with the Work to which such Contribution(s) was submitted. If You
+ institute patent litigation against any entity (including a
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
+ or a Contribution incorporated within the Work constitutes direct
+ or contributory patent infringement, then any patent licenses
+ granted to You under this License for that Work shall terminate
+ as of the date such litigation is filed.
+
+ 4. Redistribution. You may reproduce and distribute copies of the
+ Work or Derivative Works thereof in any medium, with or without
+ modifications, and in Source or Object form, provided that You
+ meet the following conditions:
+
+ (a) You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works
+ that You distribute, all copyright, patent, trademark, and
+ attribution notices from the Source form of the Work,
+ excluding those notices that do not pertain to any part of
+ the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its
+ distribution, then any Derivative Works that You distribute must
+ include a readable copy of the attribution notices contained
+ within such NOTICE file, excluding those notices that do not
+ pertain to any part of the Derivative Works, in at least one
+ of the following places: within a NOTICE text file distributed
+ as part of the Derivative Works; within the Source form or
+ documentation, if provided along with the Derivative Works; or,
+ within a display generated by the Derivative Works, if and
+ wherever such third-party notices normally appear. The contents
+ of the NOTICE file are for informational purposes only and
+ do not modify the License. You may add Your own attribution
+ notices within Derivative Works that You distribute, alongside
+ or as an addendum to the NOTICE text from the Work, provided
+ that such additional attribution notices cannot be construed
+ as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and
+ may provide additional or different license terms and conditions
+ for use, reproduction, or distribution of Your modifications, or
+ for any such Derivative Works as a whole, provided Your use,
+ reproduction, and distribution of the Work otherwise complies with
+ the conditions stated in this License.
+
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
+ any Contribution intentionally submitted for inclusion in the Work
+ by You to the Licensor shall be under the terms and conditions of
+ this License, without any additional terms or conditions.
+ Notwithstanding the above, nothing herein shall supersede or modify
+ the terms of any separate license agreement you may have executed
+ with Licensor regarding such Contributions.
+
+ 6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor,
+ except as required for reasonable and customary use in describing the
+ origin of the Work and reproducing the content of the NOTICE file.
+
+ 7. Disclaimer of Warranty. Unless required by applicable law or
+ agreed to in writing, Licensor provides the Work (and each
+ Contributor provides its Contributions) on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied, including, without limitation, any warranties or conditions
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ PARTICULAR PURPOSE. You are solely responsible for determining the
+ appropriateness of using or redistributing the Work and assume any
+ risks associated with Your exercise of permissions under this License.
+
+ 8. Limitation of Liability. In no event and under no legal theory,
+ whether in tort (including negligence), contract, or otherwise,
+ unless required by applicable law (such as deliberate and grossly
+ negligent acts) or agreed to in writing, shall any Contributor be
+ liable to You for damages, including any direct, indirect, special,
+ incidental, or consequential damages of any character arising as a
+ result of this License or out of the use or inability to use the
+ Work (including but not limited to damages for loss of goodwill,
+ work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses), even if such Contributor
+ has been advised of the possibility of such damages.
+
+ 9. Accepting Warranty or Additional Liability. While redistributing
+ the Work or Derivative Works thereof, You may choose to offer,
+ and charge a fee for, acceptance of support, warranty, indemnity,
+ or other liability obligations and/or rights consistent with this
+ License. However, in accepting such obligations, You may act only
+ on Your own behalf and on Your sole responsibility, not on behalf
+ of any other Contributor, and only if You agree to indemnify,
+ defend, and hold each Contributor harmless for any liability
+ incurred by, or claims asserted against, such Contributor by reason
+ of your accepting any such warranty or additional liability.
+
+ END OF TERMS AND CONDITIONS
+
+ APPENDIX: How to apply the Apache License to your work.
+
+ To apply the Apache License to your work, attach the following
+ boilerplate notice, with the fields enclosed by brackets "[]"
+ replaced with your own identifying information. (Don't include
+ the brackets!) The text should be enclosed in the appropriate
+ comment syntax for the file format. We also recommend that a
+ file or class name and description of purpose be included on the
+ same "printed page" as the copyright notice for easier
+ identification within third-party archives.
+
+ Copyright [yyyy] [name of copyright owner]
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+
+APACHE ACTIVEMQ DEPENDENCIES:
+
+The Apache ActiveMQ message broker includes a number of dependencies, many
+of them optional, with separate copyright notices and license terms. Your
+use of the source code for the these subcomponents is subject to the terms
+and conditions of the following licenses.
+
+For the backport-util-concurrent library:
+
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "DTD/xhtml1-transitional.dtd">
+<html><head><title>Creative Commons Public Domain</title>
+
+<body>
+
+<p align="center"><em>Copyright-Only Dedication (based on United States law) or Public Domain Certification</em></p>
+
+ <p>The
+person or persons who have associated work with this document (the
+"Dedicator" or "Certifier") hereby either (a) certifies that, to the
+best of his knowledge, the work of authorship identified is in the
+public domain of the country from which the work is published, or (b)
+hereby dedicates whatever copyright the dedicators holds in the work of
+authorship identified below (the "Work") to the public domain. A
+certifier, morever, dedicates any copyright interest he may have in the
+associated work, and for these purposes, is described as a "dedicator"
+below.</p>
+
+ <p>A certifier has taken reasonable steps to verify
+the copyright status of this work. Certifier recognizes that his good
+faith efforts may not shield him from liability if in fact the work
+certified is not in the public domain.</p>
+
+ <p>Dedicator makes
+this dedication for the benefit of the public at large and to the
+detriment of the Dedicator's heirs and successors. Dedicator intends
+this dedication to be an overt act of relinquishment in perpetuity of
+all present and future rights under copyright law, whether vested or
+contingent, in the Work. Dedicator understands that such relinquishment
+of all rights includes the relinquishment of all rights to enforce (by
+lawsuit or otherwise) those copyrights in the Work.</p>
+
+ <p>Dedicator
+recognizes that, once placed in the public domain, the Work may be
+freely reproduced, distributed, transmitted, used, modified, built
+upon, or otherwise exploited by anyone for any purpose, commercial or
+non-commercial, and in any way, including by methods that have not yet
+been invented or conceived.</p>
+ </div>
+</div>
+</body></html>
+
+For the mx4j, mx4j-remote, and mx4j-tools library:
+
+ The MX4J License, Version 1.0
+
+ Copyright (c) 2001-2004 by the MX4J contributors. All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+
+ 1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+
+ 2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in
+ the documentation and/or other materials provided with the
+ distribution.
+
+ 3. The end-user documentation included with the redistribution,
+ if any, must include the following acknowledgment:
+ "This product includes software developed by the
+ MX4J project (http://mx4j.sourceforge.net)."
+ Alternately, this acknowledgment may appear in the software itself,
+ if and wherever such third-party acknowledgments normally appear.
+
+ 4. The name "MX4J" must not be used to endorse or promote
+ products derived from this software without prior written
+ permission.
+ For written permission, please contact
+ biorn_steedom [at] users [dot] sourceforge [dot] net
+
+ 5. Products derived from this software may not be called "MX4J",
+ nor may "MX4J" appear in their name, without prior written
+ permission of Simone Bordet.
+
+ THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ DISCLAIMED. IN NO EVENT SHALL THE MX4J CONTRIBUTORS
+ BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ SUCH DAMAGE.
+ ====================================================================
+
+ This software consists of voluntary contributions made by many
+ individuals on behalf of the MX4J project. For more information on
+ MX4J, please see
+ <a href="http://mx4j.sourceforge.net" target="_top">the MX4J website</a>.
+
+For the jetty and jetty-util library:
+
+
+ Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
+
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+ 1. Definitions.
+
+ "License" shall mean the terms and conditions for use, reproduction,
+ and distribution as defined by Sections 1 through 9 of this document.
+
+ "Licensor" shall mean the copyright owner or entity authorized by
+ the copyright owner that is granting the License.
+
+ "Legal Entity" shall mean the union of the acting entity and all
+ other entities that control, are controlled by, or are under common
+ control with that entity. For the purposes of this definition,
+ "control" means (i) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ outstanding shares, or (iii) beneficial ownership of such entity.
+
+ "You" (or "Your") shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+
+ "Source" form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
+
+ "Object" form shall mean any form resulting from mechanical
+ transformation or translation of a Source form, including but
+ not limited to compiled object code, generated documentation,
+ and conversions to other media types.
+
+ "Work" shall mean the work of authorship, whether in Source or
+ Object form, made available under the License, as indicated by a
+ copyright notice that is included in or attached to the work
+ (an example is provided in the Appendix below).
+
+ "Derivative Works" shall mean any work, whether in Source or Object
+ form, that is based on (or derived from) the Work and for which the
+ editorial revisions, annotations, elaborations, or other modifications
+ represent, as a whole, an original work of authorship. For the purposes
+ of this License, Derivative Works shall not include works that remain
+ separable from, or merely link (or bind by name) to the interfaces of,
+ the Work and Derivative Works thereof.
+
+ "Contribution" shall mean any work of authorship, including
+ the original version of the Work and any modifications or additions
+ to that Work or Derivative Works thereof, that is intentionally
+ submitted to Licensor for inclusion in the Work by the copyright owner
+ or by an individual or Legal Entity authorized to submit on behalf of
+ the copyright owner. For the purposes of this definition, "submitted"
+ means any form of electronic, verbal, or written communication sent
+ to the Licensor or its representatives, including but not limited to
+ communication on electronic mailing lists, source code control systems,
+ and issue tracking systems that are managed by, or on behalf of, the
+ Licensor for the purpose of discussing and improving the Work, but
+ excluding communication that is conspicuously marked or otherwise
+ designated in writing by the copyright owner as "Not a Contribution."
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity
+ on behalf of whom a Contribution has been received by Licensor and
+ subsequently incorporated within the Work.
+
+ 2. Grant of Copyright License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ copyright license to reproduce, prepare Derivative Works of,
+ publicly display, publicly perform, sublicense, and distribute the
+ Work and such Derivative Works in Source or Object form.
+
+ 3. Grant of Patent License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ (except as stated in this section) patent license to make, have made,
+ use, offer to sell, sell, import, and otherwise transfer the Work,
+ where such license applies only to those patent claims licensable
+ by such Contributor that are necessarily infringed by their
+ Contribution(s) alone or by combination of their Contribution(s)
+ with the Work to which such Contribution(s) was submitted. If You
+ institute patent litigation against any entity (including a
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
+ or a Contribution incorporated within the Work constitutes direct
+ or contributory patent infringement, then any patent licenses
+ granted to You under this License for that Work shall terminate
+ as of the date such litigation is filed.
+
+ 4. Redistribution. You may reproduce and distribute copies of the
+ Work or Derivative Works thereof in any medium, with or without
+ modifications, and in Source or Object form, provided that You
+ meet the following conditions:
+
+ (a) You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works
+ that You distribute, all copyright, patent, trademark, and
+ attribution notices from the Source form of the Work,
+ excluding those notices that do not pertain to any part of
+ the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its
+ distribution, then any Derivative Works that You distribute must
+ include a readable copy of the attribution notices contained
+ within such NOTICE file, excluding those notices that do not
+ pertain to any part of the Derivative Works, in at least one
+ of the following places: within a NOTICE text file distributed
+ as part of the Derivative Works; within the Source form or
+ documentation, if provided along with the Derivative Works; or,
+ within a display generated by the Derivative Works, if and
+ wherever such third-party notices normally appear. The contents
+ of the NOTICE file are for informational purposes only and
+ do not modify the License. You may add Your own attribution
+ notices within Derivative Works that You distribute, alongside
+ or as an addendum to the NOTICE text from the Work, provided
+ that such additional attribution notices cannot be construed
+ as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and
+ may provide additional or different license terms and conditions
+ for use, reproduction, or distribution of Your modifications, or
+ for any such Derivative Works as a whole, provided Your use,
+ reproduction, and distribution of the Work otherwise complies with
+ the conditions stated in this License.
+
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
+ any Contribution intentionally submitted for inclusion in the Work
+ by You to the Licensor shall be under the terms and conditions of
+ this License, without any additional terms or conditions.
+ Notwithstanding the above, nothing herein shall supersede or modify
+ the terms of any separate license agreement you may have executed
+ with Licensor regarding such Contributions.
+
+ 6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor,
+ except as required for reasonable and customary use in describing the
+ origin of the Work and reproducing the content of the NOTICE file.
+
+ 7. Disclaimer of Warranty. Unless required by applicable law or
+ agreed to in writing, Licensor provides the Work (and each
+ Contributor provides its Contributions) on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied, including, without limitation, any warranties or conditions
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ PARTICULAR PURPOSE. You are solely responsible for determining the
+ appropriateness of using or redistributing the Work and assume any
+ risks associated with Your exercise of permissions under this License.
+
+ 8. Limitation of Liability. In no event and under no legal theory,
+ whether in tort (including negligence), contract, or otherwise,
+ unless required by applicable law (such as deliberate and grossly
+ negligent acts) or agreed to in writing, shall any Contributor be
+ liable to You for damages, including any direct, indirect, special,
+ incidental, or consequential damages of any character arising as a
+ result of this License or out of the use or inability to use the
+ Work (including but not limited to damages for loss of goodwill,
+ work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses), even if such Contributor
+ has been advised of the possibility of such damages.
+
+ 9. Accepting Warranty or Additional Liability. While redistributing
+ the Work or Derivative Works thereof, You may choose to offer,
+ and charge a fee for, acceptance of support, warranty, indemnity,
+ or other liability obligations and/or rights consistent with this
+ License. However, in accepting such obligations, You may act only
+ on Your own behalf and on Your sole responsibility, not on behalf
+ of any other Contributor, and only if You agree to indemnify,
+ defend, and hold each Contributor harmless for any liability
+ incurred by, or claims asserted against, such Contributor by reason
+ of your accepting any such warranty or additional liability.
+
+ END OF TERMS AND CONDITIONS
+
+ APPENDIX: How to apply the Apache License to your work.
+
+ To apply the Apache License to your work, attach the following
+ boilerplate notice, with the fields enclosed by brackets "[]"
+ replaced with your own identifying information. (Don't include
+ the brackets!) The text should be enclosed in the appropriate
+ comment syntax for the file format. We also recommend that a
+ file or class name and description of purpose be included on the
+ same "printed page" as the copyright notice for easier
+ identification within third-party archives.
+
+ Copyright [yyyy] [name of copyright owner]
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+
+For the xmlpull library:
+
+XMLPULL API IS FREE
+-------------------
+
+All of the XMLPULL API source code, compiled code, and documentation
+contained in this distribution *except* for tests (see separate LICENSE_TESTS.txt)
+are in the Public Domain.
+
+XMLPULL API comes with NO WARRANTY or guarantee of fitness for any purpose.
+
+Initial authors:
+
+ Stefan Haustein
+ Aleksander Slominski
+
+2001-12-12
+
+For the spring library:
+
+ Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
+
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+ 1. Definitions.
+
+ "License" shall mean the terms and conditions for use, reproduction,
+ and distribution as defined by Sections 1 through 9 of this document.
+
+ "Licensor" shall mean the copyright owner or entity authorized by
+ the copyright owner that is granting the License.
+
+ "Legal Entity" shall mean the union of the acting entity and all
+ other entities that control, are controlled by, or are under common
+ control with that entity. For the purposes of this definition,
+ "control" means (i) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ outstanding shares, or (iii) beneficial ownership of such entity.
+
+ "You" (or "Your") shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+
+ "Source" form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
+
+ "Object" form shall mean any form resulting from mechanical
+ transformation or translation of a Source form, including but
+ not limited to compiled object code, generated documentation,
+ and conversions to other media types.
+
+ "Work" shall mean the work of authorship, whether in Source or
+ Object form, made available under the License, as indicated by a
+ copyright notice that is included in or attached to the work
+ (an example is provided in the Appendix below).
+
+ "Derivative Works" shall mean any work, whether in Source or Object
+ form, that is based on (or derived from) the Work and for which the
+ editorial revisions, annotations, elaborations, or other modifications
+ represent, as a whole, an original work of authorship. For the purposes
+ of this License, Derivative Works shall not include works that remain
+ separable from, or merely link (or bind by name) to the interfaces of,
+ the Work and Derivative Works thereof.
+
+ "Contribution" shall mean any work of authorship, including
+ the original version of the Work and any modifications or additions
+ to that Work or Derivative Works thereof, that is intentionally
+ submitted to Licensor for inclusion in the Work by the copyright owner
+ or by an individual or Legal Entity authorized to submit on behalf of
+ the copyright owner. For the purposes of this definition, "submitted"
+ means any form of electronic, verbal, or written communication sent
+ to the Licensor or its representatives, including but not limited to
+ communication on electronic mailing lists, source code control systems,
+ and issue tracking systems that are managed by, or on behalf of, the
+ Licensor for the purpose of discussing and improving the Work, but
+ excluding communication that is conspicuously marked or otherwise
+ designated in writing by the copyright owner as "Not a Contribution."
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity
+ on behalf of whom a Contribution has been received by Licensor and
+ subsequently incorporated within the Work.
+
+ 2. Grant of Copyright License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ copyright license to reproduce, prepare Derivative Works of,
+ publicly display, publicly perform, sublicense, and distribute the
+ Work and such Derivative Works in Source or Object form.
+
+ 3. Grant of Patent License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ (except as stated in this section) patent license to make, have made,
+ use, offer to sell, sell, import, and otherwise transfer the Work,
+ where such license applies only to those patent claims licensable
+ by such Contributor that are necessarily infringed by their
+ Contribution(s) alone or by combination of their Contribution(s)
+ with the Work to which such Contribution(s) was submitted. If You
+ institute patent litigation against any entity (including a
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
+ or a Contribution incorporated within the Work constitutes direct
+ or contributory patent infringement, then any patent licenses
+ granted to You under this License for that Work shall terminate
+ as of the date such litigation is filed.
+
+ 4. Redistribution. You may reproduce and distribute copies of the
+ Work or Derivative Works thereof in any medium, with or without
+ modifications, and in Source or Object form, provided that You
+ meet the following conditions:
+
+ (a) You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works
+ that You distribute, all copyright, patent, trademark, and
+ attribution notices from the Source form of the Work,
+ excluding those notices that do not pertain to any part of
+ the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its
+ distribution, then any Derivative Works that You distribute must
+ include a readable copy of the attribution notices contained
+ within such NOTICE file, excluding those notices that do not
+ pertain to any part of the Derivative Works, in at least one
+ of the following places: within a NOTICE text file distributed
+ as part of the Derivative Works; within the Source form or
+ documentation, if provided along with the Derivative Works; or,
+ within a display generated by the Derivative Works, if and
+ wherever such third-party notices normally appear. The contents
+ of the NOTICE file are for informational purposes only and
+ do not modify the License. You may add Your own attribution
+ notices within Derivative Works that You distribute, alongside
+ or as an addendum to the NOTICE text from the Work, provided
+ that such additional attribution notices cannot be construed
+ as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and
+ may provide additional or different license terms and conditions
+ for use, reproduction, or distribution of Your modifications, or
+ for any such Derivative Works as a whole, provided Your use,
+ reproduction, and distribution of the Work otherwise complies with
+ the conditions stated in this License.
+
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
+ any Contribution intentionally submitted for inclusion in the Work
+ by You to the Licensor shall be under the terms and conditions of
+ this License, without any additional terms or conditions.
+ Notwithstanding the above, nothing herein shall supersede or modify
+ the terms of any separate license agreement you may have executed
+ with Licensor regarding such Contributions.
+
+ 6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor,
+ except as required for reasonable and customary use in describing the
+ origin of the Work and reproducing the content of the NOTICE file.
+
+ 7. Disclaimer of Warranty. Unless required by applicable law or
+ agreed to in writing, Licensor provides the Work (and each
+ Contributor provides its Contributions) on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied, including, without limitation, any warranties or conditions
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ PARTICULAR PURPOSE. You are solely responsible for determining the
+ appropriateness of using or redistributing the Work and assume any
+ risks associated with Your exercise of permissions under this License.
+
+ 8. Limitation of Liability. In no event and under no legal theory,
+ whether in tort (including negligence), contract, or otherwise,
+ unless required by applicable law (such as deliberate and grossly
+ negligent acts) or agreed to in writing, shall any Contributor be
+ liable to You for damages, including any direct, indirect, special,
+ incidental, or consequential damages of any character arising as a
+ result of this License or out of the use or inability to use the
+ Work (including but not limited to damages for loss of goodwill,
+ work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses), even if such Contributor
+ has been advised of the possibility of such damages.
+
+ 9. Accepting Warranty or Additional Liability. While redistributing
+ the Work or Derivative Works thereof, You may choose to offer,
+ and charge a fee for, acceptance of support, warranty, indemnity,
+ or other liability obligations and/or rights consistent with this
+ License. However, in accepting such obligations, You may act only
+ on Your own behalf and on Your sole responsibility, not on behalf
+ of any other Contributor, and only if You agree to indemnify,
+ defend, and hold each Contributor harmless for any liability
+ incurred by, or claims asserted against, such Contributor by reason
+ of your accepting any such warranty or additional liability.
+
+ END OF TERMS AND CONDITIONS
+
+ APPENDIX: How to apply the Apache License to your work.
+
+ To apply the Apache License to your work, attach the following
+ boilerplate notice, with the fields enclosed by brackets "[]"
+ replaced with your own identifying information. (Don't include
+ the brackets!) The text should be enclosed in the appropriate
+ comment syntax for the file format. We also recommend that a
+ file or class name and description of purpose be included on the
+ same "printed page" as the copyright notice for easier
+ identification within third-party archives.
+
+ Copyright [yyyy] [name of copyright owner]
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+
+For the xstream library:
+
+(BSD Style License)
+
+Copyright (c) 2003-2004, Joe Walnes
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+Redistributions of source code must retain the above copyright notice, this list of
+conditions and the following disclaimer. Redistributions in binary form must reproduce
+the above copyright notice, this list of conditions and the following disclaimer in
+the documentation and/or other materials provided with the distribution.
+
+Neither the name of XStream nor the names of its contributors may be used to endorse
+or promote products derived from this software without specific prior written
+permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
+EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
+SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
+WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
+DAMAGE.
diff --git a/NOTICE.txt b/NOTICE.txt
new file mode 100644
index 0000000..d8ded15
--- /dev/null
+++ b/NOTICE.txt
@@ -0,0 +1,12 @@
+=========================================================================
+== NOTICE file corresponding to the section 4 d of ==
+== the Apache License, Version 2.0, ==
+== in this case for the Apache ActiveMQ distribution. ==
+=========================================================================
+
+Apache ActiveMQ
+Copyright 2005-2006 The Apache Software Foundation
+
+This product includes software developed by
+The Apache Software Foundation (http://www.apache.org/).
+
diff --git a/README.txt b/README.txt
new file mode 100644
index 0000000..6c5d2cf
--- /dev/null
+++ b/README.txt
@@ -0,0 +1,47 @@
+=======================================================================
+Welcome to:
+ * Apache.NMS.XMS : Apache NMS for IBM XMS Client Library
+=======================================================================
+
+For more information see http://activemq.apache.org/nms
+
+=======================================================================
+Building With NAnt 0.86 see http://nant.sourceforge.net/
+=======================================================================
+
+NAnt version 0.86 or newer is required to build Apache.NMS.XMS. Version 0.90
+or newer is highly recommended.
+To build the code using NAnt, run:
+
+ nant
+
+The NMS documentation can be generated into three different formats using
+Microsoft's Sandcastle open source product. The Sandcastle Styles project
+was used to enhance the output generated from the current release of Sandcastle.
+
+The Sandcastle project is located here:
+
+http://sandcastle.codeplex.com/
+
+The Sandcastle Styles project is located here:
+
+http://sandcastlestyles.codeplex.com/
+
+To generate the documentation, run:
+
+ nant sandcastle-all
+
+=======================================================================
+Building With Visual Studio 2013
+=======================================================================
+
+First build the project with nant, this will download and install
+all the 3rd party dependencies for you.
+
+Open the solution File. Build using "Build"->"Build Solution"
+menu option.
+
+The resulting DLLs will be in build\${framework}\debug or the
+build\${framework}\release directories depending on your settings
+under "Build"->"Configuration Manager"
+
diff --git a/keyfile/NMSKey.snk b/keyfile/NMSKey.snk
new file mode 100644
index 0000000..fdd5b24
--- /dev/null
+++ b/keyfile/NMSKey.snk
Binary files differ
diff --git a/nant-common.xml b/nant-common.xml
new file mode 100644
index 0000000..3e5a8fc
--- /dev/null
+++ b/nant-common.xml
@@ -0,0 +1,658 @@
+<?xml version="1.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.
+-->
+<project xmlns="http://nant.sourceforge.net/release/0.85/nant.xsd">
+
+ <!-- ============================================================================================ -->
+ <!-- P R O P E R T Y D E F I N I T I O N S -->
+ <!-- ============================================================================================ -->
+
+ <!-- global project settings -->
+ <property name="project.cls.compliant" value="true" unless="${property::exists('project.cls.compliant')}" />
+ <property name="project.release.type" value="SNAPSHOT" unless="${property::exists('project.release.type')}" />
+ <property name="project.version.full" value="${project.version + if(project.release.type == 'snapshot', '-' + project.release.type, '')}" dynamic="true" />
+ <property name="project.startyear" value="2005" />
+ <property name="build.dir" value="${basedir}/build" />
+ <property name="doc.dir" value="${build.dir}/doc" />
+ <property name="lib.dir" value="${path::combine(basedir, 'lib')}" dynamic="true" />
+ <property name="lib.family.dir" value="${path::combine(lib.dir, framework::get-family(framework::get-target-framework()))}" dynamic="true" />
+ <property name="lib.framework.dir" value="${path::combine(lib.family.dir, version::to-string(framework::get-version(framework::get-target-framework())))}" dynamic="true" />
+ <property name="package.dir" value="${basedir}/package" />
+ <property name="src.package.name" value="${project.name + '-' + project.version + if(project.release.type == 'SNAPSHOT', '-' + project.release.type, '') + '-src.zip'}" />
+ <property name="bin.package.name" value="${project.name + '-' + project.version + if(project.release.type == 'SNAPSHOT', '-' + project.release.type, '') + '-bin.zip'}" />
+
+ <!-- default configuration -->
+ <property name="build.defines" value="" />
+ <property name="build.noskip" value="false" />
+ <property name="build.skip" value="false" />
+ <property name="build.skip.release" value="false" unless="${property::exists('build.skip.release')}" />
+ <property name="download.skip" value="false" unless="${property::exists('download.skip')}"/>
+ <property name="install.skip" value="false" unless="${property::exists('install.skip')}"/>
+ <property name="compile.skip" value="false" unless="${property::exists('compile.skip')}" />
+ <property name="current.build.config" value="${if(project.release.type == 'release', 'release', 'debug')}" overwrite="false" />
+ <property name="current.build.framework" value="${framework::get-target-framework()}" overwrite="false" />
+ <property name="current.build.defines" value="${build.defines}" />
+ <property name="build.framework.strings" value="net-2.0,net-3.5,net-4.0,mono-2.0,mono-4.0,netcf-2.0,netcf-3.5" unless="${property::exists('build.framework.strings')}"/>
+ <property name="current.build.framework.assembly.dir" value="${framework::get-assembly-directory(framework::get-target-framework())}" dynamic="true" />
+
+ <property name="build.config.strings" value="${if(property::exists('configuration'), configuration, if(build.skip.release == 'true', 'debug', 'debug,release'))}" dynamic="true" />
+
+ <!-- Figure out the user's HOME directory -->
+ <property name="user.home" value="${environment::get-variable('HOME')}"
+ if="${environment::variable-exists('HOME') and platform::is-unix()}"
+ unless="${property::exists('user.home')}" />
+ <property name="user.home" value="${environment::get-variable('USERPROFILE')}"
+ if="${environment::variable-exists('USERPROFILE') and platform::is-windows()}"
+ unless="${property::exists('user.home')}" />
+ <fail message="The HOME environment variable is not defined. Please set it to your home directory."
+ unless="${property::exists('user.home')}" if="${platform::is-unix()}" />
+ <fail message="The USERPROFILE environment variable is not defined. Please set it to your home directory."
+ unless="${property::exists('user.home')}" if="${platform::is-windows()}" />
+
+ <!-- Figure out the NANT repositories -->
+ <property name="nant.remote.repo" value="${environment::get-variable('NANT_REMOTE_REPO')}"
+ if="${environment::variable-exists('NANT_REMOTE_REPO')}"
+ unless="${property::exists('nant.remote.repo')}" />
+ <property name="nant.local.repo" value="${environment::get-variable('NANT_REPO')}/local"
+ if="${environment::variable-exists('NANT_REPO')}"
+ unless="${property::exists('nant.local.repo')}" />
+ <property name="nant.local.repo" value="${user.home}/.nant/repository/local"
+ unless="${property::exists('nant.local.repo')}" />
+
+ <!-- Figure out the keyfile location -->
+ <property name="snk.file" value="${environment::get-variable('ACTIVEMQ_DOTNET_SNK')}"
+ if="${environment::variable-exists('ACTIVEMQ_DOTNET_SNK')}"
+ unless="${property::exists('snk.file')}" />
+ <property name="snk.file" value="${basedir}/keyfile/NMSKey.snk"
+ if="${not property::exists('snk.file')}" />
+
+ <!-- ============================================================================================ -->
+ <!-- I N I T I A L I Z A T I O N T A R G E T S -->
+ <!-- ============================================================================================ -->
+
+ <target name="init" description="Initializes build properties">
+ <!-- enabled the release or debug configuration -->
+ <call target="set-${current.build.config}-configuration" />
+
+ <!-- Check to see if our build setup for the target framework -->
+ <if test="${not(target::exists('set-'+current.build.framework+'-framework-configuration'))}">
+ <fail message="The '${current.build.framework}' framework is not supported by this version of ActiveMQ .NET" />
+ </if>
+ <call target="set-${current.build.framework}-framework-configuration" />
+
+ <!-- Check to see current platform supports the target framework -->
+ <if test="${framework::exists(current.build.framework)}">
+ <property name="build.skip" value="false" />
+ </if>
+ <if test="${not framework::exists(current.build.framework)}">
+ <if test="${build.noskip}">
+ <fail message="${current.build.framework.name} is not available." />
+ </if>
+ <if test="${not(build.noskip)}">
+ <echo message="${current.build.framework.name} is not available. Build skipped." />
+ <property name="build.skip" value="true" />
+ </if>
+ </if>
+
+ <!-- Check to see if we should skip this build framework. -->
+ <if test="${not(build.skip)}">
+ <if test="${property::exists('build.'+current.build.framework+'.skip')}">
+ <property name="build.skip" value="true" />
+ <echo message="The '${current.build.framework}' framework is not supported by this version of ActiveMQ .NET" />
+ </if>
+ </if>
+
+ <property name="current.build.keysign" value="${current.build.framework.sign}" />
+ <property name="build.bin.dir" value="${build.dir}/${current.build.framework}/${current.build.config}" />
+ <if test="${not(build.skip)}">
+ <echo message="Doing ${if(current.build.keysign,'a signed','an unsigned')} ${current.build.config} build for the ${current.build.framework.name} framework" />
+ <mkdir dir="${build.bin.dir}" />
+ </if>
+ <call target="dependency-init" />
+ </target>
+
+ <!-- Generate four-digit build number -->
+ <target name="generate-build-number">
+ <if test="${not property::exists('project.version.numeric')}">
+ <script language="C#">
+ <imports>
+ <import namespace="System.Globalization" />
+ <import namespace="System.Threading" />
+ </imports>
+ <code>
+ <!-- Format for assembly revision is the number of days from the year the project 'started', property project.startyear. -->
+ <![CDATA[
+ public static void ScriptMain(Project project)
+ {
+ int startYear = Convert.ToInt32(project.Properties["project.startyear"]);
+ DateTime start = new DateTime(startYear, 1, 1);
+ TimeSpan ts = DateTime.Now - start;
+ project.Properties["project.version.numeric"] = project.Properties["project.version"].ToString() + "." + ts.Days.ToString();
+ }
+ ]]>
+ </code>
+ </script>
+ </if>
+ </target>
+
+ <!-- Generate assemblyinfo.cs files -->
+ <target name="generate-assemblyinfo" depends="generate-build-number" description="Generate the assembly info for the path in assemblyinfo.filename">
+ <asminfo output="${assemblyinfo.filename}" language="CSharp">
+ <imports>
+ <import namespace="System" />
+ <import namespace="System.Reflection" />
+ <import namespace="System.Runtime.InteropServices" />
+ </imports>
+ <attributes>
+ <attribute type="ComVisibleAttribute" value="false" />
+ <attribute type="CLSCompliantAttribute" value="${project.cls.compliant}" />
+ <attribute type="AssemblyTitleAttribute" value="${project.short_description}" />
+ <attribute type="AssemblyDescriptionAttribute" value="${project.description}" />
+ <attribute type="AssemblyConfigurationAttribute" value="${project.release.type}" />
+ <attribute type="AssemblyCompanyAttribute" value="http://activemq.apache.org/nms" />
+ <attribute type="AssemblyProductAttribute" value="${project.short_description}" />
+ <attribute type="AssemblyCopyrightAttribute" value="Copyright (C) ${project.startyear}-${datetime::get-year(datetime::now())} Apache Software Foundation" />
+ <attribute type="AssemblyTrademarkAttribute" value="" />
+ <attribute type="AssemblyCultureAttribute" value="" />
+ <attribute type="AssemblyVersionAttribute" value="${project.version.numeric}" />
+ <attribute type="AssemblyInformationalVersionAttribute" value="${project.version}" />
+ </attributes>
+ </asminfo>
+ </target>
+
+ <!-- ============================================================================================ -->
+ <!-- C O N F I G U R A T I O N T A R G E T S -->
+ <!-- ============================================================================================ -->
+
+ <target name="set-noskip-configuration" description="Disable skipping builds">
+ <property name="project.noskip" value="true" />
+ </target>
+
+ <target name="set-debug-configuration" description="Enabled 'debug' builds">
+ <property name="current.build.config" value="debug" />
+ <property name="current.build.config.debug" value="true" />
+ <property name="current.build.config.release" value="false" />
+ <property name="current.build.defines" value="${build.defines}DEBUG,TRACE," dynamic="true" />
+ <property name="csc.debug" value="Full" />
+ <property name="csc.optimize" value="false" />
+ </target>
+
+ <target name="set-release-configuration" description="Enabled 'release' builds">
+ <property name="current.build.config" value="release" />
+ <property name="current.build.config.release" value="true" />
+ <property name="current.build.config.debug" value="false" />
+ <property name="csc.debug" value="Full" />
+ <property name="csc.optimize" value="true" />
+ </target>
+
+ <target name="set-net-2.0-framework-configuration">
+ <property name="current.build.framework" value="net-2.0" />
+ <property name="current.build.framework.name" value=".NET 2.0" />
+ <property name="current.build.defines" value="${build.defines}NET,NET_2_0" dynamic="true" />
+ <property name="current.build.framework.sign" value="true" />
+ <property name="link.sdkdoc.version" value="SDK_v2_0" />
+ <property name="link.sdkdoc.web" value="true" />
+ <if test="${framework::exists(current.build.framework)}">
+ <property name="nant.settings.currentframework" value="${current.build.framework}" />
+ </if>
+ <!-- Use the .NET 3.5 compiler for improved language features. Still targets same runtime. -->
+ <if test="${framework::exists('net-3.5')}">
+ <property name="nant.settings.currentframework" value="net-3.5" />
+ </if>
+ </target>
+
+ <target name="set-net-3.5-framework-configuration">
+ <property name="current.build.framework" value="net-3.5" />
+ <property name="current.build.framework.name" value=".NET 3.5" />
+ <property name="current.build.defines" value="${build.defines}NET,NET_2_0,NET_3_5" dynamic="true" />
+ <property name="current.build.framework.sign" value="true" />
+ <property name="link.sdkdoc.version" value="SDK_v6_1" />
+ <property name="link.sdkdoc.web" value="true" />
+ <if test="${framework::exists(current.build.framework)}">
+ <property name="nant.settings.currentframework" value="${current.build.framework}" />
+ </if>
+ </target>
+
+ <target name="set-net-4.0-framework-configuration">
+ <property name="current.build.framework" value="net-4.0" />
+ <property name="current.build.framework.name" value=".NET 4.0" />
+ <property name="current.build.defines" value="${build.defines}NET,NET_2_0,NET_3_5,NET_4_0" dynamic="true" />
+ <property name="current.build.framework.sign" value="true" />
+ <property name="link.sdkdoc.version" value="SDK_v7_0" />
+ <property name="link.sdkdoc.web" value="true" />
+ <if test="${framework::exists(current.build.framework)}">
+ <property name="nant.settings.currentframework" value="${current.build.framework}" />
+ </if>
+ </target>
+
+ <target name="set-netcf-2.0-framework-configuration">
+ <property name="current.build.framework" value="netcf-2.0" />
+ <property name="current.build.framework.name" value=".NET Compact Framework 2.0" />
+ <property name="current.build.defines" value="${build.defines}PocketPC,NETCF,NETCF_2_0" dynamic="true" />
+ <property name="current.build.framework.sign" value="true" />
+ <property name="link.sdkdoc.version" value="SDK_v1_1" />
+ <property name="link.sdkdoc.web" value="true" />
+ <if test="${framework::exists(current.build.framework)}">
+ <property name="nant.settings.currentframework" value="${current.build.framework}" />
+ </if>
+ </target>
+
+ <target name="set-netcf-3.5-framework-configuration">
+ <property name="current.build.framework" value="netcf-3.5" />
+ <property name="current.build.framework.name" value=".NET Compact Framework 3.5" />
+ <property name="current.build.defines" value="${build.defines}PocketPC,NETCF,NETCF_3_5" dynamic="true" />
+ <property name="current.build.framework.sign" value="true" />
+ <property name="link.sdkdoc.version" value="SDK_v3_5" />
+ <property name="link.sdkdoc.web" value="true" />
+ <if test="${framework::exists(current.build.framework)}">
+ <property name="nant.settings.currentframework" value="${current.build.framework}" />
+ </if>
+ </target>
+
+ <target name="set-mono-2.0-framework-configuration">
+ <property name="current.build.framework" value="mono-2.0" />
+ <property name="current.build.framework.name" value="Mono 2.0" />
+ <property name="current.build.defines" value="${build.defines}MONO,MONO_2_0" dynamic="true" />
+ <property name="current.build.framework.sign" value="true" />
+ <property name="link.sdkdoc.version" value="SDK_v1_1" />
+ <property name="link.sdkdoc.web" value="true" />
+ <if test="${framework::exists(current.build.framework)}">
+ <property name="nant.settings.currentframework" value="${current.build.framework}" />
+ </if>
+ </target>
+
+ <target name="set-mono-4.0-framework-configuration">
+ <property name="current.build.framework" value="mono-4.0" />
+ <property name="current.build.framework.name" value="Mono 4.0" />
+ <property name="current.build.defines" value="${build.defines}MONO,MONO_4_0" dynamic="true" />
+ <property name="current.build.framework.sign" value="true" />
+ <property name="link.sdkdoc.version" value="SDK_v1_1" />
+ <property name="link.sdkdoc.web" value="true" />
+ <if test="${framework::exists(current.build.framework)}">
+ <property name="nant.settings.currentframework" value="${current.build.framework}" />
+ </if>
+ </target>
+
+ <!-- ============================================================================================ -->
+ <!-- C O M P I L E T A R G E T S -->
+ <!-- ============================================================================================ -->
+
+ <target name="compile-all" description="Compile all build configurations for all runtime configurations">
+ <echo message="Compiling all build configurations for all runtime configurations." />
+ <foreach item="String" in="${build.framework.strings}" delim="," property="current.build.framework">
+ <foreach item="String" in="${build.config.strings}" delim="," property="current.build.config">
+ <call target="compile-target" />
+ </foreach>
+ </foreach>
+ </target>
+
+ <target name="compile-target" depends="init, download-vendor, conditional-compile" />
+
+ <target name="conditional-compile" depends="init" unless="${build.skip or compile.skip}"
+ description="Conditionaly compiles all the modules if build framework and type are supported">
+ <call target="compile" />
+ </target>
+
+ <target name="compile" description="Compile everything">
+ <call target="compile-main" cascade="false" />
+ <call target="compile-test" cascade="false" />
+ </target>
+
+ <target name="compile-main" depends="init" description="Build the main library">
+ <echo message="Building the ${project.name} library" />
+ <property name="assemblyinfo.filename" value="src/main/csharp/CommonAssemblyInfo.cs" />
+ <call target="generate-assemblyinfo" />
+
+ <csc if="${current.build.keysign}" keyfile="${snk.file}" target="library"
+ define="${current.build.defines}" warnaserror="false" debug="${csc.debug}" optimize="${csc.optimize}"
+ output="${build.bin.dir}/${project.name}.dll" doc="${build.bin.dir}/${project.name}.xml">
+ <nowarn>
+ <warning number="1591" /> <!-- do not report warnings for missing XML comments -->
+ </nowarn>
+ <sources failonempty="true">
+ <include name="src/main/csharp/**.cs" />
+ </sources>
+ <references refid="dependencies" />
+ </csc>
+ <csc if="${not current.build.keysign}" target="library"
+ define="${current.build.defines}" warnaserror="false" debug="${csc.debug}" optimize="${csc.optimize}"
+ output="${build.bin.dir}/${project.name}.dll" doc="${build.bin.dir}/${project.name}.xml">
+ <nowarn>
+ <warning number="1591" /> <!-- do not report warnings for missing XML comments -->
+ </nowarn>
+ <sources failonempty="true">
+ <include name="src/main/csharp/**.cs" />
+ </sources>
+ <references refid="dependencies" />
+ </csc>
+ <call target="copy-content" />
+ </target>
+
+ <!-- Compile the nms-test module -->
+ <target name="compile-test" depends="compile-main" description="Build the test library">
+ <echo message="Building the ${project.name}.Test library" />
+ <property name="assemblyinfo.filename" value="src/test/csharp/CommonAssemblyInfo.cs" />
+ <call target="generate-assemblyinfo" />
+
+ <csc if="${current.build.keysign}" keyfile="${snk.file}" target="library"
+ define="${current.build.defines}" warnaserror="false" debug="${csc.debug}" optimize="${csc.optimize}"
+ output="${build.bin.dir}/${project.name}.Test.dll" doc="${build.bin.dir}/${project.name}.Test.xml">
+ <nowarn>
+ <warning number="1591" /> <!-- do not report warnings for missing XML comments -->
+ <warning number="3016" /> <!-- do not report warnings for array parameters -->
+ </nowarn>
+ <sources failonempty="true">
+ <include name="src/test/csharp/**.cs" />
+ </sources>
+ <references refid="test.dependencies" />
+ </csc>
+ <csc if="${not current.build.keysign}" target="library"
+ define="${current.build.defines}" warnaserror="false" debug="${csc.debug}" optimize="${csc.optimize}"
+ output="${build.bin.dir}/${project.name}.Test.dll" doc="${build.bin.dir}/${project.name}.Test.xml">
+ <nowarn>
+ <warning number="1591" /> <!-- do not report warnings for missing XML comments -->
+ <warning number="3016" /> <!-- do not report warnings for array parameters -->
+ </nowarn>
+ <sources failonempty="true">
+ <include name="src/test/csharp/**.cs" />
+ </sources>
+ <references refid="test.dependencies" />
+ </csc>
+ <call target="copy-content" />
+ </target>
+
+ <target name="copy-content">
+ <foreach item="File" property="content.filename">
+ <in>
+ <items refid="content.filenames" />
+ </in>
+ <do>
+ <copy todir="${build.bin.dir}" file="${content.filename}" if="${not file::up-to-date(content.filename, '${build.bin.dir}/${content.filename}')}" />
+ </do>
+ </foreach>
+ </target>
+
+ <!-- ============================================================================================ -->
+ <!-- I N S T A L L T A R G E T S -->
+ <!-- ============================================================================================ -->
+
+ <target name="install-all" description="Install all build configurations for all runtime configurations">
+ <echo message="Installing all build configurations for all runtime configurations." />
+ <foreach item="String" in="${build.framework.strings}" delim="," property="current.build.framework">
+ <foreach item="String" in="${build.config.strings}" delim="," property="current.build.config">
+ <call target="install" />
+ </foreach>
+ </foreach>
+ </target>
+
+ <!-- Install the modules to the local repo -->
+ <target name="install" depends="init, compile-target, conditional-install"
+ description="Install the artifacts into the nant repo" />
+
+ <target name="conditional-install" unless="${build.skip or install.skip}"
+ description="Install the artifacts into the nant repo">
+ <property name="path" value="${project.group}/${project.name}/${project.version.full}/${current.build.framework}/${current.build.config}" />
+ <foreach item="File" property="install.filename">
+ <in>
+ <items refid="install.filenames" />
+ </in>
+ <do>
+ <property name="repo.task.artifact" value="${path}/${path::get-file-name(install.filename)}" />
+ <property name="repo.task.src" value="${install.filename}" />
+ <property name="repo.task.dest" value="${nant.local.repo}/${repo.task.artifact}" />
+ <mkdir dir="${directory::get-parent-directory(repo.task.dest)}" />
+ <copy file="${repo.task.src}" tofile="${repo.task.dest}" />
+ </do>
+ </foreach>
+ </target>
+
+ <!-- ============================================================================================ -->
+ <!-- R E P O D O W N L O A D T A R G E T S -->
+ <!-- ============================================================================================ -->
+
+ <target name="download-vendor-all" description="Download vendor files for all runtime configurations">
+ <echo message="Downloading vendor files for all runtime configurations." />
+ <property name="current.build.config" value="release" />
+ <foreach item="String" in="${build.framework.strings}" delim="," property="current.build.framework">
+ <call target="download-vendor" />
+ </foreach>
+ </target>
+
+ <target name="download-vendor" depends="vendor-init, conditional-download"
+ description="Download the vendor artifacts from the nant repo" />
+
+ <target name="conditional-download" unless="${build.skip or download.skip}"
+ description="Download the artifacts from the nant repo">
+ <!-- Iterate over the defined vendor filesets. -->
+ <foreach item="String" in="${vendor.fileset.names}" delim="," property="current.vendor">
+ <property name="vendor.name" value="${property::get-value(current.vendor + '.name')}" />
+ <property name="vendor.group" value="${property::get-value(current.vendor + '.group')}" />
+ <property name="vendor.version" value="${property::get-value(current.vendor + '.version')}" />
+ <property name="vendor.filenames" value="${property::get-value(current.vendor + '.filenames')}" />
+ <property name="local.repo.vendor.path" value="${nant.local.repo}/${vendor.group}/${vendor.name}/${vendor.version}/${current.build.framework}/${current.build.config}" />
+ <property name="lib.path" value="lib/${vendor.name}/${current.build.framework}" />
+ <!--
+ Update the LIB folder with the latest version of the file. If there is a newer version
+ installed in the local repository, then that version will be copied into the LIB folder.
+ -->
+ <foreach item="String" in="${vendor.filenames}" delim="," property="repo.task.artifact">
+ <property name="lib.task.dest" value="${lib.path}/${repo.task.artifact}" />
+ <mkdir dir="${directory::get-parent-directory(lib.task.dest)}" />
+ <property name="repo.task.src" value="${local.repo.vendor.path}/${repo.task.artifact}" />
+ <copy file="${repo.task.src}" tofile="${lib.task.dest}" if="${file::exists(repo.task.src)}" />
+ <if test="${not file::exists(lib.task.dest)}">
+ <echo message="Required dependent assembly ${repo.task.artifact} from ${vendor.name} for ${current.build.framework} is not available. Build skipped." />
+ <property name="build.skip" value="true" />
+ </if>
+ </foreach>
+ </foreach>
+ </target>
+
+ <!-- ============================================================================================ -->
+ <!-- T E S T T A R G E T S -->
+ <!-- ============================================================================================ -->
+
+ <target name="test" depends="test-debug" description="Alias test target to test-debug" />
+
+ <target name="test-all" depends="test-debug, test-release" description="Test all build configurations for all runtime configurations" />
+
+ <target name="test-debug" depends="" description="Test debug build configurations for all runtime configurations">
+ <property name="current.build.config" value="debug" />
+ <call target="test-frameworks" />
+ </target>
+
+ <target name="test-release" depends="" description="Test release build configurations for all runtime configurations">
+ <property name="current.build.config" value="release" />
+ <call target="test-frameworks" />
+ </target>
+
+ <target name="test-frameworks">
+ <foreach item="String" in="${build.framework.strings}" delim="," property="current.build.framework">
+ <call target="init" />
+ <if test="${not build.skip}">
+ <exec program="nunit-console" failonerror="true" workingdir="build/${current.build.framework}/${current.build.config}">
+ <arg value="${NUnit.Projectfile}" />
+ <arg value="-labels" />
+ <arg value="-exclude=Manual,LongRunning" />
+ <arg value="-xml=Nunit.TestOutput.xml" />
+ </exec>
+ </if>
+ </foreach>
+ </target>
+
+ <!-- ============================================================================================ -->
+ <!-- M I S C E L L A N E O U S T A R G E T S -->
+ <!-- ============================================================================================ -->
+
+ <target name="build" depends="default" description="Build the project." />
+
+ <target name="rebuild" depends="clean,build" description="Rebuild the project." />
+
+ <target name="clean" description="Deletes build">
+ <if test="${target::exists('clean-init')}">
+ <call target="clean-init" />
+ </if>
+ <foreach item="String" in="${build.framework.strings}" delim="," property="current.build.framework">
+ <foreach item="String" in="${build.config.strings}" delim="," property="current.build.config">
+ <call target="clean-proj" />
+ </foreach>
+ </foreach>
+ </target>
+
+ <target name="clean-proj" depends="init" description="Deletes specific project build">
+ <property name="clean.dir" value="build/${current.build.framework}/${current.build.config}" />
+ <delete dir="${clean.dir}" if="${directory::exists(clean.dir)}" />
+ <property name="clean.dir" value="package/${current.build.config}" />
+ <delete dir="${clean.dir}" if="${directory::exists(clean.dir)}" />
+ </target>
+
+ <target name="package" description="Bundle the source and binary distributions.">
+ <mkdir dir="${package.dir}"
+ if="${not directory::exists(package.dir)}" />
+ <zip zipfile="${package.dir}/${bin.package.name}">
+ <fileset refid="bin.package.contents"/>
+ </zip>
+ <zip zipfile="${package.dir}/${src.package.name}">
+ <fileset refid="src.package.contents"/>
+ </zip>
+ </target>
+
+ <target name="doc" depends="build">
+ <mkdir dir="${doc.dir}" />
+ <ndoc failonerror="false">
+ <assemblies basedir="${build.bin.dir}">
+ <include name="${project.name}.dll" />
+ </assemblies>
+ <summaries basedir="${basedir}/src/main/ndoc">
+ <include name="NamespaceSummary.xml" />
+ </summaries>
+ <documenters>
+ <documenter name="MSDN">
+ <property name="OutputDirectory" value="${doc.dir}" />
+ <property name="HtmlHelpName" value="${project.name}" />
+ <property name="HtmlHelpCompilerFilename" value="hhc.exe" />
+ <property name="IncludeFavorites" value="False" />
+ <property name="Title" value="${project.short_description}" />
+ <property name="SplitTOCs" value="False" />
+ <property name="DefaulTOC" value="" />
+ <!--
+ <property name="ShowVisualBasic" value="True" />
+ <property name="ShowMissingSummaries" value="True" />
+ <property name="ShowMissingRemarks" value="True" />
+ <property name="ShowMissingParams" value="True" />
+ <property name="ShowMissingReturns" value="True" />
+ <property name="ShowMissingValues" value="True" />
+ -->
+ <property name="DocumentInternals" value="False" />
+ <property name="DocumentProtected" value="True" />
+ <property name="DocumentPrivates" value="False" />
+ <property name="DocumentEmptyNamespaces" value="False" />
+ <property name="IncludeAssemblyVersion" value="True" />
+ <property name="CopyrightText" value="" />
+ <property name="CopyrightHref" value="" />
+ </documenter>
+ </documenters>
+ </ndoc>
+ </target>
+
+ <target name="sandcastle" depends="set-release-configuration, init, conditional-compile">
+ <!-- Directories -->
+ <property name="sandcastle.style" value="vs2005" unless="${property::exists('sandcastle.style')}" />
+ <property name="documentation.dir" value="${build.bin.dir}" />
+ <property name="bin.intern.dir" value="${build.bin.dir}" />
+ <property name="bin.extern.dir" value="${basedir}\lib\NUnit\net-2.0" />
+ <property name="sandcastle.dir" value="${environment::get-variable('DXROOT')}" />
+ <property name="sandcastle.workingdir" value="${build.dir}\doc\${sandcastle.style}" />
+ <property name="sandcastle.output.dir" value="${sandcastle.workingdir}\Output" />
+
+ <!-- Executables -->
+ <property name="sandcastle.mrefbuilder.exe" value="${sandcastle.dir}\productiontools\mrefbuilder.exe" />
+ <property name="sandcastle.buildassembler.exe" value="${sandcastle.dir}\productiontools\buildassembler.exe" />
+ <property name="sandcastle.xsltransform.exe" value="${sandcastle.dir}\productiontools\xsltransform.exe" />
+ <property name="sandcastle.productiontransforms.dir" value="${sandcastle.dir}\ProductionTransforms" />
+
+ <!-- Create or Cleanup Working Directory -->
+ <mkdir dir="${sandcastle.workingdir}"
+ if="${not directory::exists(sandcastle.workingdir)}" />
+ <delete>
+ <fileset basedir="${sandcastle.workingdir}">
+ <include name="**\*" />
+ </fileset>
+ </delete>
+
+ <!-- Copy configuration file, and hard code references -->
+ <copy file="${sandcastle.dir}/Presentation/${sandcastle.style}/Configuration/Sandcastle.config"
+ tofile="${sandcastle.workingdir}/Sandcastle.config">
+ <filterchain>
+ <replacestring from=""..\..\" to=""${sandcastle.dir}\" />
+ <replacestring from=""..\" to=""${sandcastle.dir}\Examples\" />
+ <replacestring from="".\comments.xml" to=""${documentation.dir}\${project.name}.xml" />
+ <replacestring from=""%DXROOT%\Presentation\${sandcastle.style}\content\feedback_content.xml"" to=""${basedir}/src/main/sandcastle/feedback_content.xml"" />
+ </filterchain>
+ </copy>
+
+ <!-- Run MRefBuilder (introspection on assemblies) to create basic Reflection XML -->
+ <exec program="${sandcastle.mrefbuilder.exe}" workingdir="${sandcastle.workingdir}">
+ <arg value="${bin.intern.dir}/${project.name}.dll" />
+ <arg value="/out:reflection.int.xml" />
+ <arg value="/dep:${bin.extern.dir}\*.dll" />
+ </exec>
+
+ <!-- Create Reflection XML -->
+ <exec program="${sandcastle.xsltransform.exe}" workingdir="${sandcastle.workingdir}">
+ <arg value="/xsl:"${sandcastle.productiontransforms.dir}\ApplyVSDocModel.xsl"" if="${sandcastle.style != 'prototype'}" />
+ <arg value="/xsl:"${sandcastle.productiontransforms.dir}\ApplyPrototypeDocModel.xsl"" if="${sandcastle.style == 'prototype'}" />
+ <arg value="/xsl:"${sandcastle.productiontransforms.dir}\AddFriendlyFilenames.xsl"" /> <!-- if="${sandcastle.style != 'prototype'}" /> -->
+ <arg value="/xsl:"${sandcastle.productiontransforms.dir}\AddGuidFilenames.xsl"" if="${sandcastle.style == 'disabled'}" />
+ <arg value="reflection.int.xml" />
+ <arg value="/out:reflection.xml" />
+ <arg value="/arg:IncludeAllMembersTopic=true" />
+ <arg value="/arg:IncludeInheritedOverloadTopics=true" />
+ </exec>
+
+ <!-- Create Manifest (list of Topics) -->
+ <exec program="${sandcastle.xsltransform.exe}" workingdir="${sandcastle.workingdir}">
+ <arg value="/xsl:"${sandcastle.productiontransforms.dir}\ReflectionToManifest.xsl"" />
+ <arg value="reflection.xml" />
+ <arg value="/out:manifest.xml" />
+ </exec>
+
+ <!-- Create Output Environment -->
+ <mkdir dir="${sandcastle.output.dir}" />
+ <mkdir dir="${sandcastle.output.dir}/html" />
+ <copy todir="${sandcastle.output.dir}">
+ <fileset basedir="${sandcastle.dir}/Presentation/${sandcastle.style}">
+ <include name="icons/*" />
+ <include name="media/*" />
+ <include name="scripts/*" />
+ <include name="styles/*" />
+ </fileset>
+ </copy>
+
+ <!-- Run BuildAssembler (create html topic files) -->
+ <exec program="${sandcastle.buildassembler.exe}" workingdir="${sandcastle.workingdir}">
+ <arg value="/config:Sandcastle.config" />
+ <arg value="manifest.xml" />
+ </exec>
+ </target>
+
+ <target name="sandcastle-all" description="Generate all formats of the Sandcastle documentation files.">
+ <foreach item="String" in="vs2005,prototype,hana" delim="," property="sandcastle.style">
+ <call target="sandcastle" />
+ </foreach>
+ </target>
+</project>
diff --git a/nant.build b/nant.build
new file mode 100644
index 0000000..0912aa5
--- /dev/null
+++ b/nant.build
@@ -0,0 +1,189 @@
+<?xml version="1.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.
+-->
+<project name="Apache.NMS.XMS" default="default" xmlns="http://nant.sourceforge.net/release/0.85/nant.xsd">
+ <!-- ============================================================================================ -->
+ <!-- I N I T I A L I Z A T I O N -->
+ <!-- ============================================================================================ -->
+ <property name="basedir" value="${project::get-base-directory()}" />
+ <property name="project.name" value="Apache.NMS.XMS" />
+ <property name="project.group" value="org.apache.activemq" />
+ <property name="project.version" value="1.8.0" unless="${property::exists('project.version')}" />
+ <property name="project.release.type" value="SNAPSHOT" unless="${property::exists('project.release.type')}" />
+ <property name="project.short_description" value="Apache NMS for XMS Class Library" />
+ <property name="project.description" value="Apache NMS for XMS Class Library (.Net Messaging Library Implementation): An implementation of the NMS API for XMS" />
+ <!-- The XMS module is not CLS compliant yet -->
+ <property name="project.cls.compliant" value="false" />
+ <!-- Repository organized as: organization/module/version/plaform/artifact, platform might be something like 'all' or 'net-4.0/release' -->
+ <property name="nunit.dll" value="${basedir}/lib/NUnit/${current.build.framework}/nunit.framework.dll" dynamic="true" />
+ <property name="Apache.NMS.dll" value="${basedir}/lib/Apache.NMS/${current.build.framework}/Apache.NMS.dll" dynamic="true" />
+ <property name="Apache.NMS.pdb" value="${basedir}/lib/Apache.NMS/${current.build.framework}/Apache.NMS.pdb" dynamic="true" />
+ <!--<property name="Apache.NMS.Test.dll" value="${basedir}/lib/Apache.NMS/${current.build.framework}//Apache.NMS.Test.dll" dynamic="true" />-->
+ <!--<property name="Apache.NMS.Test.pdb" value="${basedir}/lib/Apache.NMS/${current.build.framework}/Apache.NMS.Test.pdb" dynamic="true" />-->
+ <property name="IBM.XMS.dll" value="${basedir}/lib/IBM.XMS/${current.build.framework}/IBM.XMS.dll" dynamic="true" />
+ <property name="IBM.XMS.Impl.dll" value="${basedir}/lib/IBM.XMS/${current.build.framework}/IBM.XMS.Impl.dll" dynamic="true" />
+ <property name="IBM.XMS.Core.dll" value="${basedir}/lib/IBM.XMS/${current.build.framework}/IBM.XMS.Core.dll" dynamic="true" />
+ <property name="IBM.XMS.Util.dll" value="${basedir}/lib/IBM.XMS/${current.build.framework}/IBM.XMS.Util.dll" dynamic="true" />
+ <property name="IBM.XMS.NLS.dll" value="${basedir}/lib/IBM.XMS/${current.build.framework}/IBM.XMS.NLS.dll" dynamic="true" />
+ <property name="IBM.XMS.Provider.dll" value="${basedir}/lib/IBM.XMS/${current.build.framework}/IBM.XMS.Provider.dll" dynamic="true" />
+ <property name="IBM.XMS.Client.Impl.dll" value="${basedir}/lib/IBM.XMS/${current.build.framework}/IBM.XMS.Client.Impl.dll" dynamic="true" />
+ <property name="IBM.XMS.Client.WMQ.dll" value="${basedir}/lib/IBM.XMS/${current.build.framework}/IBM.XMS.Client.WMQ.dll" dynamic="true" />
+ <property name="IBM.XMS.Admin.dll" value="${basedir}/lib/IBM.XMS/${current.build.framework}/IBM.XMS.Admin.dll" dynamic="true" />
+ <property name="IBM.XMS.Admin.Objects.dll" value="${basedir}/lib/IBM.XMS/${current.build.framework}/IBM.XMS.Admin.Objects.dll" dynamic="true" />
+ <property name="IBM.XMS.Comms.dll" value="${basedir}/lib/IBM.XMS/${current.build.framework}/IBM.XMS.Comms.dll" dynamic="true" />
+ <property name="IBM.XMS.Comms.RMM.dll" value="${basedir}/lib/IBM.XMS/${current.build.framework}/IBM.XMS.Comms.RMM.dll" dynamic="true" />
+ <property name="IBM.XMS.Comms.SSL.dll" value="${basedir}/lib/IBM.XMS/${current.build.framework}/IBM.XMS.Comms.SSL.dll" dynamic="true" />
+ <property name="IBM.XMS.Formats.JMF.dll" value="${basedir}/lib/IBM.XMS/${current.build.framework}/IBM.XMS.Formats.JMF.dll" dynamic="true" />
+ <property name="IBM.XMS.Formats.MFP.dll" value="${basedir}/lib/IBM.XMS/${current.build.framework}/IBM.XMS.Formats.MFP.dll" dynamic="true" />
+ <property name="IBM.XMS.Match.dll" value="${basedir}/lib/IBM.XMS/${current.build.framework}/IBM.XMS.Match.dll" dynamic="true" />
+ <property name="IBM.XMS.SIB.dll" value="${basedir}/lib/IBM.XMS/${current.build.framework}/IBM.XMS.SIB.dll" dynamic="true" />
+ <property name="IBM.XMS.WCF.dll" value="${basedir}/lib/IBM.XMS/${current.build.framework}/IBM.XMS.WCF.dll" dynamic="true" />
+ <property name="IBM.XMS.WCF.NLS.dll" value="${basedir}/lib/IBM.XMS/${current.build.framework}/IBM.XMS.WCF.NLS.dll" dynamic="true" />
+ <property name="IBM.XMS.WMQI.dll" value="${basedir}/lib/IBM.XMS/${current.build.framework}/IBM.XMS.WMQI.dll" dynamic="true" />
+ <property name="NUnit.Projectfile" value="Apache.NMS.XMS.Test.nunit" />
+ <!-- Skip certain frameworks, since IBM XMS client is not supported on those platforms. -->
+ <property name="build.netcf-2.0.skip" value="true" />
+ <property name="build.netcf-3.5.skip" value="true" />
+ <property name="build.mono-2.0.skip" value="true" />
+ <!-- Possibly supported (cf. http://stackoverflow.com/questions/10138267/ibm-mqs-net-xms-and-mono) but not tested -->
+ <property name="build.mono-4.0.skip" value="true" />
+ <!-- Possibly supported (cf. http://stackoverflow.com/questions/10138267/ibm-mqs-net-xms-and-mono) but not tested -->
+ <property name="build.net-2.0.skip" value="true" />
+ <!-- Possibly supported but not tested -->
+ <property name="build.net-3.5.skip" value="true" />
+ <!-- Possibly supported but not tested -->
+ <target name="vendor-init" description="Initializes Vendor library from local repository.">
+ <!--
+ Vendor specific info. The prefix of 'vendor.apache.org' is taken from the property
+ 'vendor.fileset.names'. This comma-delimited list is iterated, and properties with
+ well-known suffixes are used to access and copy down vendor file dependencies.
+ -->
+ <property name="vendor.fileset.names" value="vendor.apache.org,vendor.nunit.org,vendor.ibm.org" />
+ <!-- Property grouping for 'vendor.apache.org' -->
+ <property name="vendor.apache.org.name" value="Apache.NMS" />
+ <property name="vendor.apache.org.group" value="org.apache.activemq" />
+ <property name="vendor.apache.org.version" value="1.8.0" />
+ <property name="vendor.apache.org.filenames" value="Apache.NMS.dll,Apache.NMS.pdb,Apache.NMS.Test.dll,Apache.NMS.Test.pdb" />
+ <!-- Property grouping for 'vendor.nunit.org' -->
+ <property name="vendor.nunit.org.name" value="NUnit" />
+ <property name="vendor.nunit.org.group" value="org.nunit" />
+ <property name="vendor.nunit.org.version" value="2.5.8" />
+ <property name="vendor.nunit.org.filenames" value="nunit.framework.dll" />
+ <!-- Property grouping for 'vendor.ibm.org' -->
+ <property name="vendor.ibm.org.name" value="IBM.XMS" />
+ <property name="vendor.ibm.org.group" value="org.ibm.xms" />
+ <property name="vendor.ibm.org.version" value="8.0.0" />
+ <property name="vendor.ibm.org.filenames" value="IBM.XMS.dll,IBM.XMS.Impl.dll,IBM.XMS.Core.dll,IBM.XMS.Util.dll,IBM.XMS.NLS.dll,IBM.XMS.Provider.dll,IBM.XMS.Client.Impl.dll,IBM.XMS.Client.WMQ.dll,IBM.XMS.Admin.dll,IBM.XMS.Admin.Objects.dll,IBM.XMS.Comms.dll,IBM.XMS.Comms.RMM.dll,IBM.XMS.Comms.SSL.dll,IBM.XMS.Formats.JMF.dll,IBM.XMS.Formats.MFP.dll,IBM.XMS.Match.dll,IBM.XMS.SIB.dll,IBM.XMS.WCF.dll,IBM.XMS.WCF.NLS.dll,IBM.XMS.WMQI.dll" />
+ </target>
+ <target name="dependency-init" description="Initializes build dependencies">
+ <assemblyfileset failonempty="true" id="dependencies">
+ <include name="${current.build.framework.assembly.dir}/mscorlib.dll" />
+ <include name="${current.build.framework.assembly.dir}/System.dll" />
+ <include name="${current.build.framework.assembly.dir}/System.Xml.dll" />
+ <include name="${IBM.XMS.dll}" />
+ <include name="${IBM.XMS.Impl.dll}" />
+ <include name="${IBM.XMS.Core.dll}" />
+ <include name="${IBM.XMS.Util.dll}" />
+ <include name="${IBM.XMS.NLS.dll}" />
+ <include name="${IBM.XMS.Provider.dll}" />
+ <include name="${IBM.XMS.Client.Impl.dll}" />
+ <include name="${IBM.XMS.Client.WMQ.dll}" />
+ <include name="${IBM.XMS.Admin.dll}" />
+ <include name="${IBM.XMS.Admin.Objects.dll}" />
+ <include name="${IBM.XMS.Comms.dll}" />
+ <include name="${IBM.XMS.Comms.RMM.dll}" />
+ <include name="${IBM.XMS.Comms.SSL.dll}" />
+ <include name="${IBM.XMS.Formats.JMF.dll}" />
+ <include name="${IBM.XMS.Formats.MFP.dll}" />
+ <include name="${IBM.XMS.Match.dll}" />
+ <include name="${IBM.XMS.SIB.dll}" />
+ <include name="${IBM.XMS.WCF.dll}" />
+ <include name="${IBM.XMS.WCF.NLS.dll}" />
+ <include name="${IBM.XMS.WMQI.dll}" />
+ <include name="${Apache.NMS.dll}" />
+ </assemblyfileset>
+ <assemblyfileset failonempty="true" id="test.dependencies">
+ <include name="${current.build.framework.assembly.dir}/mscorlib.dll" />
+ <include name="${current.build.framework.assembly.dir}/System.dll" />
+ <include name="${current.build.framework.assembly.dir}/System.Xml.dll" />
+ <include name="${IBM.XMS.dll}" />
+ <include name="${IBM.XMS.Impl.dll}" />
+ <include name="${IBM.XMS.Core.dll}" />
+ <include name="${IBM.XMS.Util.dll}" />
+ <include name="${IBM.XMS.NLS.dll}" />
+ <include name="${IBM.XMS.Provider.dll}" />
+ <include name="${IBM.XMS.Client.Impl.dll}" />
+ <include name="${IBM.XMS.Client.WMQ.dll}" />
+ <include name="${IBM.XMS.Admin.dll}" />
+ <include name="${IBM.XMS.Admin.Objects.dll}" />
+ <include name="${IBM.XMS.Comms.dll}" />
+ <include name="${IBM.XMS.Comms.RMM.dll}" />
+ <include name="${IBM.XMS.Comms.SSL.dll}" />
+ <include name="${IBM.XMS.Formats.JMF.dll}" />
+ <include name="${IBM.XMS.Formats.MFP.dll}" />
+ <include name="${IBM.XMS.Match.dll}" />
+ <include name="${IBM.XMS.SIB.dll}" />
+ <include name="${IBM.XMS.WCF.dll}" />
+ <include name="${IBM.XMS.WCF.NLS.dll}" />
+ <include name="${IBM.XMS.WMQI.dll}" />
+ <include name="${Apache.NMS.dll}" />
+ <!--<include name="${Apache.NMS.Test.dll}" />-->
+ <include name="${build.bin.dir}/${project.name}.dll" />
+ <include name="${nunit.dll}" />
+ </assemblyfileset>
+ <fileset id="content.filenames">
+ <include name="LICENSE.txt" />
+ <include name="NOTICE.txt" />
+ <include name="nmsprovider-*.config" />
+ <include name="${IBM.XMS.dll}" />
+ <include name="${IBM.XMS.Impl.dll}" />
+ <include name="${IBM.XMS.Core.dll}" />
+ <include name="${IBM.XMS.Util.dll}" />
+ <include name="${IBM.XMS.NLS.dll}" />
+ <include name="${IBM.XMS.Provider.dll}" />
+ <include name="${IBM.XMS.Client.Impl.dll}" />
+ <include name="${IBM.XMS.Client.WMQ.dll}" />
+ <include name="${IBM.XMS.Admin.dll}" />
+ <include name="${IBM.XMS.Admin.Objects.dll}" />
+ <include name="${IBM.XMS.Comms.dll}" />
+ <include name="${IBM.XMS.Comms.RMM.dll}" />
+ <include name="${IBM.XMS.Comms.SSL.dll}" />
+ <include name="${IBM.XMS.Formats.JMF.dll}" />
+ <include name="${IBM.XMS.Formats.MFP.dll}" />
+ <include name="${IBM.XMS.Match.dll}" />
+ <include name="${IBM.XMS.SIB.dll}" />
+ <include name="${IBM.XMS.WCF.dll}" />
+ <include name="${IBM.XMS.WCF.NLS.dll}" />
+ <include name="${IBM.XMS.WMQI.dll}" />
+ <include name="${Apache.NMS.dll}" />
+ <include name="${Apache.NMS.pdb}" />
+ <!--<include name="${Apache.NMS.Test.dll}" />-->
+ <!--<include name="${Apache.NMS.Test.pdb}" />-->
+ <include name="${nunit.dll}" />
+ <include name="${NUnit.Projectfile}" />
+ </fileset>
+ <fileset id="install.filenames">
+ <include name="LICENSE.txt" />
+ <include name="NOTICE.txt" />
+ <include name="${build.bin.dir}/${project.name}.dll" />
+ <include name="${build.bin.dir}/${project.name}.pdb" />
+ </fileset>
+ </target>
+ <target name="default" depends="install-all" />
+ <!-- Load the common target definitions -->
+ <include buildfile="${basedir}/nant-common.xml" />
+</project>
diff --git a/package.ps1 b/package.ps1
new file mode 100644
index 0000000..6fbb79b
--- /dev/null
+++ b/package.ps1
@@ -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.
+
+$pkgname = "Apache.NMS.XMS"
+$pkgver = "1.8-SNAPSHOT"
+$configurations = "release", "debug"
+$frameworks = "net-4.0"
+
+write-progress "Creating package directory." "Initializing..."
+if(!(test-path package))
+{
+ md package
+}
+
+if(test-path build)
+{
+ pushd build
+
+ $pkgdir = "..\package"
+
+ write-progress "Packaging Application files." "Scanning..."
+ $zipfile = "$pkgdir\$pkgname-$pkgver-bin.zip"
+ zip -9 -u -j "$zipfile" ..\LICENSE.txt
+ zip -9 -u -j "$zipfile" ..\NOTICE.txt
+ foreach($configuration in $configurations)
+ {
+ foreach($framework in $frameworks)
+ {
+ zip -9 -u "$zipfile" "$framework\$configuration\$pkgname.dll"
+ zip -9 -u "$zipfile" "$framework\$configuration\$pkgname.xml"
+ zip -9 -u "$zipfile" "$framework\$configuration\xmsprovider*.config"
+ zip -9 -u "$zipfile" "$framework\$configuration\$pkgname.Test.dll"
+ zip -9 -u "$zipfile" "$framework\$configuration\$pkgname.Test.xml"
+ zip -9 -u "$zipfile" "$framework\$configuration\$pkgname.pdb"
+ zip -9 -u "$zipfile" "$framework\$configuration\$pkgname.Test.pdb"
+ }
+ }
+
+ popd
+}
+
+write-progress "Packaging Source code files." "Scanning..."
+$pkgdir = "package"
+$zipfile = "$pkgdir\$pkgname-$pkgver-src.zip"
+
+zip -9 -u "$zipfile" LICENSE.txt NOTICE.txt nant-common.xml nant.build package.ps1 vs2013-xms-test.csproj vs2013-xms.csproj vs2013-xms.sln
+zip -9 -u -r "$zipfile" keyfile src
+
+write-progress -Completed "Packaging" "Complete."
diff --git a/src/main/csharp/BytesMessage.cs b/src/main/csharp/BytesMessage.cs
new file mode 100644
index 0000000..bddfb0f
--- /dev/null
+++ b/src/main/csharp/BytesMessage.cs
@@ -0,0 +1,187 @@
+/*
+ * 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.
+ */
+using System;
+using Apache.NMS;
+using Apache.NMS.Util;
+using Apache.NMS.XMS.Util;
+using IBM.XMS;
+
+namespace Apache.NMS.XMS
+{
+ class BytesMessage : Apache.NMS.XMS.Message, Apache.NMS.IBytesMessage
+ {
+ public IBM.XMS.IBytesMessage xmsBytesMessage
+ {
+ get { return (IBM.XMS.IBytesMessage)this.xmsMessage; }
+ set { this.xmsMessage = value; }
+ }
+
+ public BytesMessage(IBM.XMS.IBytesMessage message)
+ : base(message)
+ {
+ }
+
+ #region IBytesMessage Members
+
+ public byte[] Content
+ {
+ get
+ {
+ int contentLength = (int) this.xmsBytesMessage.BodyLength;
+ byte[] msgContent = new byte[contentLength];
+
+ this.xmsBytesMessage.Reset();
+ this.xmsBytesMessage.ReadBytes(msgContent, contentLength);
+ return msgContent;
+ }
+
+ set
+ {
+ this.ReadOnlyBody = false;
+ this.xmsBytesMessage.ClearBody();
+ this.xmsBytesMessage.WriteBytes(value, 0, value.Length);
+ }
+ }
+
+ public long BodyLength
+ {
+ get { return this.xmsBytesMessage.BodyLength; }
+ }
+
+ public bool ReadBoolean()
+ {
+ return this.xmsBytesMessage.ReadBoolean();
+ }
+
+ public byte ReadByte()
+ {
+ return (byte) this.xmsBytesMessage.ReadByte();
+ }
+
+ public int ReadBytes(byte[] value, int length)
+ {
+ return this.xmsBytesMessage.ReadBytes(value, length);
+ }
+
+ public int ReadBytes(byte[] value)
+ {
+ return this.xmsBytesMessage.ReadBytes(value);
+ }
+
+ public char ReadChar()
+ {
+ return this.xmsBytesMessage.ReadChar();
+ }
+
+ public double ReadDouble()
+ {
+ return this.xmsBytesMessage.ReadDouble();
+ }
+
+ public short ReadInt16()
+ {
+ return this.xmsBytesMessage.ReadShort();
+ }
+
+ public int ReadInt32()
+ {
+ return this.xmsBytesMessage.ReadInt();
+ }
+
+ public long ReadInt64()
+ {
+ return this.xmsBytesMessage.ReadLong();
+ }
+
+ public float ReadSingle()
+ {
+ return this.xmsBytesMessage.ReadFloat();
+ }
+
+ public string ReadString()
+ {
+ return this.xmsBytesMessage.ReadUTF();
+ }
+
+ public void Reset()
+ {
+ this.xmsBytesMessage.Reset();
+ }
+
+ public void WriteBoolean(bool value)
+ {
+ this.xmsBytesMessage.WriteBoolean(value);
+ }
+
+ public void WriteByte(byte value)
+ {
+ this.xmsBytesMessage.WriteByte(value);
+ }
+
+ public void WriteBytes(byte[] value, int offset, int length)
+ {
+ this.xmsBytesMessage.WriteBytes(value, offset, length);
+ }
+
+ public void WriteBytes(byte[] value)
+ {
+ this.xmsBytesMessage.WriteBytes(value);
+ }
+
+ public void WriteChar(char value)
+ {
+ this.xmsBytesMessage.WriteChar(value);
+ }
+
+ public void WriteDouble(double value)
+ {
+ this.xmsBytesMessage.WriteDouble(value);
+ }
+
+ public void WriteInt16(short value)
+ {
+ this.xmsBytesMessage.WriteShort(value);
+ }
+
+ public void WriteInt32(int value)
+ {
+ this.xmsBytesMessage.WriteInt(value);
+ }
+
+ public void WriteInt64(long value)
+ {
+ this.xmsBytesMessage.WriteLong(value);
+ }
+
+ public void WriteObject(object value)
+ {
+ this.xmsBytesMessage.WriteObject(value);
+ }
+
+ public void WriteSingle(float value)
+ {
+ this.xmsBytesMessage.WriteFloat(value);
+ }
+
+ public void WriteString(string value)
+ {
+ this.xmsBytesMessage.WriteUTF(value);
+ }
+
+ #endregion
+ }
+}
diff --git a/src/main/csharp/Connection.cs b/src/main/csharp/Connection.cs
new file mode 100644
index 0000000..07ba2fd
--- /dev/null
+++ b/src/main/csharp/Connection.cs
@@ -0,0 +1,461 @@
+/*
+ * 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.
+ */
+using System;
+using Apache.NMS;
+using Apache.NMS.Util;
+using Apache.NMS.XMS.Util;
+using IBM.XMS;
+
+namespace Apache.NMS.XMS
+{
+ /// <summary>
+ /// Represents an NMS connection to IBM MQ.
+ /// </summary>
+ ///
+ public class Connection : Apache.NMS.IConnection
+ {
+ private Apache.NMS.AcknowledgementMode acknowledgementMode;
+ public readonly IBM.XMS.IConnection xmsConnection;
+ private IRedeliveryPolicy redeliveryPolicy;
+ private ConnectionMetaData metaData = null;
+ private readonly Atomic<bool> started = new Atomic<bool>(false);
+ private bool closed = false;
+ private bool disposed = false;
+
+ #region Constructors
+
+ /// <summary>
+ /// Constructs a connection object.
+ /// </summary>
+ public Connection(IBM.XMS.IConnection xmsConnection)
+ {
+ this.xmsConnection = xmsConnection;
+ this.xmsConnection.ExceptionListener = this.HandleXmsException;
+ }
+
+ /// <summary>
+ /// "Destructs" or "finalizes" a connection object.
+ /// </summary>
+ ~Connection()
+ {
+ Dispose(false);
+ }
+
+ #endregion
+
+ #region IStartable Members
+
+ /// <summary>
+ /// Starts message delivery for this connection.
+ /// </summary>
+ public void Start()
+ {
+ if(started.CompareAndSet(false, true))
+ {
+ try
+ {
+ this.xmsConnection.Start();
+ }
+ catch(Exception ex)
+ {
+ ExceptionUtil.WrapAndThrowNMSException(ex);
+ }
+ }
+ }
+
+ public bool IsStarted
+ {
+ get { return this.started.Value; }
+ }
+
+ #endregion
+
+ #region IStoppable Members
+
+ /// <summary>
+ /// Stop message delivery for this connection.
+ /// </summary>
+ public void Stop()
+ {
+ try
+ {
+ if(started.CompareAndSet(true, false))
+ {
+ this.xmsConnection.Stop();
+ }
+ }
+ catch(Exception ex)
+ {
+ ExceptionUtil.WrapAndThrowNMSException(ex);
+ }
+ }
+
+ #endregion
+
+ #region IConnection Members
+
+ /// <summary>
+ /// Creates a new session to work on this connection
+ /// </summary>
+ public Apache.NMS.ISession CreateSession()
+ {
+ return CreateSession(acknowledgementMode);
+ }
+
+ /// <summary>
+ /// Creates a new session to work on this connection
+ /// </summary>
+ public Apache.NMS.ISession CreateSession(
+ Apache.NMS.AcknowledgementMode mode)
+ {
+ try
+ {
+ bool isTransacted =
+ (mode == Apache.NMS.AcknowledgementMode.Transactional);
+ return XMSConvert.ToNMSSession(
+ this.xmsConnection.CreateSession(
+ isTransacted, XMSConvert.ToAcknowledgeMode(mode)));
+ }
+ catch(Exception ex)
+ {
+ ExceptionUtil.WrapAndThrowNMSException(ex);
+ return null;
+ }
+ }
+
+ public void Close()
+ {
+ lock(this)
+ {
+ if(closed)
+ {
+ return;
+ }
+
+ try
+ {
+ this.xmsConnection.ExceptionListener = null;
+ this.xmsConnection.Stop();
+ this.xmsConnection.Close();
+ }
+ catch(Exception ex)
+ {
+ ExceptionUtil.WrapAndThrowNMSException(ex);
+ }
+ finally
+ {
+ closed = true;
+ }
+ }
+ }
+
+ public void PurgeTempDestinations()
+ {
+ }
+
+ #endregion
+
+ #region IDisposable Members
+
+ public void Dispose()
+ {
+ Dispose(true);
+ GC.SuppressFinalize(this);
+ }
+
+ protected void Dispose(bool disposing)
+ {
+ if(disposed)
+ {
+ return;
+ }
+
+ if(disposing)
+ {
+ // Dispose managed code here.
+ }
+
+ try
+ {
+ Close();
+ }
+ catch
+ {
+ // Ignore errors.
+ }
+
+ disposed = true;
+ }
+
+ #endregion
+
+ #region Attributes
+
+ /// <summary>
+ /// The default timeout for network requests.
+ /// </summary>
+ public TimeSpan RequestTimeout
+ {
+ get { return Apache.NMS.NMSConstants.defaultRequestTimeout; }
+ set { }
+ }
+
+ public Apache.NMS.AcknowledgementMode AcknowledgementMode
+ {
+ get { return acknowledgementMode; }
+ set { acknowledgementMode = value; }
+ }
+
+ public string ClientId
+ {
+ get
+ {
+ try
+ {
+ return this.xmsConnection.ClientID;
+ }
+ catch(Exception ex)
+ {
+ ExceptionUtil.WrapAndThrowNMSException(ex);
+ return null;
+ }
+ }
+ set
+ {
+ try
+ {
+ this.xmsConnection.ClientID = value;
+ }
+ catch(Exception ex)
+ {
+ ExceptionUtil.WrapAndThrowNMSException(ex);
+ }
+ }
+ }
+
+ /// <summary>
+ /// Get/or set the redelivery policy for this connection.
+ /// </summary>
+ public IRedeliveryPolicy RedeliveryPolicy
+ {
+ get { return this.redeliveryPolicy; }
+ set { this.redeliveryPolicy = value; }
+ }
+
+ /// <summary>
+ /// Gets the Meta Data for the NMS Connection instance.
+ /// </summary>
+ public IConnectionMetaData MetaData
+ {
+ get { return this.metaData ?? (this.metaData = new ConnectionMetaData()); }
+ }
+
+ #endregion
+
+ #region Properties
+
+ // http://www-01.ibm.com/support/knowledgecenter/SSFKSJ_8.0.0/com.ibm.mq.msc.doc/props_conn.htm?lang=en
+
+ #region Common properties
+
+ /// <summary>
+ /// This property is used to obtain the name of the queue manager
+ /// to which it is connected.
+ /// </summary>
+ public string ResolvedQueueManagerName
+ {
+ get { return this.xmsConnection.GetStringProperty(XMSC.WMQ_RESOLVED_QUEUE_MANAGER); }
+ set { this.xmsConnection.SetStringProperty(XMSC.WMQ_RESOLVED_QUEUE_MANAGER, value); }
+ }
+
+ /// <summary>
+ /// This property is populated with the ID of the queue manager
+ /// after the connection.
+ /// </summary>
+ public string ResolvedQueueManagerId
+ {
+ get { return this.xmsConnection.GetStringProperty(XMSC.WMQ_RESOLVED_QUEUE_MANAGER_ID); }
+ set { this.xmsConnection.SetStringProperty(XMSC.WMQ_RESOLVED_QUEUE_MANAGER_ID, value); }
+ }
+
+ #endregion
+
+ #region WPM-specific properties
+
+ /// <summary>
+ /// The communications protocol used for the connection to the
+ /// messaging engine. This property is read-only.
+ /// </summary>
+ public Int32 XMSConnectionProtocol
+ {
+ get { return this.xmsConnection.GetIntProperty(XMSC.WPM_CONNECTION_PROTOCOL); }
+ }
+
+ /// <summary>
+ /// The communications protocol used for the connection to the
+ /// messaging engine. This property is read-only.
+ /// </summary>
+ public WPMConnectionProtocol ConnectionProtocol
+ {
+ get { return XMSConvert.ToWPMConnectionProtocol(this.XMSConnectionProtocol); }
+ }
+
+ /// <summary>
+ /// The host name or IP address of the system that contains the
+ /// messaging engine to which the application is connected. This
+ /// property is read-only.
+ /// </summary>
+ public string HostName
+ {
+ get { return this.xmsConnection.GetStringProperty(XMSC.WPM_HOST_NAME); }
+ }
+
+ /// <summary>
+ /// The name of the messaging engine to which the application is
+ /// connected. This property is read-only.
+ /// </summary>
+ public string MessagingEngineName
+ {
+ get { return this.xmsConnection.GetStringProperty(XMSC.WPM_ME_NAME); }
+ }
+
+ /// <summary>
+ /// The number of the port listened on by the messaging engine to
+ /// which the application is connected. This property is read-only.
+ /// </summary>
+ public Int32 Port
+ {
+ get { return this.xmsConnection.GetIntProperty(XMSC.WPM_PORT); }
+ }
+
+ #endregion
+
+ #endregion
+
+ #region Event Listeners, Handlers and Delegates
+
+ /// <summary>
+ /// A delegate that can receive transport level exceptions.
+ /// </summary>
+ public event ExceptionListener ExceptionListener;
+
+ /// <summary>
+ /// Handles XMS connection exceptions.
+ /// </summary>
+ private void HandleXmsException(Exception exception)
+ {
+ if(ExceptionListener != null)
+ {
+ // Return codes MQRC_RECONNECTING and MQRC_RECONNECTED
+ // are not defined in XMS.
+ // const int MQRC_RECONNECTING = 2544;
+ // const int MQRC_RECONNECTED = 2545;
+ // According to http://www-01.ibm.com/support/knowledgecenter/#!/SSFKSJ_8.0.0/com.ibm.mq.con.doc/q017800_.htm
+ // Except for JMS and XMS clients, if a client application has
+ // access to reconnection options, it can also create an event
+ // handler to handle reconnection events.
+ ExceptionListener(exception);
+ }
+ else
+ {
+ Apache.NMS.Tracer.Error(exception);
+ }
+ }
+
+ /// <summary>
+ /// An asynchronous listener that is notified when a fault tolerant
+ /// connection has been interrupted.
+ /// </summary>
+ /// <remarks>
+ /// IBM XMS does not handle disconnection / reconnection notifications.
+ /// This delegate will never be called.
+ /// </remarks>
+ public event ConnectionInterruptedListener ConnectionInterruptedListener;
+
+ private void HandleTransportInterrupted()
+ {
+ Tracer.Debug("Transport has been interrupted.");
+
+ if(this.ConnectionInterruptedListener != null && !this.closed)
+ {
+ try
+ {
+ this.ConnectionInterruptedListener();
+ }
+ catch
+ {
+ }
+ }
+ }
+
+ /// <summary>
+ /// An asynchronous listener that is notified when a fault tolerant
+ /// connection has been resumed.
+ /// </summary>
+ /// <remarks>
+ /// IBM XMS does not handle disconnection / reconnection notifications.
+ /// This delegate will never be called.
+ /// </remarks>
+ public event ConnectionResumedListener ConnectionResumedListener;
+
+ private void HandleTransportResumed()
+ {
+ Tracer.Debug("Transport has resumed normal operation.");
+
+ if(this.ConnectionResumedListener != null && !this.closed)
+ {
+ try
+ {
+ this.ConnectionResumedListener();
+ }
+ catch
+ {
+ }
+ }
+ }
+
+ private ConsumerTransformerDelegate consumerTransformer;
+ /// <summary>
+ /// A Delegate that is called each time a Message is dispatched to allow the client to do
+ /// any necessary transformations on the received message before it is delivered. The
+ /// ConnectionFactory sets the provided delegate instance on each Connection instance that
+ /// is created from this factory, each connection in turn passes the delegate along to each
+ /// Session it creates which then passes that along to the Consumers it creates.
+ /// </summary>
+ public ConsumerTransformerDelegate ConsumerTransformer
+ {
+ get { return this.consumerTransformer; }
+ set { this.consumerTransformer = value; }
+ }
+
+ private ProducerTransformerDelegate producerTransformer;
+ /// <summary>
+ /// A delegate that is called each time a Message is sent from this Producer which allows
+ /// the application to perform any needed transformations on the Message before it is sent.
+ /// The ConnectionFactory sets the provided delegate instance on each Connection instance that
+ /// is created from this factory, each connection in turn passes the delegate along to each
+ /// Session it creates which then passes that along to the Producers it creates.
+ /// </summary>
+ public ProducerTransformerDelegate ProducerTransformer
+ {
+ get { return this.producerTransformer; }
+ set { this.producerTransformer = value; }
+ }
+
+ #endregion
+ }
+}
diff --git a/src/main/csharp/ConnectionFactory.cs b/src/main/csharp/ConnectionFactory.cs
new file mode 100644
index 0000000..35863bb
--- /dev/null
+++ b/src/main/csharp/ConnectionFactory.cs
@@ -0,0 +1,1502 @@
+/*
+ * 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.
+ */
+using System;
+using System.Collections;
+using System.Collections.Specialized;
+using Apache.NMS.XMS.Util;
+using Apache.NMS.Policies;
+using Apache.NMS.Util;
+using IBM.XMS;
+
+namespace Apache.NMS.XMS
+{
+ /// <summary>
+ /// A Factory that can establish NMS connections to IBM MQ.
+ /// </summary>
+ /// <remarks>
+ /// XMS connection factories can either be created from definitions
+ /// administered in a repository ("administered object"), or created
+ /// from an <c>XMSFactoryFactory</c>.
+ ///
+ /// Addressable repositories for administered objects are:
+ /// - file system context
+ /// (URL format: "file://Path").
+ /// - LDAP context
+ /// (URL format: "ldap:[Hostname][:Port]["/"[DistinguishedName]]").
+ /// - WSS context:
+ /// (URL format: "http://Url", "cosnaming://Url" or "wsvc://Url").
+ ///
+ /// A non-administered object is instanciated for a specific protocol:
+ /// - WebSphere Application Server Service Integration Bus
+ /// (protocol prefix: <c>"wpm:"</c>; XMS key: <c>XMSC.CT_WPM</c>).
+ /// - IBM Integration Bus using WebSphere MQ Real-Time Transport
+ /// (protocol prefix: <c>"rtt:"</c>; XMS key: <c>XMSC.CT_RTT</c>).
+ /// - WebSphere MQ queue manager
+ /// (protocol prefix: <c>"wmq:"</c>; XMS key: <c>XMSC.CT_WMQ</c>).
+ /// </remarks>
+ public class ConnectionFactory : Apache.NMS.IConnectionFactory
+ {
+ public IBM.XMS.IConnectionFactory xmsConnectionFactory = null;
+
+ private Uri brokerUri = null;
+ private IRedeliveryPolicy redeliveryPolicy = new RedeliveryPolicy();
+
+ #region Constructors
+
+ /// <summary>
+ /// Constructs a <c>ConnectionFactory</c> object using default values.
+ /// </summary>
+ public ConnectionFactory()
+ : this(new Uri("xms:wmq:"))
+ {
+ }
+
+ /// <summary>
+ /// Constructs a <c>ConnectionFactory</c> object.
+ /// </summary>
+ /// <param name="brokerUri">Factory URI.</param>
+ public ConnectionFactory(Uri brokerUri)
+ {
+ try
+ {
+ // BrokerUri will construct the xmsConnectionFactory
+ this.BrokerUri = brokerUri;
+ }
+ catch(Exception ex)
+ {
+ Apache.NMS.Tracer.DebugFormat(
+ "Exception instantiating IBM.XMS.ConnectionFactory: {0}",
+ ex.Message);
+ ExceptionUtil.WrapAndThrowNMSException(ex);
+ }
+ // In case WrapAndThrowNMSException masks the exception
+ if(this.xmsConnectionFactory == null)
+ {
+ throw new Apache.NMS.NMSException(
+ "Error instantiating XMS connection factory object.");
+ }
+ }
+
+ /// <summary>
+ /// Constructs the internal <c>ConnectionFactory</c> object from the
+ /// parameters specified in the input URI.
+ /// </summary>
+ /// <param name="factoryUri">Factory URI.</param>
+ /// <returns>URI stripped out from overridable property values.
+ /// </returns>
+ private Uri CreateConnectionFactoryFromURI(Uri factoryUri)
+ {
+ try
+ {
+ // Remove "xms:" scheme prefix
+ string originalString = factoryUri.OriginalString;
+ factoryUri = new Uri(originalString.Substring(
+ originalString.IndexOf(":") + 1));
+
+ // Parse URI properties
+ StringDictionary properties = URISupport.ParseQuery(
+ factoryUri.Query);
+
+ // The URI scheme specifies either the repository of
+ // administered objects where the ConnectionFactory object
+ // is defined, or the target connection type for
+ // non-administered objects.
+ switch(factoryUri.Scheme.ToLower())
+ {
+ case "rtt":
+ case "wmq":
+ case "wpm":
+ CreateNonAdministeredConnectionFactory(
+ factoryUri, properties);
+ break;
+ case "http":
+ case "ldap":
+ case "cosnaming":
+ case "wsvc":
+ default:
+ CreateAdministeredConnectionFactory(
+ factoryUri, properties);
+ break;
+ }
+
+ // Configure the instanciated connection factory
+ ConfigureConnectionFactory(factoryUri, properties);
+
+ return new Uri("xms:" + factoryUri.Scheme);
+ }
+ catch(Exception ex)
+ {
+ ExceptionUtil.WrapAndThrowNMSException(ex);
+ return null;
+ }
+ }
+
+ /// <summary>
+ /// Creates a connection factory from the object definition retrieved
+ /// from a repository of administered objects.
+ /// </summary>
+ /// <param name="factoryUri">Factory URI.</param>
+ /// <param name="properties">URI properties.</param>
+ private void CreateAdministeredConnectionFactory(
+ Uri factoryUri, StringDictionary properties)
+ {
+ // The initial context URL is the non-query part of the factory URI
+ string icUrl = factoryUri.OriginalString.Substring(0,
+ factoryUri.OriginalString.IndexOf('?'));
+
+ // Extract other InitialContext property values from URI
+ string icPrefix = "ic.";
+ StringDictionary icProperties = URISupport.ExtractProperties(
+ properties, icPrefix);
+
+ // Initialize environment Hashtable
+ Hashtable environment = new Hashtable();
+ environment[XMSC.IC_URL] = icUrl;
+ foreach(DictionaryEntry de in icProperties)
+ {
+ string key = ((string)de.Key).Substring(icPrefix.Length);
+ //TODO: convert "environment." attribute types.
+ environment[key] = de.Value;
+ }
+
+ // Create an InitialContext
+ InitialContext ic = new InitialContext(environment);
+
+ // Extract administered object name
+ string objectNameKey = "object.Name";
+ if(!properties.ContainsKey(objectNameKey))
+ {
+ throw new NMSException(string.Format(
+ "URI attribute {0} must be specified.", objectNameKey));
+ }
+ string objectName = properties[objectNameKey];
+ properties.Remove(objectNameKey);
+
+ // Lookup for object
+ this.xmsConnectionFactory =
+ (IBM.XMS.IConnectionFactory)ic.Lookup(objectName);
+ }
+
+ /// <summary>
+ /// Creates a non-administered connection factory.
+ /// </summary>
+ /// <param name="factoryUri">Factory URI.</param>
+ /// <param name="properties">URI properties.</param>
+ private void CreateNonAdministeredConnectionFactory(
+ Uri factoryUri, StringDictionary properties)
+ {
+ // Get an XMS factory factory for the requested protocol
+ IBM.XMS.XMSFactoryFactory xmsFactoryFactory = null;
+ string scheme = factoryUri.Scheme.ToLower();
+ switch(scheme)
+ {
+ case "rtt":
+ xmsFactoryFactory =
+ IBM.XMS.XMSFactoryFactory.GetInstance(IBM.XMS.XMSC.CT_RTT);
+
+ if(!string.IsNullOrEmpty(factoryUri.Host))
+ {
+ this.RTTHostName = factoryUri.Host;
+ }
+
+ if(factoryUri.Port != -1)
+ {
+ this.RTTPort = factoryUri.Port;
+ }
+ break;
+
+ case "wmq":
+ xmsFactoryFactory =
+ IBM.XMS.XMSFactoryFactory.GetInstance(IBM.XMS.XMSC.CT_WMQ);
+ break;
+
+ case "wpm":
+ xmsFactoryFactory =
+ IBM.XMS.XMSFactoryFactory.GetInstance(IBM.XMS.XMSC.CT_WPM);
+ break;
+ }
+
+ // Create the connection factory
+ this.xmsConnectionFactory =
+ xmsFactoryFactory.CreateConnectionFactory();
+
+ // For RTT and WMQ protocols, set the host name and port if
+ // they are specified
+ switch(scheme)
+ {
+ case "rtt":
+ if(!string.IsNullOrEmpty(factoryUri.Host))
+ {
+ this.RTTHostName = factoryUri.Host;
+ }
+
+ if(factoryUri.Port != -1)
+ {
+ this.RTTPort = factoryUri.Port;
+ }
+ break;
+
+ case "wmq":
+ if(!string.IsNullOrEmpty(factoryUri.Host))
+ {
+ this.WMQHostName = factoryUri.Host;
+ }
+
+ if(factoryUri.Port != -1)
+ {
+ this.WMQPort = factoryUri.Port;
+ }
+ break;
+ }
+ }
+
+ /// <summary>
+ /// Configures the connection factory.
+ /// </summary>
+ /// <param name="factoryUri">Factory URI.</param>
+ /// <param name="properties">URI properties.</param>
+ private void ConfigureConnectionFactory(
+ Uri factoryUri, StringDictionary properties)
+ {
+ if(properties != null && properties.Count > 0)
+ {
+ IntrospectionSupport.SetProperties(this, properties);
+ }
+ }
+
+ #endregion
+
+ #region Redelivery Policy
+
+ /// <summary>
+ /// Get/or set the redelivery policy that new IConnection objects are
+ /// assigned upon creation.
+ /// </summary>
+ public IRedeliveryPolicy RedeliveryPolicy
+ {
+ get { return this.redeliveryPolicy; }
+ set
+ {
+ if(value != null)
+ {
+ this.redeliveryPolicy = value;
+ }
+ }
+ }
+
+ #endregion
+
+ #region Properties (configure via URL parameters)
+
+ // http://www-01.ibm.com/support/knowledgecenter/?lang=en#!/SSFKSJ_8.0.0/com.ibm.mq.msc.doc/props_connf.htm
+
+ #region Connection Factory Properties common to all protocols
+
+ /// <summary>
+ /// The client identifier for a connection.
+ /// </summary>
+ [UriAttribute("factory.ClientId")]
+ public string ClientId
+ {
+ get { return this.xmsConnectionFactory.GetStringProperty(XMSC.CLIENT_ID); }
+ set { this.xmsConnectionFactory.SetStringProperty(XMSC.CLIENT_ID, value); }
+ }
+
+ /// <summary>
+ /// The type of messaging server to which an application connects.
+ /// </summary>
+ [UriAttribute("factory.XMSConnectionType")]
+ public Int32 XMSConnectionType
+ {
+ get { return this.xmsConnectionFactory.GetIntProperty(XMSC.CONNECTION_TYPE); }
+ set { this.xmsConnectionFactory.SetIntProperty(XMSC.CONNECTION_TYPE, value); }
+ }
+
+ /// <summary>
+ /// The type of messaging server to which an application connects.
+ /// </summary>
+ [UriAttribute("factory.ConnectionType")]
+ public ConnectionType ConnectionType
+ {
+ get { return XMSConvert.ToConnectionType(this.XMSConnectionType); }
+ set { this.XMSConnectionType = XMSConvert.ToXMSConnectionType(value); }
+ }
+
+ /// <summary>
+ /// A user identifier that can be used to authenticate the application
+ /// when it attempts to connect to a messaging server.
+ /// </summary>
+ [UriAttribute("factory.UserId")]
+ public string UserId
+ {
+ get { return this.xmsConnectionFactory.GetStringProperty(XMSC.USERID); }
+ set { this.xmsConnectionFactory.SetStringProperty(XMSC.USERID, value); }
+ }
+
+ /// <summary>
+ /// A password that can be used to authenticate the application when it
+ /// attempts to connect to a messaging server.
+ /// </summary>
+ [UriAttribute("factory.XMSPassword")]
+ public byte[] XMSPassword
+ {
+ get { return this.xmsConnectionFactory.GetBytesProperty(XMSC.PASSWORD); }
+ set { this.xmsConnectionFactory.SetBytesProperty(XMSC.PASSWORD, value); }
+ }
+
+ /// <summary>
+ /// A password that can be used to authenticate the application when it
+ /// attempts to connect to a messaging server, specified as a string.
+ /// </summary>
+ [UriAttribute("factory.Password")]
+ public string Password
+ {
+ get { return Convert.ToBase64String(this.XMSPassword); }
+ set { this.XMSPassword = Convert.FromBase64String(value); }
+ }
+
+ /// <summary>
+ /// This property determines whether XMS informs an ExceptionListener
+ /// only when a connection is broken, or when any exception occurs
+ /// asynchronously to an XMS API call.
+ /// </summary>
+ /// <remarks>
+ /// This property applies to all Connections created from this
+ /// ConnectionFactory that have an ExceptionListener registered.
+ /// </remarks>
+ [UriAttribute("factory.XMSAsynchronousExceptions")]
+ public Int32 XMSAsynchronousExceptions
+ {
+ get { return this.xmsConnectionFactory.GetIntProperty(XMSC.ASYNC_EXCEPTIONS); }
+ set { this.xmsConnectionFactory.SetIntProperty(XMSC.ASYNC_EXCEPTIONS, value); }
+ }
+
+ /// <summary>
+ /// This property determines whether XMS informs an
+ /// <c>ExceptionListener</c> only when a connection is broken, or when
+ /// any exception occurs asynchronously to an XMS API call.
+ /// </summary>
+ [UriAttribute("factory.AsynchronousExceptions")]
+ public AsynchronousExceptions AsynchronousExceptions
+ {
+ get { return XMSConvert.ToAsynchronousExceptions(this.XMSAsynchronousExceptions); }
+ set { this.XMSAsynchronousExceptions = XMSConvert.ToXMSAsynchronousExceptions(value); }
+ }
+
+ #endregion
+
+ #region RTT-specific properties
+
+ /// <summary>
+ /// The communications protocol used for a real-time connection to a broker.
+ /// </summary>
+ [UriAttribute("rtt.XMSConnectionProtocol")]
+ public Int32 XMSConnectionProtocol
+ {
+ get { return this.xmsConnectionFactory.GetIntProperty(XMSC.RTT_CONNECTION_PROTOCOL); }
+ set { this.xmsConnectionFactory.SetIntProperty(XMSC.RTT_CONNECTION_PROTOCOL, value); }
+ }
+
+ /// <summary>
+ /// The communications protocol used for a real-time connection to a broker.
+ /// </summary>
+ [UriAttribute("rtt.ConnectionProtocol")]
+ public RTTConnectionProtocol ConnectionProtocol
+ {
+ get { return XMSConvert.ToRTTConnectionProtocol(this.XMSConnectionProtocol); }
+ set { this.XMSConnectionProtocol = XMSConvert.ToXMSRTTConnectionProtocol(value); }
+ }
+
+ /// <summary>
+ /// The host name or IP address of the system on which a broker runs.
+ /// </summary>
+ [UriAttribute("rtt.HostName")]
+ public string RTTHostName
+ {
+ get { return this.xmsConnectionFactory.GetStringProperty(XMSC.RTT_HOST_NAME); }
+ set { this.xmsConnectionFactory.SetStringProperty(XMSC.RTT_HOST_NAME, value); }
+ }
+
+ /// <summary>
+ /// The number of the port on which a broker listens for incoming requests.
+ /// </summary>
+ [UriAttribute("rtt.Port")]
+ public Int32 RTTPort
+ {
+ get { return this.xmsConnectionFactory.GetIntProperty(XMSC.RTT_PORT); }
+ set { this.xmsConnectionFactory.SetIntProperty(XMSC.RTT_PORT, value); }
+ }
+
+ /// <summary>
+ /// The host name or IP address of the local network interface to be
+ /// used for a real-time connection to a broker.
+ /// </summary>
+ [UriAttribute("rtt.LocalAddress")]
+ public string RTTLocalAddress
+ {
+ get { return this.xmsConnectionFactory.GetStringProperty(XMSC.RTT_LOCAL_ADDRESS); }
+ set { this.xmsConnectionFactory.SetStringProperty(XMSC.RTT_LOCAL_ADDRESS, value); }
+ }
+
+ /// <summary>
+ /// The multicast setting for the connection factory.
+ /// </summary>
+ [UriAttribute("rtt.XMSMulticast")]
+ public Int32 XMSMulticast
+ {
+ get { return this.xmsConnectionFactory.GetIntProperty(XMSC.RTT_MULTICAST); }
+ set { this.xmsConnectionFactory.SetIntProperty(XMSC.RTT_MULTICAST, value); }
+ }
+
+ /// <summary>
+ /// The multicast setting for a connection factory or destination.
+ /// </summary>
+ [UriAttribute("rtt.Multicast")]
+ public Multicast Multicast
+ {
+ get { return XMSConvert.ToMulticast(this.XMSMulticast); }
+ set { this.XMSMulticast = XMSConvert.ToXMSMulticast(value); }
+ }
+
+ /// <summary>
+ /// The time interval, in milliseconds, after which XMS .NET checks the
+ /// connection to a Real Time messaging server to detect any activity.
+ /// </summary>
+ [UriAttribute("rtt.BrokerPingInterval")]
+ public Int32 BrokerPingInterval
+ {
+ get { return this.xmsConnectionFactory.GetIntProperty(XMSC.RTT_BROKER_PING_INTERVAL); }
+ set { this.xmsConnectionFactory.SetIntProperty(XMSC.RTT_BROKER_PING_INTERVAL, value); }
+ }
+
+ #endregion
+
+ #region WMQ-specific properties
+
+ /// <summary>
+ /// The host name or IP address of the system on which a queue manager
+ /// runs.
+ /// </summary>
+ [UriAttribute("wmq.HostName")]
+ public string WMQHostName
+ {
+ get { return this.xmsConnectionFactory.GetStringProperty(XMSC.WMQ_HOST_NAME); }
+ set { this.xmsConnectionFactory.SetStringProperty(XMSC.WMQ_HOST_NAME, value); }
+ }
+
+ /// <summary>
+ /// The number of the port on which a queue manager listens for
+ /// incoming requests.
+ /// </summary>
+ [UriAttribute("wmq.Port")]
+ public Int32 WMQPort
+ {
+ get { return this.xmsConnectionFactory.GetIntProperty(XMSC.WMQ_PORT); }
+ set { this.xmsConnectionFactory.SetIntProperty(XMSC.WMQ_PORT, value); }
+ }
+
+ /// <summary>
+ /// For a connection to a queue manager, this property specifies the
+ /// local network interface to be used, or the local port or range of
+ /// local ports to be used, or both.
+ /// </summary>
+ [UriAttribute("wmq.LocalAddress")]
+ public string WMQLocalAddress
+ {
+ get { return this.xmsConnectionFactory.GetStringProperty(XMSC.WMQ_LOCAL_ADDRESS); }
+ set { this.xmsConnectionFactory.SetStringProperty(XMSC.WMQ_LOCAL_ADDRESS, value); }
+ }
+
+ /// <summary>
+ /// The name of the queue manager to connect to.
+ /// </summary>
+ [UriAttribute("wmq.QueueManagerName")]
+ public string QueueManagerName
+ {
+ get { return this.xmsConnectionFactory.GetStringProperty(XMSC.WMQ_QUEUE_MANAGER); }
+ set { this.xmsConnectionFactory.SetStringProperty(XMSC.WMQ_QUEUE_MANAGER, value); }
+ }
+
+ /// <summary>
+ /// The version, release, modification level and fix pack of the queue
+ /// manager to which the application intends to connect.
+ /// </summary>
+ [UriAttribute("wmq.ProviderVersion")]
+ public string ProviderVersion
+ {
+ get { return this.xmsConnectionFactory.GetStringProperty(XMSC.WMQ_PROVIDER_VERSION); }
+ set { this.xmsConnectionFactory.SetStringProperty(XMSC.WMQ_PROVIDER_VERSION, value); }
+ }
+
+ /// <summary>
+ /// The name of the channel to be used for a connection.
+ /// </summary>
+ [UriAttribute("wmq.ChannelName")]
+ public string ChannelName
+ {
+ get { return this.xmsConnectionFactory.GetStringProperty(XMSC.WMQ_CHANNEL); }
+ set { this.xmsConnectionFactory.SetStringProperty(XMSC.WMQ_CHANNEL, value); }
+ }
+
+ /// <summary>
+ /// A Uniform Resource Locator (URL) that identifies the name and
+ /// location of the file that contains the client channel definition
+ /// table and also specifies how the file can be accessed.
+ /// </summary>
+ [UriAttribute("wmq.ClientChannelDefinitionTableURL")]
+ public string ClientChannelDefinitionTableURL
+ {
+ get { return this.xmsConnectionFactory.GetStringProperty(XMSC.WMQ_CCDTURL); }
+ set { this.xmsConnectionFactory.SetStringProperty(XMSC.WMQ_CCDTURL, value); }
+ }
+
+ /// <summary>
+ /// The mode by which an application connects to a queue manager.
+ /// </summary>
+ [UriAttribute("wmq.XMSConnectionMode")]
+ public Int32 XMSConnectionMode
+ {
+ get { return this.xmsConnectionFactory.GetIntProperty(XMSC.WMQ_CONNECTION_MODE); }
+ set { this.xmsConnectionFactory.SetIntProperty(XMSC.WMQ_CONNECTION_MODE, value); }
+ }
+
+ /// <summary>
+ /// The mode by which an application connects to a queue manager,
+ /// specified as a string.
+ /// </summary>
+ [UriAttribute("wmq.ConnectionMode")]
+ public ConnectionMode ConnectionMode
+ {
+ get { return XMSConvert.ToConnectionMode(this.XMSConnectionMode); }
+ set { this.XMSConnectionMode = XMSConvert.ToXMSConnectionMode(value); }
+ }
+
+ /// <summary>
+ /// This property specifies the client reconnect options for new
+ /// connections created by this factory.
+ /// </summary>
+ [UriAttribute("wmq.ClientReconnectOptions")]
+ public string ClientReconnectOptions
+ {
+ get { return this.xmsConnectionFactory.GetStringProperty(XMSC.WMQ_CLIENT_RECONNECT_OPTIONS); }
+ set { this.xmsConnectionFactory.SetStringProperty(XMSC.WMQ_CLIENT_RECONNECT_OPTIONS, value); }
+ }
+
+ /// <summary>
+ /// This property specifies the duration of time, in seconds, that a
+ /// client connection attempts to reconnect.
+ /// </summary>
+ [UriAttribute("wmq.ClientReconnectTimeout")]
+ public string ClientReconnectTimeout
+ {
+ get { return this.xmsConnectionFactory.GetStringProperty(XMSC.WMQ_CLIENT_RECONNECT_TIMEOUT); }
+ set { this.xmsConnectionFactory.SetStringProperty(XMSC.WMQ_CLIENT_RECONNECT_TIMEOUT, value); }
+ }
+
+ /// <summary>
+ /// This property specifies the hosts to which the client attempts to
+ /// reconnect to after its connection are broken.
+ /// </summary>
+ [UriAttribute("wmq.ConnectionNameList")]
+ public string ConnectionNameList
+ {
+ get { return this.xmsConnectionFactory.GetStringProperty(XMSC.WMQ_CONNECTION_NAME_LIST); }
+ set { this.xmsConnectionFactory.SetStringProperty(XMSC.WMQ_CONNECTION_NAME_LIST, value); }
+ }
+
+ /// <summary>
+ /// Whether calls to certain methods fail if the queue manager to which
+ /// the application is connected is in a quiescing state.
+ /// </summary>
+ [UriAttribute("wmq.XMSFailIfQuiesce")]
+ public Int32 XMSFailIfQuiesce
+ {
+ get { return this.xmsConnectionFactory.GetIntProperty(XMSC.WMQ_FAIL_IF_QUIESCE); }
+ set { this.xmsConnectionFactory.SetIntProperty(XMSC.WMQ_FAIL_IF_QUIESCE, value); }
+ }
+
+ /// <summary>
+ /// Whether calls to certain methods fail if the queue manager to which
+ /// the application is connected is in a quiescing state.
+ /// </summary>
+ [UriAttribute("wmq.FailIfQuiesce")]
+ public bool FailIfQuiesce
+ {
+ get { return XMSConvert.ToFailIfQuiesce(this.XMSFailIfQuiesce); }
+ set { this.XMSFailIfQuiesce = XMSConvert.ToXMSFailIfQuiesce(value); }
+ }
+
+ /// <summary>
+ /// The type of broker used by the application for a connection or for
+ /// the destination.
+ /// </summary>
+ [UriAttribute("wmq.XMSBrokerVersion")]
+ public Int32 XMSBrokerVersion
+ {
+ get { return this.xmsConnectionFactory.GetIntProperty(XMSC.WMQ_BROKER_VERSION); }
+ set { this.xmsConnectionFactory.SetIntProperty(XMSC.WMQ_BROKER_VERSION, value); }
+ }
+
+ /// <summary>
+ /// The type of broker used by the application for a connection or for
+ /// the destination.
+ /// </summary>
+ [UriAttribute("wmq.BrokerVersion")]
+ public BrokerVersion BrokerVersion
+ {
+ get { return XMSConvert.ToBrokerVersion(this.XMSBrokerVersion); }
+ set { this.XMSBrokerVersion = XMSConvert.ToXMSBrokerVersion(value); }
+ }
+
+ /// <summary>
+ /// The name of the queue manager to which a broker is connected.
+ /// </summary>
+ [UriAttribute("wmq.BrokerQueueManagerName")]
+ public string BrokerQueueManagerName
+ {
+ get { return this.xmsConnectionFactory.GetStringProperty(XMSC.WMQ_BROKER_QMGR); }
+ set { this.xmsConnectionFactory.SetStringProperty(XMSC.WMQ_BROKER_QMGR, value); }
+ }
+
+ /// <summary>
+ /// The name of the control queue used by a broker.
+ /// </summary>
+ [UriAttribute("wmq.BrokerControlQueueName")]
+ public string BrokerControlQueueName
+ {
+ get { return this.xmsConnectionFactory.GetStringProperty(XMSC.WMQ_BROKER_CONTROLQ); }
+ set { this.xmsConnectionFactory.SetStringProperty(XMSC.WMQ_BROKER_CONTROLQ, value); }
+ }
+
+ /// <summary>
+ /// The name of the queue monitored by a broker where applications send
+ /// messages that they publish.
+ /// </summary>
+ [UriAttribute("wmq.BrokerPublishQueueName")]
+ public string BrokerPublishQueueName
+ {
+ get { return this.xmsConnectionFactory.GetStringProperty(XMSC.WMQ_BROKER_PUBQ); }
+ set { this.xmsConnectionFactory.SetStringProperty(XMSC.WMQ_BROKER_PUBQ, value); }
+ }
+
+ /// <summary>
+ /// The name of the subscriber queue for a nondurable message consumer.
+ /// </summary>
+ [UriAttribute("wmq.BrokerSubscriberQueueName")]
+ public string BrokerSubscriberQueueName
+ {
+ get { return this.xmsConnectionFactory.GetStringProperty(XMSC.WMQ_BROKER_SUBQ); }
+ set { this.xmsConnectionFactory.SetStringProperty(XMSC.WMQ_BROKER_SUBQ, value); }
+ }
+
+ /// <summary>
+ /// Determines whether message selection is done by the XMS client or
+ /// by the broker.
+ /// </summary>
+ [UriAttribute("wmq.XMSMessageSelection")]
+ public Int32 XMSMessageSelection
+ {
+ get { return this.xmsConnectionFactory.GetIntProperty(XMSC.WMQ_MESSAGE_SELECTION); }
+ set { this.xmsConnectionFactory.SetIntProperty(XMSC.WMQ_MESSAGE_SELECTION, value); }
+ }
+
+ /// <summary>
+ /// Determines whether message selection is done by the XMS client or
+ /// by the broker.
+ /// </summary>
+ [UriAttribute("wmq.MessageSelection")]
+ public MessageSelection MessageSelection
+ {
+ get { return XMSConvert.ToMessageSelection(this.XMSMessageSelection); }
+ set { this.XMSMessageSelection = XMSConvert.ToXMSMessageSelection(value); }
+ }
+
+ /// <summary>
+ /// The maximum number of messages to be retrieved from a queue in one
+ /// batch when using asynchronous message delivery.
+ /// </summary>
+ [UriAttribute("wmq.MessageBatchSize")]
+ public Int32 MessageBatchSize
+ {
+ get { return this.xmsConnectionFactory.GetIntProperty(XMSC.WMQ_MSG_BATCH_SIZE); }
+ set { this.xmsConnectionFactory.SetIntProperty(XMSC.WMQ_MSG_BATCH_SIZE, value); }
+ }
+
+ /// <summary>
+ /// If each message listener within a session has no suitable message
+ /// on its queue, this value is the maximum interval, in milliseconds,
+ /// that elapses before each message listener tries again to get a
+ /// message from its queue.
+ /// </summary>
+ [UriAttribute("wmq.PollingInterval")]
+ public Int32 PollingInterval
+ {
+ get { return this.xmsConnectionFactory.GetIntProperty(XMSC.WMQ_POLLING_INTERVAL); }
+ set { this.xmsConnectionFactory.SetIntProperty(XMSC.WMQ_POLLING_INTERVAL, value); }
+ }
+
+ /// <summary>
+ /// The number of messages published by a publisher before the XMS
+ /// client requests an acknowledgement from the broker.
+ /// </summary>
+ [UriAttribute("wmq.PublishAcknowledgementInterval")]
+ public Int32 PublishAcknowledgementInterval
+ {
+ get { return this.xmsConnectionFactory.GetIntProperty(XMSC.WMQ_PUB_ACK_INTERVAL); }
+ set { this.xmsConnectionFactory.SetIntProperty(XMSC.WMQ_PUB_ACK_INTERVAL, value); }
+ }
+
+ /// <summary>
+ /// This property determines whether message producers are allowed to
+ /// use asynchronous puts to send messages to this destination.
+ /// </summary>
+ [UriAttribute("wmq.XMSAsynchronousPutsAllowed")]
+ public Int32 XMSAsynchronousPutsAllowed
+ {
+ get { return this.xmsConnectionFactory.GetIntProperty(XMSC.WMQ_PUT_ASYNC_ALLOWED); }
+ set { this.xmsConnectionFactory.SetIntProperty(XMSC.WMQ_PUT_ASYNC_ALLOWED, value); }
+ }
+
+ /// <summary>
+ /// This property determines whether message producers are allowed to
+ /// use asynchronous puts to send messages to this destination.
+ /// </summary>
+ [UriAttribute("wmq.AsynchronousPutsAllowed")]
+ public AsynchronousPutsAllowed AsynchronousPutsAllowed
+ {
+ get { return XMSConvert.ToAsynchronousPutsAllowed(this.XMSAsynchronousPutsAllowed); }
+ set { this.XMSAsynchronousPutsAllowed = XMSConvert.ToXMSAsynchronousPutsAllowed(value); }
+ }
+
+ /// <summary>
+ /// The identifier (CCSID) of the coded character set, or code page,
+ /// in which fields of character data defined in the Message Queue
+ /// Interface (MQI) are exchanged between the XMS client and the
+ /// WebSphere MQ client.
+ /// </summary>
+ [UriAttribute("wmq.QueueManagerCCSID")]
+ public string QueueManagerCCSID
+ {
+ get { return this.xmsConnectionFactory.GetStringProperty(XMSC.WMQ_QMGR_CCSID); }
+ set { this.xmsConnectionFactory.SetStringProperty(XMSC.WMQ_QMGR_CCSID, value); }
+ }
+
+ /// <summary>
+ /// Identifies a channel receive exit to be run.
+ /// </summary>
+ [UriAttribute("wmq.ReceiveExit")]
+ public string ReceiveExit
+ {
+ get { return this.xmsConnectionFactory.GetStringProperty(XMSC.WMQ_RECEIVE_EXIT); }
+ set { this.xmsConnectionFactory.SetStringProperty(XMSC.WMQ_RECEIVE_EXIT, value); }
+ }
+
+ /// <summary>
+ /// The user data that is passed to a channel receive exit when it
+ /// is called.
+ /// </summary>
+ [UriAttribute("wmq.ReceiveExitInit")]
+ public string ReceiveExitInit
+ {
+ get { return this.xmsConnectionFactory.GetStringProperty(XMSC.WMQ_RECEIVE_EXIT_INIT); }
+ set { this.xmsConnectionFactory.SetStringProperty(XMSC.WMQ_RECEIVE_EXIT_INIT, value); }
+ }
+
+ /// <summary>
+ /// Identifies a channel security exit.
+ /// </summary>
+ [UriAttribute("wmq.SecurityExit")]
+ public string SecurityExit
+ {
+ get { return this.xmsConnectionFactory.GetStringProperty(XMSC.WMQ_SECURITY_EXIT); }
+ set { this.xmsConnectionFactory.SetStringProperty(XMSC.WMQ_SECURITY_EXIT, value); }
+ }
+
+ /// <summary>
+ /// The user data that is passed to a channel security exit when it
+ /// is called.
+ /// </summary>
+ [UriAttribute("wmq.SecurityExitInit")]
+ public string SecurityExitInit
+ {
+ get { return this.xmsConnectionFactory.GetStringProperty(XMSC.WMQ_SECURITY_EXIT_INIT); }
+ set { this.xmsConnectionFactory.SetStringProperty(XMSC.WMQ_SECURITY_EXIT_INIT, value); }
+ }
+
+ /// <summary>
+ /// Identifies a channel send exit.
+ /// </summary>
+ [UriAttribute("wmq.SendExit")]
+ public string SendExit
+ {
+ get { return this.xmsConnectionFactory.GetStringProperty(XMSC.WMQ_SEND_EXIT); }
+ set { this.xmsConnectionFactory.SetStringProperty(XMSC.WMQ_SEND_EXIT, value); }
+ }
+
+ /// <summary>
+ /// The user data that is passed to channel send exits when they
+ /// are called.
+ /// </summary>
+ [UriAttribute("wmq.SendExitInit")]
+ public string SendExitInit
+ {
+ get { return this.xmsConnectionFactory.GetStringProperty(XMSC.WMQ_SEND_EXIT_INIT); }
+ set { this.xmsConnectionFactory.SetStringProperty(XMSC.WMQ_SEND_EXIT_INIT, value); }
+ }
+
+ /// <summary>
+ /// The number of send calls to allow between checking for asynchronous
+ /// put errors, within a single non-transacted XMS session.
+ /// </summary>
+ [UriAttribute("wmq.SendCheckCount")]
+ public Int32 SendCheckCount
+ {
+ get { return this.xmsConnectionFactory.GetIntProperty(XMSC.WMQ_SEND_CHECK_COUNT); }
+ set { this.xmsConnectionFactory.SetIntProperty(XMSC.WMQ_SEND_CHECK_COUNT, value); }
+ }
+
+ /// <summary>
+ /// Whether a client connection can share its socket with other
+ /// top-level XMS connections from the same process to the same queue
+ /// manager, if the channel definitions match.
+ /// </summary>
+ [UriAttribute("wmq.XMSShareSocketAllowed")]
+ public Int32 XMSShareSocketAllowed
+ {
+ get { return this.xmsConnectionFactory.GetIntProperty(XMSC.WMQ_SHARE_CONV_ALLOWED); }
+ set { this.xmsConnectionFactory.SetIntProperty(XMSC.WMQ_SHARE_CONV_ALLOWED, value); }
+ }
+
+ /// <summary>
+ /// Whether a client connection can share its socket with other
+ /// top-level XMS connections from the same process to the same queue
+ /// manager, if the channel definitions match.
+ /// </summary>
+ [UriAttribute("wmq.ShareSocketAllowed")]
+ public bool ShareSocketAllowed
+ {
+ get { return XMSConvert.ToShareSocketAllowed(this.XMSShareSocketAllowed); }
+ set { this.XMSShareSocketAllowed = XMSConvert.ToXMSShareSocketAllowed(value); }
+ }
+
+ /// <summary>
+ /// The locations of the servers that hold the certificate revocation
+ /// lists (CRLs) to be used on an SSL connection to a queue manager.
+ /// </summary>
+ [UriAttribute("wmq.SSLCertificateStores")]
+ public string SSLCertificateStores
+ {
+ get { return this.xmsConnectionFactory.GetStringProperty(XMSC.WMQ_SSL_CERT_STORES); }
+ set { this.xmsConnectionFactory.SetStringProperty(XMSC.WMQ_SSL_CERT_STORES, value); }
+ }
+
+ /// <summary>
+ /// The name of the CipherSpec to be used on a secure connection to
+ /// a queue manager.
+ /// </summary>
+ [UriAttribute("wmq.SSLCipherSpec")]
+ public string SSLCipherSpec
+ {
+ get { return this.xmsConnectionFactory.GetStringProperty(XMSC.WMQ_SSL_CIPHER_SPEC); }
+ set { this.xmsConnectionFactory.SetStringProperty(XMSC.WMQ_SSL_CIPHER_SPEC, value); }
+ }
+
+ /// <summary>
+ /// The name of the CipherSuite to be used on an SSL or TLS connection
+ /// to a queue manager. The protocol used in negotiating the secure
+ /// connection depends on the specified CipherSuite.
+ /// </summary>
+ [UriAttribute("wmq.SSLCipherSuite")]
+ public string SSLCipherSuite
+ {
+ get { return this.xmsConnectionFactory.GetStringProperty(XMSC.WMQ_SSL_CIPHER_SUITE); }
+ set { this.xmsConnectionFactory.SetStringProperty(XMSC.WMQ_SSL_CIPHER_SUITE, value); }
+ }
+
+ /// <summary>
+ /// Configuration details for the cryptographic hardware connected
+ /// to the client system.
+ /// </summary>
+ [UriAttribute("wmq.SSLCryptoHardware")]
+ public string SSLCryptoHardware
+ {
+ get { return this.xmsConnectionFactory.GetStringProperty(XMSC.WMQ_SSL_CRYPTO_HW); }
+ set { this.xmsConnectionFactory.SetStringProperty(XMSC.WMQ_SSL_CRYPTO_HW, value); }
+ }
+
+ /// <summary>
+ /// The value of this property determines whether an application can
+ /// or cannot use non-FIPS compliant cipher suites. If this property
+ /// is set to true, only FIPS algorithms are used for the client-server
+ /// connection.
+ /// </summary>
+ [UriAttribute("wmq.SSLFipsRequired")]
+ public bool SSLFipsRequired
+ {
+ get { return this.xmsConnectionFactory.GetBooleanProperty(XMSC.WMQ_SSL_FIPS_REQUIRED); }
+ set { this.xmsConnectionFactory.SetBooleanProperty(XMSC.WMQ_SSL_FIPS_REQUIRED, value); }
+ }
+
+ /// <summary>
+ /// The location of the key database file in which keys and
+ /// certificates are stored.
+ /// </summary>
+ [UriAttribute("wmq.SSLKeyRepository")]
+ public string SSLKeyRepository
+ {
+ get { return this.xmsConnectionFactory.GetStringProperty(XMSC.WMQ_SSL_KEY_REPOSITORY); }
+ set { this.xmsConnectionFactory.SetStringProperty(XMSC.WMQ_SSL_KEY_REPOSITORY, value); }
+ }
+
+ /// <summary>
+ /// The KeyResetCount represents the total number of unencrypted bytes
+ /// sent and received within an SSL conversation before the secret key
+ /// is renegotiated.
+ /// </summary>
+ [UriAttribute("wmq.SSLKeyResetCount")]
+ public Int32 SSLKeyResetCount
+ {
+ get { return this.xmsConnectionFactory.GetIntProperty(XMSC.WMQ_SSL_KEY_RESETCOUNT); }
+ set { this.xmsConnectionFactory.SetIntProperty(XMSC.WMQ_SSL_KEY_RESETCOUNT, value); }
+ }
+
+ /// <summary>
+ /// The peer name to be used on an SSL connection to a queue manager.
+ /// </summary>
+ [UriAttribute("wmq.SSLPeerName")]
+ public string SSLPeerName
+ {
+ get { return this.xmsConnectionFactory.GetStringProperty(XMSC.WMQ_SSL_PEER_NAME); }
+ set { this.xmsConnectionFactory.SetStringProperty(XMSC.WMQ_SSL_PEER_NAME, value); }
+ }
+
+ /// <summary>
+ /// Whether all messages must be retrieved from queues within sync point control.
+ /// </summary>
+ [UriAttribute("wmq.SyncpointAllGets")]
+ public bool SyncpointAllGets
+ {
+ get { return this.xmsConnectionFactory.GetBooleanProperty(XMSC.WMQ_SYNCPOINT_ALL_GETS); }
+ set { this.xmsConnectionFactory.SetBooleanProperty(XMSC.WMQ_SYNCPOINT_ALL_GETS, value); }
+ }
+
+ /// <summary>
+ /// Whether messages sent to the destination contain an MQRFH2 header.
+ /// </summary>
+ [UriAttribute("wmq.XMSTargetClient")]
+ public Int32 XMSTargetClient
+ {
+ get { return this.xmsConnectionFactory.GetIntProperty(XMSC.WMQ_TARGET_CLIENT); }
+ set { this.xmsConnectionFactory.SetIntProperty(XMSC.WMQ_TARGET_CLIENT, value); }
+ }
+
+ /// <summary>
+ /// Whether messages sent to the destination contain an <c>MQRFH2</c>
+ /// header.
+ /// </summary>
+ [UriAttribute("wmq.TargetClient")]
+ public TargetClient TargetClient
+ {
+ get { return XMSConvert.ToTargetClient(this.XMSTargetClient); }
+ set { this.XMSTargetClient = XMSConvert.ToXMSTargetClient(value); }
+ }
+
+ /// <summary>
+ /// The prefix used to form the name of the WebSphere MQ dynamic queue
+ /// that is created when the application creates an XMS temporary queue.
+ /// </summary>
+ [UriAttribute("wmq.TemporaryQueuePrefix")]
+ public string WMQTemporaryQueuePrefix
+ {
+ get { return this.xmsConnectionFactory.GetStringProperty(XMSC.WMQ_TEMP_Q_PREFIX); }
+ set { this.xmsConnectionFactory.SetStringProperty(XMSC.WMQ_TEMP_Q_PREFIX, value); }
+ }
+
+ /// <summary>
+ /// When creating temporary topics, XMS generates a topic string of
+ /// the form "TEMP/TEMPTOPICPREFIX/unique_id", or if this property
+ /// contains the default value, then this string, "TEMP/unique_id", is
+ /// generated. Specifying a non-empty value allows specific model
+ /// queues to be defined for creating the managed queues for subscribers
+ /// to temporary topics created under this connection.
+ /// </summary>
+ [UriAttribute("wmq.TemporaryTopicPrefix")]
+ public string WMQTemporaryTopicPrefix
+ {
+ get { return this.xmsConnectionFactory.GetStringProperty(XMSC.WMQ_TEMP_TOPIC_PREFIX); }
+ set { this.xmsConnectionFactory.SetStringProperty(XMSC.WMQ_TEMP_TOPIC_PREFIX, value); }
+ }
+
+ /// <summary>
+ /// The name of the WebSphere MQ model queue from which a dynamic
+ /// queue is created when the application creates an XMS temporary
+ /// queue.
+ /// </summary>
+ [UriAttribute("wmq.TemporaryModel")]
+ public string WMQTemporaryModel
+ {
+ get { return this.xmsConnectionFactory.GetStringProperty(XMSC.WMQ_TEMP_TOPIC_PREFIX); }
+ set { this.xmsConnectionFactory.SetStringProperty(XMSC.WMQ_TEMP_TOPIC_PREFIX, value); }
+ }
+
+ #endregion
+
+ #region WPM-specific properties
+
+ /// <summary>
+ /// For a connection to a service integration bus, this property
+ /// specifies the local network interface to be used, or the local
+ /// port or range of local ports to be used, or both.
+ /// </summary>
+ [UriAttribute("wpm.LocalAddress")]
+ public string WPMLocalAddress
+ {
+ get { return this.xmsConnectionFactory.GetStringProperty(XMSC.WPM_LOCAL_ADDRESS); }
+ set { this.xmsConnectionFactory.SetStringProperty(XMSC.WPM_LOCAL_ADDRESS, value); }
+ }
+
+ /// <summary>
+ /// The name of the service integration bus that the application
+ /// connects to.
+ /// </summary>
+ [UriAttribute("wpm.BusName")]
+ public string BusName
+ {
+ get { return this.xmsConnectionFactory.GetStringProperty(XMSC.WPM_BUS_NAME); }
+ set { this.xmsConnectionFactory.SetStringProperty(XMSC.WPM_BUS_NAME, value); }
+ }
+
+ /// <summary>
+ /// The connection proximity setting for the connection.
+ /// </summary>
+ [UriAttribute("wpm.XMSConnectionProximity")]
+ public Int32 XMSConnectionProximity
+ {
+ get { return this.xmsConnectionFactory.GetIntProperty(XMSC.WPM_CONNECTION_PROXIMITY); }
+ set { this.xmsConnectionFactory.SetIntProperty(XMSC.WPM_CONNECTION_PROXIMITY, value); }
+ }
+
+ /// <summary>
+ /// The connection proximity setting for the connection.
+ /// </summary>
+ [UriAttribute("wpm.ConnectionProximity")]
+ public ConnectionProximity ConnectionProximity
+ {
+ get { return XMSConvert.ToConnectionProximity(this.XMSConnectionProximity); }
+ set { this.XMSConnectionProximity = XMSConvert.ToXMSConnectionProximity(value); }
+ }
+
+ /// <summary>
+ /// The name of the messaging engine where all durable subscriptions
+ /// for a connection or a destination are managed.
+ /// </summary>
+ [UriAttribute("wpm.DurableSubscriptionHome")]
+ public string DurableSubscriptionHome
+ {
+ get { return this.xmsConnectionFactory.GetStringProperty(XMSC.WPM_DUR_SUB_HOME); }
+ set { this.xmsConnectionFactory.SetStringProperty(XMSC.WPM_DUR_SUB_HOME, value); }
+ }
+
+ /// <summary>
+ /// The reliability level of nonpersistent messages that are sent
+ /// using the connection.
+ /// </summary>
+ [UriAttribute("wpm.XMSNonPersistentMap")]
+ public Int32 XMSNonPersistentMap
+ {
+ get { return this.xmsConnectionFactory.GetIntProperty(XMSC.WPM_NON_PERSISTENT_MAP); }
+ set { this.xmsConnectionFactory.SetIntProperty(XMSC.WPM_NON_PERSISTENT_MAP, value); }
+ }
+
+ /// <summary>
+ /// The reliability level of nonpersistent messages that are sent
+ /// using the connection.
+ /// </summary>
+ [UriAttribute("wpm.NonPersistentMap")]
+ public Mapping NonPersistentMap
+ {
+ get { return XMSConvert.ToMapping(this.XMSNonPersistentMap); }
+ set { this.XMSNonPersistentMap = XMSConvert.ToXMSMapping(value); }
+ }
+
+ /// <summary>
+ /// The reliability level of persistent messages that are sent
+ /// using the connection.
+ /// </summary>
+ [UriAttribute("wpm.XMSPersistentMap")]
+ public Int32 XMSPersistentMap
+ {
+ get { return this.xmsConnectionFactory.GetIntProperty(XMSC.WPM_PERSISTENT_MAP); }
+ set { this.xmsConnectionFactory.SetIntProperty(XMSC.WPM_PERSISTENT_MAP, value); }
+ }
+
+ /// <summary>
+ /// The reliability level of persistent messages that are sent
+ /// using the connection.
+ /// </summary>
+ [UriAttribute("wpm.PersistentMap")]
+ public Mapping PersistentMap
+ {
+ get { return XMSConvert.ToMapping(this.XMSPersistentMap); }
+ set { this.XMSPersistentMap = XMSConvert.ToXMSMapping(value); }
+ }
+
+ /// <summary>
+ /// A sequence of one or more endpoint addresses of bootstrap servers.
+ /// </summary>
+ [UriAttribute("wpm.ProviderEndpoints")]
+ public string ProviderEndpoints
+ {
+ get { return this.xmsConnectionFactory.GetStringProperty(XMSC.WPM_PROVIDER_ENDPOINTS); }
+ set { this.xmsConnectionFactory.SetStringProperty(XMSC.WPM_PROVIDER_ENDPOINTS, value); }
+ }
+
+ /// <summary>
+ /// The name of a target group of messaging engines.
+ /// </summary>
+ [UriAttribute("wpm.TargetGroup")]
+ public string TargetGroup
+ {
+ get { return this.xmsConnectionFactory.GetStringProperty(XMSC.WPM_TARGET_GROUP); }
+ set { this.xmsConnectionFactory.SetStringProperty(XMSC.WPM_TARGET_GROUP, value); }
+ }
+
+ /// <summary>
+ /// The significance of the target group of messaging engines.
+ /// </summary>
+ [UriAttribute("wpm.XMSTargetSignificance")]
+ public Int32 XMSTargetSignificance
+ {
+ get { return this.xmsConnectionFactory.GetIntProperty(XMSC.WPM_TARGET_SIGNIFICANCE); }
+ set { this.xmsConnectionFactory.SetIntProperty(XMSC.WPM_TARGET_SIGNIFICANCE, value); }
+ }
+
+ /// <summary>
+ /// The significance of the target group of messaging engines.
+ /// </summary>
+ [UriAttribute("wpm.TargetSignificance")]
+ public TargetSignificance TargetSignificance
+ {
+ get { return XMSConvert.ToTargetSignificance(this.XMSTargetSignificance); }
+ set { this.XMSTargetSignificance = XMSConvert.ToXMSTargetSignificance(value); }
+ }
+
+ /// <summary>
+ /// The name of the inbound transport chain that the application must
+ /// use to connect to a messaging engine.
+ /// </summary>
+ [UriAttribute("wpm.TargetTransportChain")]
+ public string TargetTransportChain
+ {
+ get { return this.xmsConnectionFactory.GetStringProperty(XMSC.WPM_TARGET_TRANSPORT_CHAIN); }
+ set { this.xmsConnectionFactory.SetStringProperty(XMSC.WPM_TARGET_TRANSPORT_CHAIN, value); }
+ }
+
+ /// <summary>
+ /// The type of the target group of messaging engines.
+ /// </summary>
+ [UriAttribute("wpm.XMSTargetType")]
+ public Int32 XMSTargetType
+ {
+ get { return this.xmsConnectionFactory.GetIntProperty(XMSC.WPM_TARGET_TYPE); }
+ set { this.xmsConnectionFactory.SetIntProperty(XMSC.WPM_TARGET_TYPE, value); }
+ }
+
+ /// <summary>
+ /// The type of the target group of messaging engines.
+ /// </summary>
+ [UriAttribute("wpm.TargetType")]
+ public TargetType TargetType
+ {
+ get { return XMSConvert.ToTargetType(this.XMSTargetType); }
+ set { this.XMSTargetType = XMSConvert.ToXMSTargetType(value); }
+ }
+
+ /// <summary>
+ /// The prefix used to form the name of the temporary queue that is
+ /// created in the service integration bus when the application creates
+ /// an XMS temporary queue.
+ /// </summary>
+ [UriAttribute("wpm.TemporaryQueuePrefix")]
+ public string WPMTemporaryQueuePrefix
+ {
+ get { return this.xmsConnectionFactory.GetStringProperty(XMSC.WMQ_TEMP_Q_PREFIX); }
+ set { this.xmsConnectionFactory.SetStringProperty(XMSC.WMQ_TEMP_Q_PREFIX, value); }
+ }
+
+ /// <summary>
+ /// The prefix used to form the name of a temporary topic that is
+ /// created by the application.
+ /// </summary>
+ [UriAttribute("wpm.TemporaryTopicPrefix")]
+ public string WPMTemporaryTopicPrefix
+ {
+ get { return this.xmsConnectionFactory.GetStringProperty(XMSC.WMQ_TEMP_TOPIC_PREFIX); }
+ set { this.xmsConnectionFactory.SetStringProperty(XMSC.WMQ_TEMP_TOPIC_PREFIX, value); }
+ }
+
+ #endregion
+
+ #region Common properties having protocol-specific keys
+
+ /// <summary>
+ /// The host name or IP address of the system on which a broker (RTT)
+ /// or queue manager (WMQ) runs.
+ /// </summary>
+ public string HostName
+ {
+ get
+ {
+ switch(this.XMSConnectionType)
+ {
+ case XMSC.CT_RTT: return this.RTTHostName;
+ case XMSC.CT_WMQ: return this.WMQHostName;
+ case XMSC.CT_WPM: return null;
+ default : return null;
+ }
+ }
+ set
+ {
+ switch(this.XMSConnectionType)
+ {
+ case XMSC.CT_RTT: this.RTTHostName = value; break;
+ case XMSC.CT_WMQ: this.WMQHostName = value; break;
+ case XMSC.CT_WPM: break;
+ default : break;
+ }
+ }
+ }
+
+ /// <summary>
+ /// The number of the port on which a broker (RTT) or queue manager
+ /// (WMQ) listens for incoming requests.
+ /// </summary>
+ public Int32 Port
+ {
+ get
+ {
+ switch(this.XMSConnectionType)
+ {
+ case IBM.XMS.XMSC.CT_RTT: return this.RTTPort;
+ case IBM.XMS.XMSC.CT_WMQ: return this.WMQPort;
+ case IBM.XMS.XMSC.CT_WPM: return 0;
+ default : return 0;
+ }
+ }
+ set
+ {
+ switch(this.XMSConnectionType)
+ {
+ case IBM.XMS.XMSC.CT_RTT: this.RTTPort = value; break;
+ case IBM.XMS.XMSC.CT_WMQ: this.WMQPort = value; break;
+ case IBM.XMS.XMSC.CT_WPM: break;
+ default : break;
+ }
+ }
+ }
+
+ /// <summary>
+ /// The host name or IP address of the local network interface to be
+ /// used for a RTT real-time connection to a broker.
+ /// For a WMQ connection to a queue manager, this property specifies
+ /// the local network interface to be used, or the local port or range
+ /// of local ports to be used, or both.
+ /// For a WPM connection to a service integration bus, this property
+ /// specifies the local network interface to be used, or the local
+ /// port or range of local ports to be used, or both.
+ /// </summary>
+ public string LocalAddress
+ {
+ get
+ {
+ switch(this.XMSConnectionType)
+ {
+ case IBM.XMS.XMSC.CT_RTT: return this.RTTLocalAddress;
+ case IBM.XMS.XMSC.CT_WMQ: return this.WMQLocalAddress;
+ case IBM.XMS.XMSC.CT_WPM: return this.WPMLocalAddress;
+ default : return null;
+ }
+ }
+ set
+ {
+ switch(this.XMSConnectionType)
+ {
+ case IBM.XMS.XMSC.CT_RTT: this.RTTLocalAddress = value; break;
+ case IBM.XMS.XMSC.CT_WMQ: this.WMQLocalAddress = value; break;
+ case IBM.XMS.XMSC.CT_WPM: this.WPMLocalAddress = value; break;
+ default : break;
+ }
+ }
+ }
+
+ /// <summary>
+ /// The prefix used to form the name of the WebSphere MQ dynamic queue
+ /// that is created (WMQ), or the name of the temporary queue that is
+ /// created in the service integration bus (WPM) when the application
+ /// creates an XMS temporary queue.
+ /// </summary>
+ public string TemporaryQueuePrefix
+ {
+ get
+ {
+ switch(this.XMSConnectionType)
+ {
+ case IBM.XMS.XMSC.CT_RTT: return null;
+ case IBM.XMS.XMSC.CT_WMQ: return this.WMQTemporaryQueuePrefix;
+ case IBM.XMS.XMSC.CT_WPM: return this.WPMTemporaryQueuePrefix;
+ default : return null;
+ }
+ }
+ set
+ {
+ switch(this.XMSConnectionType)
+ {
+ case IBM.XMS.XMSC.CT_RTT: break;
+ case IBM.XMS.XMSC.CT_WMQ: this.WMQTemporaryQueuePrefix = value; break;
+ case IBM.XMS.XMSC.CT_WPM: this.WPMTemporaryQueuePrefix = value; break;
+ default : break;
+ }
+ }
+ }
+
+ /// <summary>
+ /// The prefix used to form the name of a temporary topic that is
+ /// created by the application (WMQ and WPM).
+ /// </summary>
+ public string TemporaryTopicPrefix
+ {
+ get
+ {
+ switch(this.XMSConnectionType)
+ {
+ case IBM.XMS.XMSC.CT_RTT: return null;
+ case IBM.XMS.XMSC.CT_WMQ: return this.WMQTemporaryTopicPrefix;
+ case IBM.XMS.XMSC.CT_WPM: return this.WPMTemporaryTopicPrefix;
+ default : return null;
+ }
+ }
+ set
+ {
+ switch(this.XMSConnectionType)
+ {
+ case IBM.XMS.XMSC.CT_RTT: break;
+ case IBM.XMS.XMSC.CT_WMQ: this.WMQTemporaryTopicPrefix = value; break;
+ case IBM.XMS.XMSC.CT_WPM: this.WPMTemporaryTopicPrefix = value; break;
+ default : break;
+ }
+ }
+ }
+
+ #endregion
+
+ #endregion
+
+ #region IConnectionFactory Members
+
+ /// <summary>
+ /// Creates a new connection to IBM MQ with the default properties.
+ /// </summary>
+ public Apache.NMS.IConnection CreateConnection()
+ {
+ Apache.NMS.IConnection connection = null;
+ try
+ {
+ connection = new Apache.NMS.XMS.Connection(
+ this.xmsConnectionFactory.CreateConnection());
+ ConfigureConnection(connection);
+ }
+ catch(Exception ex)
+ {
+ ExceptionUtil.WrapAndThrowNMSException(ex);
+ }
+ return connection;
+ }
+
+ /// <summary>
+ /// Creates a new connection to IBM MQ using a specified user identity.
+ /// </summary>
+ /// <param name="userName">User name.</param>
+ /// <param name="password">Password.</param>
+ public Apache.NMS.IConnection CreateConnection(
+ string userName, string password)
+ {
+ Apache.NMS.IConnection connection = null;
+ try
+ {
+ connection = new Apache.NMS.XMS.Connection(
+ this.xmsConnectionFactory.CreateConnection(
+ userName, password));
+ ConfigureConnection(connection);
+ }
+ catch(Exception ex)
+ {
+ ExceptionUtil.WrapAndThrowNMSException(ex);
+ }
+ return connection;
+ }
+
+ /// <summary>
+ /// Configure the newly created connection.
+ /// </summary>
+ /// <param name="connection">Connection.</param>
+ private void ConfigureConnection(IConnection connection)
+ {
+ connection.RedeliveryPolicy = this.redeliveryPolicy.Clone() as IRedeliveryPolicy;
+ connection.ConsumerTransformer = this.consumerTransformer;
+ connection.ProducerTransformer = this.producerTransformer;
+ }
+
+ /// <summary>
+ /// Get or set the broker URI.
+ /// </summary>
+ public Uri BrokerUri
+ {
+ get { return this.brokerUri; }
+ set { this.brokerUri = CreateConnectionFactoryFromURI(value); }
+ }
+
+ private ConsumerTransformerDelegate consumerTransformer;
+ /// <summary>
+ /// A Delegate that is called each time a Message is dispatched to allow the client to do
+ /// any necessary transformations on the received message before it is delivered. The
+ /// ConnectionFactory sets the provided delegate instance on each Connection instance that
+ /// is created from this factory, each connection in turn passes the delegate along to each
+ /// Session it creates which then passes that along to the Consumers it creates.
+ /// </summary>
+ public ConsumerTransformerDelegate ConsumerTransformer
+ {
+ get { return this.consumerTransformer; }
+ set { this.consumerTransformer = value; }
+ }
+
+ private ProducerTransformerDelegate producerTransformer;
+ /// <summary>
+ /// A delegate that is called each time a Message is sent from this Producer which allows
+ /// the application to perform any needed transformations on the Message before it is sent.
+ /// The ConnectionFactory sets the provided delegate instance on each Connection instance that
+ /// is created from this factory, each connection in turn passes the delegate along to each
+ /// Session it creates which then passes that along to the Producers it creates.
+ /// </summary>
+ public ProducerTransformerDelegate ProducerTransformer
+ {
+ get { return this.producerTransformer; }
+ set { this.producerTransformer = value; }
+ }
+
+ #endregion
+ }
+}
diff --git a/src/main/csharp/ConnectionMetaData.cs b/src/main/csharp/ConnectionMetaData.cs
new file mode 100644
index 0000000..27ffce3
--- /dev/null
+++ b/src/main/csharp/ConnectionMetaData.cs
@@ -0,0 +1,106 @@
+/*
+ * 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.
+ */
+using System;
+using System.Reflection;
+
+namespace Apache.NMS.XMS
+{
+ /// <summary>
+ /// Implements the Connection Meta-Data feature for Apache.NMS.EMS
+ /// </summary>
+ public class ConnectionMetaData : IConnectionMetaData
+ {
+ private int nmsMajorVersion;
+ private int nmsMinorVersion;
+
+ private string nmsProviderName;
+ private string nmsVersion;
+
+ private int providerMajorVersion;
+ private int providerMinorVersion;
+ private string providerVersion;
+
+ private string[] nmsxProperties;
+
+ public ConnectionMetaData()
+ {
+ Assembly self = Assembly.GetExecutingAssembly();
+ AssemblyName asmName = self.GetName();
+
+ this.nmsProviderName = asmName.Name;
+ this.providerMajorVersion = asmName.Version.Major;
+ this.providerMinorVersion = asmName.Version.Minor;
+ this.providerVersion = asmName.Version.ToString();
+
+ this.nmsxProperties = new String[] { };
+
+ foreach(AssemblyName name in self.GetReferencedAssemblies())
+ {
+ if(0 == string.Compare(name.Name, "Apache.NMS", true))
+ {
+ this.nmsMajorVersion = name.Version.Major;
+ this.nmsMinorVersion = name.Version.Minor;
+ this.nmsVersion = name.Version.ToString();
+
+ return;
+ }
+ }
+
+ throw new NMSException("Could not find a reference to the Apache.NMS Assembly.");
+ }
+
+ public int NMSMajorVersion
+ {
+ get { return this.nmsMajorVersion; }
+ }
+
+ public int NMSMinorVersion
+ {
+ get { return this.nmsMinorVersion; }
+ }
+
+ public string NMSProviderName
+ {
+ get { return this.nmsProviderName; }
+ }
+
+ public string NMSVersion
+ {
+ get { return this.nmsVersion; }
+ }
+
+ public string[] NMSXPropertyNames
+ {
+ get { return this.nmsxProperties; }
+ }
+
+ public int ProviderMajorVersion
+ {
+ get { return this.providerMajorVersion; }
+ }
+
+ public int ProviderMinorVersion
+ {
+ get { return this.providerMinorVersion; }
+ }
+
+ public string ProviderVersion
+ {
+ get { return this.providerVersion; }
+ }
+ }
+}
diff --git a/src/main/csharp/Destination.cs b/src/main/csharp/Destination.cs
new file mode 100644
index 0000000..d3848b2
--- /dev/null
+++ b/src/main/csharp/Destination.cs
@@ -0,0 +1,524 @@
+/*
+ * 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.
+ */
+using System;
+using Apache.NMS;
+using Apache.NMS.Util;
+using Apache.NMS.XMS.Util;
+using IBM.XMS;
+
+namespace Apache.NMS.XMS
+{
+ public class Destination : IDestination
+ {
+ public IBM.XMS.IDestination xmsDestination;
+
+ #region Constructors
+
+ /// <summary>
+ /// Constructs a destination object.
+ /// </summary>
+ /// <param name="destination">IBM XMS destination.</param>
+ public Destination(IBM.XMS.IDestination destination)
+ {
+ this.xmsDestination = destination;
+ }
+
+ /// <summary>
+ /// Constructs a destination object specifying if the destination is
+ /// temporary.
+ /// </summary>
+ /// <param name="destination">IBM XMS destination.</param>
+ /// <param name="isTemporary">Whether the destination is temporary.
+ /// </param>
+ public Destination(IBM.XMS.IDestination destination, bool isTemporary)
+ {
+ this.xmsDestination = destination;
+ this.isTemporary = isTemporary;
+ }
+
+ #endregion
+
+ #region IDestination implementation
+
+ /// <summary>
+ /// Destination type.
+ /// </summary>
+ public DestinationType DestinationType
+ {
+ get
+ {
+ return XMSConvert.ToDestinationType(
+ this.xmsDestination.TypeId,
+ this.isTemporary);
+ }
+ }
+
+ /// <summary>
+ /// Checks if destination is a topic.
+ /// </summary>
+ public bool IsTopic
+ {
+ get
+ {
+ return (this.xmsDestination.TypeId
+ == IBM.XMS.DestinationType.Topic);
+ }
+ }
+
+ /// <summary>
+ /// Checks if destination is a queue.
+ /// </summary>
+ public bool IsQueue
+ {
+ get
+ {
+ return (this.xmsDestination.TypeId
+ == IBM.XMS.DestinationType.Queue);
+ }
+ }
+
+ private readonly bool isTemporary;
+ /// <summary>
+ /// Checks if destination is temporary.
+ /// </summary>
+ public bool IsTemporary
+ {
+ get { return this.isTemporary; }
+ }
+
+ #endregion
+
+ #region XMS IDestination properties
+
+ // http://www-01.ibm.com/support/knowledgecenter/SSFKSJ_8.0.0/com.ibm.mq.msc.doc/props_dest.htm?lang=en
+
+ #region Common properties
+
+ /// <summary>
+ /// Destination name.
+ /// </summary>
+ public string Name
+ {
+ get { return this.xmsDestination.Name; }
+ }
+
+ /// <summary>
+ /// The delivery mode of messages sent to the destination.
+ /// </summary>
+ public Int32 XMSDeliveryMode
+ {
+ get { return this.xmsDestination.GetIntProperty(XMSC.DELIVERY_MODE); }
+ set { this.xmsDestination.SetIntProperty(XMSC.DELIVERY_MODE, value); }
+ }
+
+ /// <summary>
+ /// The delivery mode of messages sent to the destination.
+ /// </summary>
+ public Apache.NMS.XMS.Util.DeliveryMode DeliveryMode
+ {
+ get { return XMSConvert.ToDeliveryMode(this.XMSDeliveryMode); }
+ set { this.XMSDeliveryMode = XMSConvert.ToXMSDeliveryMode(value); }
+ }
+
+ /// <summary>
+ /// The priority of messages sent to the destination.
+ /// </summary>
+ public Int32 Priority
+ {
+ get { return this.xmsDestination.GetIntProperty(XMSC.PRIORITY); }
+ set { this.xmsDestination.SetIntProperty(XMSC.PRIORITY, value); }
+ }
+
+ /// <summary>
+ /// The time to live in milliseconds for messages sent to the
+ /// destination.
+ /// </summary>
+ public Int32 TimeToLive
+ {
+ get { return this.xmsDestination.GetIntProperty(XMSC.TIME_TO_LIVE); }
+ set { this.xmsDestination.SetIntProperty(XMSC.TIME_TO_LIVE, value); }
+ }
+
+ #endregion
+
+ #region RTT-specific properties
+
+ /// <summary>
+ /// The multicast setting for the destination.
+ /// </summary>
+ [UriAttribute("rtt.XMSMulticast")]
+ public Int32 XMSMulticast
+ {
+ get { return this.xmsDestination.GetIntProperty(XMSC.RTT_MULTICAST); }
+ set { this.xmsDestination.SetIntProperty(XMSC.RTT_MULTICAST, value); }
+ }
+
+ /// <summary>
+ /// The multicast setting for the destination.
+ /// </summary>
+ [UriAttribute("rtt.Multicast")]
+ public Multicast Multicast
+ {
+ get { return XMSConvert.ToMulticast(this.XMSMulticast); }
+ set { this.XMSMulticast = XMSConvert.ToXMSMulticast(value); }
+ }
+
+ #endregion
+
+ #region WMQ-specific properties
+
+ /// <summary>
+ /// The type of broker used by the application for the destination.
+ /// </summary>
+ [UriAttribute("wmq.XMSBrokerVersion")]
+ public Int32 XMSBrokerVersion
+ {
+ get { return this.xmsDestination.GetIntProperty(XMSC.WMQ_BROKER_VERSION); }
+ set { this.xmsDestination.SetIntProperty(XMSC.WMQ_BROKER_VERSION, value); }
+ }
+
+ /// <summary>
+ /// The type of broker used by the application for the destination.
+ /// </summary>
+ [UriAttribute("wmq.BrokerVersion")]
+ public BrokerVersion BrokerVersion
+ {
+ get { return XMSConvert.ToBrokerVersion(this.XMSBrokerVersion); }
+ set { this.XMSBrokerVersion = XMSConvert.ToXMSBrokerVersion(value); }
+ }
+
+ /// <summary>
+ /// The identifier (CCSID) of the coded character set, or code page,
+ /// that the strings of character data in the body of a message are in
+ /// when the XMS client forwards the message to the destination.
+ /// </summary>
+ [UriAttribute("wmq.DestinationCCSID")]
+ public Int32 DestinationCCSID
+ {
+ get { return this.xmsDestination.GetIntProperty(XMSC.WMQ_CCSID); }
+ set { this.xmsDestination.SetIntProperty(XMSC.WMQ_CCSID, value); }
+ }
+
+ /// <summary>
+ /// The name of the subscriber queue for a durable subscriber that is
+ /// receiving messages from the destination.
+ /// </summary>
+ [UriAttribute("wmq.SubscriberQueueName")]
+ public string SubscriberQueueName
+ {
+ get { return this.xmsDestination.GetStringProperty(XMSC.WMQ_DUR_SUBQ); }
+ set { this.xmsDestination.SetStringProperty(XMSC.WMQ_DUR_SUBQ, value); }
+ }
+
+ /// <summary>
+ /// How numerical data in the body of a message is represented when
+ /// the XMS client forwards the message to the destination.
+ /// </summary>
+ [UriAttribute("wmq.XMSEncoding")]
+ public Int32 XMSEncoding
+ {
+ get { return this.xmsDestination.GetIntProperty(XMSC.WMQ_ENCODING); }
+ set { this.xmsDestination.SetIntProperty(XMSC.WMQ_ENCODING, value); }
+ }
+
+ /// <summary>
+ /// How numerical data in the body of a message is represented when
+ /// the XMS client forwards the message to the destination.
+ /// </summary>
+ [UriAttribute("wmq.Encoding")]
+ public Encoding Encoding
+ {
+ get { return XMSConvert.ToEncoding(this.XMSEncoding); }
+ set { this.XMSEncoding = XMSConvert.ToXMSEncoding(value); }
+ }
+
+ /// <summary>
+ /// Whether calls to certain methods fail if the queue manager to which
+ /// the application is connected is in a quiescing state.
+ /// </summary>
+ [UriAttribute("wmq.XMSFailIfQuiesce")]
+ public Int32 XMSFailIfQuiesce
+ {
+ get { return this.xmsDestination.GetIntProperty(XMSC.WMQ_FAIL_IF_QUIESCE); }
+ set { this.xmsDestination.SetIntProperty(XMSC.WMQ_FAIL_IF_QUIESCE, value); }
+ }
+
+ /// <summary>
+ /// Whether calls to certain methods fail if the queue manager to which
+ /// the application is connected is in a quiescing state.
+ /// </summary>
+ [UriAttribute("wmq.FailIfQuiesce")]
+ public bool FailIfQuiesce
+ {
+ get { return XMSConvert.ToFailIfQuiesce(this.XMSFailIfQuiesce); }
+ set { this.XMSFailIfQuiesce = XMSConvert.ToXMSFailIfQuiesce(value); }
+ }
+
+ /// <summary>
+ /// This property determines whether an XMS application processes the
+ /// <c>MQRFH2</c> of a WebSphere MQ message as part of the message
+ /// payload (that is, as part of the message body).
+ /// </summary>
+ [UriAttribute("wmq.XMSMessageBody")]
+ public Int32 XMSMessageBody
+ {
+ get { return this.xmsDestination.GetIntProperty(XMSC.WMQ_MESSAGE_BODY); }
+ set { this.xmsDestination.SetIntProperty(XMSC.WMQ_MESSAGE_BODY, value); }
+ }
+
+ /// <summary>
+ /// This property determines whether an XMS application processes the
+ /// <c>MQRFH2</c> of a WebSphere MQ message as part of the message
+ /// payload (that is, as part of the message body).
+ /// </summary>
+ [UriAttribute("wmq.MessageBody")]
+ public MessageBody MessageBody
+ {
+ get { return XMSConvert.ToMessageBody(this.XMSMessageBody); }
+ set { this.XMSMessageBody = XMSConvert.ToXMSMessageBody(value); }
+ }
+
+ /// <summary>
+ /// Determines what level of message context is to be set by the XMS
+ /// application. The application must be running with appropriate
+ /// context authority for this property to take effect.
+ /// </summary>
+ [UriAttribute("wmq.XMSMessageContext")]
+ public Int32 XMSMessageContext
+ {
+ get { return this.xmsDestination.GetIntProperty(XMSC.WMQ_MQMD_MESSAGE_CONTEXT); }
+ set { this.xmsDestination.SetIntProperty(XMSC.WMQ_MQMD_MESSAGE_CONTEXT, value); }
+ }
+
+ /// <summary>
+ /// Determines what level of message context is to be set by the XMS
+ /// application. The application must be running with appropriate
+ /// context authority for this property to take effect.
+ /// </summary>
+ [UriAttribute("wmq.MessageContext")]
+ public MessageContext MessageContext
+ {
+ get { return XMSConvert.ToMessageContext(this.XMSMessageContext); }
+ set { this.XMSMessageContext = XMSConvert.ToXMSMessageContext(value); }
+ }
+
+ /// <summary>
+ /// This property determines whether an XMS application can extract
+ /// the values of MQMD fields or not.
+ /// </summary>
+ [UriAttribute("wmq.XMSMQMDReadEnabled")]
+ public Int32 XMSMQMDReadEnabled
+ {
+ get { return this.xmsDestination.GetIntProperty(XMSC.WMQ_MQMD_READ_ENABLED); }
+ set { this.xmsDestination.SetIntProperty(XMSC.WMQ_MQMD_READ_ENABLED, value); }
+ }
+
+ /// <summary>
+ /// This property determines whether an XMS application can extract
+ /// the values of MQMD fields or not.
+ /// </summary>
+ [UriAttribute("wmq.MQMDReadEnabled")]
+ public bool MQMDReadEnabled
+ {
+ get { return XMSConvert.ToMQMDReadEnabled(this.XMSMQMDReadEnabled); }
+ set { this.XMSMQMDReadEnabled = XMSConvert.ToXMSMQMDReadEnabled(value); }
+ }
+
+ /// <summary>
+ /// This property determines whether an XMS application can set
+ /// the values of MQMD fields or not.
+ /// </summary>
+ [UriAttribute("wmq.XMSMQMDWriteEnabled")]
+ public Int32 XMSMQMDWriteEnabled
+ {
+ get { return this.xmsDestination.GetIntProperty(XMSC.WMQ_MQMD_WRITE_ENABLED); }
+ set { this.xmsDestination.SetIntProperty(XMSC.WMQ_MQMD_WRITE_ENABLED, value); }
+ }
+
+ /// <summary>
+ /// This property determines whether an XMS application can set
+ /// the values of MQMD fields or not.
+ /// </summary>
+ [UriAttribute("wmq.MQMDWriteEnabled")]
+ public bool MQMDWriteEnabled
+ {
+ get { return XMSConvert.ToMQMDWriteEnabled(this.XMSMQMDWriteEnabled); }
+ set { this.XMSMQMDWriteEnabled = XMSConvert.ToXMSMQMDWriteEnabled(value); }
+ }
+
+ /// <summary>
+ /// This property determines whether message consumers and queue
+ /// browsers are allowed to use read ahead to get non-persistent,
+ /// non-transactional messages from this destination into an internal
+ /// buffer before receiving them.
+ /// </summary>
+ [UriAttribute("wmq.XMSReadAheadAllowed")]
+ public Int32 XMSReadAheadAllowed
+ {
+ get { return this.xmsDestination.GetIntProperty(XMSC.WMQ_READ_AHEAD_ALLOWED); }
+ set { this.xmsDestination.SetIntProperty(XMSC.WMQ_READ_AHEAD_ALLOWED, value); }
+ }
+
+ /// <summary>
+ /// This property determines whether message consumers and queue
+ /// browsers are allowed to use read ahead to get non-persistent,
+ /// non-transactional messages from this destination into an internal
+ /// buffer before receiving them.
+ /// </summary>
+ [UriAttribute("wmq.ReadAheadAllowed")]
+ public ReadAheadAllowed ReadAheadAllowed
+ {
+ get { return XMSConvert.ToReadAheadAllowed(this.XMSReadAheadAllowed); }
+ set { this.XMSReadAheadAllowed = XMSConvert.ToXMSReadAheadAllowed(value); }
+ }
+
+
+ /// <summary>
+ /// This property determines, for messages being delivered to an
+ /// asynchronous message listener, what happens to messages in the
+ /// internal read ahead buffer when the message consumer is closed.
+ /// </summary>
+ [UriAttribute("wmq.XMSReadAheadClosePolicy")]
+ public Int32 XMSReadAheadClosePolicy
+ {
+ get { return this.xmsDestination.GetIntProperty(XMSC.WMQ_READ_AHEAD_CLOSE_POLICY); }
+ set { this.xmsDestination.SetIntProperty(XMSC.WMQ_READ_AHEAD_CLOSE_POLICY, value); }
+ }
+
+ /// <summary>
+ /// This property determines, for messages being delivered to an
+ /// asynchronous message listener, what happens to messages in the
+ /// internal read ahead buffer when the message consumer is closed.
+ /// </summary>
+ [UriAttribute("wmq.ReadAheadClosePolicy")]
+ public ReadAheadClosePolicy ReadAheadClosePolicy
+ {
+ get { return XMSConvert.ToReadAheadClosePolicy(this.XMSReadAheadClosePolicy); }
+ set { this.XMSReadAheadClosePolicy = XMSConvert.ToXMSReadAheadClosePolicy(value); }
+ }
+
+ /// <summary>
+ /// Destination property that sets the target CCSID for queue manager
+ /// message conversion. The value is ignored unless
+ /// <c>XMSC.WMQ_RECEIVE_CONVERSION</c> is set to
+ /// <c>WMQ_RECEIVE_CONVERSION_QMGR</c>.
+ /// </summary>
+ [UriAttribute("wmq.ReceiveCCSID")]
+ public Int32 ReceiveCCSID
+ {
+ get { return this.xmsDestination.GetIntProperty(XMSC.WMQ_RECEIVE_CCSID); }
+ set { this.xmsDestination.SetIntProperty(XMSC.WMQ_RECEIVE_CCSID, value); }
+ }
+
+ /// <summary>
+ /// Destination property that determines whether data conversion is
+ /// going to be performed by the queue manager.
+ /// </summary>
+ [UriAttribute("wmq.XMSReceiveConversion")]
+ public Int32 XMSReceiveConversion
+ {
+ get { return this.xmsDestination.GetIntProperty(XMSC.WMQ_RECEIVE_CONVERSION); }
+ set { this.xmsDestination.SetIntProperty(XMSC.WMQ_RECEIVE_CONVERSION, value); }
+ }
+
+ /// <summary>
+ /// Destination property that determines whether data conversion is
+ /// going to be performed by the queue manager.
+ /// </summary>
+ [UriAttribute("wmq.ReceiveConversion")]
+ public ReceiveConversion ReceiveConversion
+ {
+ get { return XMSConvert.ToReceiveConversion(this.XMSReceiveConversion); }
+ set { this.XMSReceiveConversion = XMSConvert.ToXMSReceiveConversion(value); }
+ }
+
+ /// <summary>
+ /// Whether messages sent to the destination contain an <c>MQRFH2</c>
+ /// header.
+ /// </summary>
+ [UriAttribute("wmq.XMSTargetClient")]
+ public Int32 XMSTargetClient
+ {
+ get { return this.xmsDestination.GetIntProperty(XMSC.WMQ_TARGET_CLIENT); }
+ set { this.xmsDestination.SetIntProperty(XMSC.WMQ_TARGET_CLIENT, value); }
+ }
+
+ /// <summary>
+ /// Whether messages sent to the destination contain an <c>MQRFH2</c>
+ /// header.
+ /// </summary>
+ [UriAttribute("wmq.TargetClient")]
+ public TargetClient TargetClient
+ {
+ get { return XMSConvert.ToTargetClient(this.XMSTargetClient); }
+ set { this.XMSTargetClient = XMSConvert.ToXMSTargetClient(value); }
+ }
+
+ /// <summary>
+ /// When creating temporary topics, XMS generates a topic string of
+ /// the form "TEMP/TEMPTOPICPREFIX/unique_id", or if this property
+ /// contains the default value, then this string, "TEMP/unique_id",
+ /// is generated. Specifying a non-empty value allows specific model
+ /// queues to be defined for creating the managed queues for subscribers
+ /// to temporary topics created under this connection.
+ /// </summary>
+ [UriAttribute("wmq.TemporaryTopicPrefix")]
+ public string WMQTemporaryTopicPrefix
+ {
+ get { return this.xmsDestination.GetStringProperty(XMSC.WMQ_TEMP_TOPIC_PREFIX); }
+ set { this.xmsDestination.SetStringProperty(XMSC.WMQ_TEMP_TOPIC_PREFIX, value); }
+ }
+
+ #endregion
+
+ #region WPM-specific properties
+
+ /// <summary>
+ /// The name of the service integration bus in which the destination
+ /// exists.
+ /// </summary>
+ [UriAttribute("wpm.BusName")]
+ public string BusName
+ {
+ get { return this.xmsDestination.GetStringProperty(XMSC.WPM_BUS_NAME); }
+ set { this.xmsDestination.SetStringProperty(XMSC.WPM_BUS_NAME, value); }
+ }
+
+
+ /// <summary>
+ /// The name of the topic space that contains the topic.
+ /// </summary>
+ [UriAttribute("wpm.TopicSpace")]
+ public string TopicSpace
+ {
+ get { return this.xmsDestination.GetStringProperty(XMSC.WPM_TOPIC_SPACE); }
+ set { this.xmsDestination.SetStringProperty(XMSC.WPM_TOPIC_SPACE, value); }
+ }
+
+ #endregion
+
+ #endregion
+
+ #region IDisposable implementation
+
+ public void Dispose()
+ {
+ }
+
+ #endregion
+ }
+}
diff --git a/src/main/csharp/InitialContext.cs b/src/main/csharp/InitialContext.cs
new file mode 100644
index 0000000..3b9ed83
--- /dev/null
+++ b/src/main/csharp/InitialContext.cs
@@ -0,0 +1,174 @@
+/*
+ * 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.
+ */
+using System;
+using System.Collections;
+using System.Collections.Specialized;
+using Apache.NMS.XMS.Util;
+using Apache.NMS.Policies;
+using Apache.NMS.Util;
+using IBM.XMS;
+
+namespace Apache.NMS.XMS
+{
+ /// <summary>
+ /// An Initial Context for querying object repositories for object
+ /// definitions.
+ /// </summary>
+ public class InitialContext : IDisposable
+ {
+ public IBM.XMS.InitialContext xmsInitialContext;
+
+ #region Constructors
+
+ /// <summary>
+ /// Constructs an <c>InitialContext</c> object.
+ /// </summary>
+ /// <param name="environment">Environment settings.</param>
+ public InitialContext(Hashtable environment)
+ {
+ this.xmsInitialContext = new IBM.XMS.InitialContext(environment);
+ }
+
+ /// <summary>
+ /// Constructs an <c>InitialContext</c> object specifying the
+ /// repository URL.
+ /// </summary>
+ /// <param name="environment">Environment settings.</param>
+ /// <param name="repositoryURL">Repository URL.</param>
+ public InitialContext(Hashtable environment, string repositoryURL)
+ {
+ this.xmsInitialContext = new IBM.XMS.InitialContext(environment);
+ this.RepositoryURL = repositoryURL;
+ }
+
+ #endregion
+
+ #region Initial Context Properties (configure via ConnectionFactory URL parameters)
+
+ // http://www-01.ibm.com/support/knowledgecenter/SSFKSJ_8.0.0/com.ibm.mq.msc.doc/props_inctx.htm?lang=en
+
+ /// <summary>
+ /// Repository URL.
+ /// </summary>
+ [UriAttribute("ic.RepositoryURL")]
+ public string RepositoryURL
+ {
+ get { return (string)this.xmsInitialContext.Environment[XMSC.IC_URL]; }
+ set { this.xmsInitialContext.Environment[XMSC.IC_URL] = value; }
+ }
+
+ /// <summary>
+ /// Initial context provider URL.
+ /// </summary>
+ [UriAttribute("ic.ProviderURL")]
+ public string ProviderURL
+ {
+ get { return (string)this.xmsInitialContext.Environment[XMSC.IC_PROVIDER_URL]; }
+ set { this.xmsInitialContext.Environment[XMSC.IC_PROVIDER_URL] = value; }
+ }
+
+ /// <summary>
+ /// Initial context security protocol.
+ /// </summary>
+ [UriAttribute("ic.SecurityProtocol")]
+ public string SecurityProtocol
+ {
+ get { return (string)this.xmsInitialContext.Environment[XMSC.IC_SECURITY_PROTOCOL]; }
+ set { this.xmsInitialContext.Environment[XMSC.IC_SECURITY_PROTOCOL] = value; }
+ }
+
+ /// <summary>
+ /// Initial context security authentication.
+ /// </summary>
+ [UriAttribute("ic.SecurityAuthentication")]
+ public string SecurityAuthentication
+ {
+ get { return (string)this.xmsInitialContext.Environment[XMSC.IC_SECURITY_AUTHENTICATION]; }
+ set { this.xmsInitialContext.Environment[XMSC.IC_SECURITY_AUTHENTICATION] = value; }
+ }
+
+ /// <summary>
+ /// Initial context security principal.
+ /// </summary>
+ [UriAttribute("ic.SecurityPrincipal")]
+ public string SecurityPrincipal
+ {
+ get { return (string)this.xmsInitialContext.Environment[XMSC.IC_SECURITY_PRINCIPAL]; }
+ set { this.xmsInitialContext.Environment[XMSC.IC_SECURITY_PRINCIPAL] = value; }
+ }
+
+ /// <summary>
+ /// Initial context security credentials.
+ /// </summary>
+ [UriAttribute("ic.SecurityCredentials")]
+ public string SecurityCredentials
+ {
+ get { return (string)this.xmsInitialContext.Environment[XMSC.IC_SECURITY_CREDENTIALS]; }
+ set { this.xmsInitialContext.Environment[XMSC.IC_SECURITY_CREDENTIALS] = value; }
+ }
+
+ #endregion
+
+ #region InitialContext Methods
+
+ /// <summary>
+ /// Create an object from an object definition that is retrieved from
+ /// the repository of administered objects.
+ /// </summary>
+ /// <param name="objectName">Requested object name.</param>
+ /// <returns>Requested object, or null if the requested object is
+ /// not found.</returns>
+ public object Lookup(string objectName)
+ {
+ return this.xmsInitialContext.Lookup(objectName);
+ }
+
+ /// <summary>
+ /// Add a new property to the environment.
+ /// </summary>
+ /// <param name="propertyName">Property name.</param>
+ /// <param name="propertyValue">Property value.</param>
+ /// <returns>Old property value.</returns>
+ public object AddToEnvironment(
+ string propertyName, object propertyValue)
+ {
+ return this.xmsInitialContext.AddToEnvironment(
+ propertyName, propertyValue);
+ }
+
+ /// <summary>
+ /// Remove a property from the environment.
+ /// </summary>
+ /// <param name="propertyName">Property name.</param>
+ /// <returns>Old property value.</returns>
+ public object RemoveFromEnvironment(string propertyName)
+ {
+ return this.xmsInitialContext.RemoveFromEnvironment(propertyName);
+ }
+
+ #endregion
+
+ #region IDisposable
+
+ public void Dispose()
+ {
+ this.xmsInitialContext.Close();
+ }
+
+ #endregion
+ }
+}
diff --git a/src/main/csharp/MapMessage.cs b/src/main/csharp/MapMessage.cs
new file mode 100644
index 0000000..188e3d7
--- /dev/null
+++ b/src/main/csharp/MapMessage.cs
@@ -0,0 +1,719 @@
+/*
+ * 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.
+ */
+using System;
+using System.Collections;
+using Apache.NMS;
+using Apache.NMS.Util;
+using Apache.NMS.XMS.Util;
+using IBM.XMS;
+
+namespace Apache.NMS.XMS
+{
+ /// <summary>
+ /// Represents a map message which contains key and value pairs which are
+ /// of primitive types.
+ /// </summary>
+ class MapMessage : Apache.NMS.XMS.Message, Apache.NMS.IMapMessage,
+ Apache.NMS.IPrimitiveMap
+ {
+ #region Constructors and access to internal map message
+
+ /// <summary>
+ /// Internal IBM XMS map message.
+ /// </summary>
+ public IBM.XMS.IMapMessage xmsMapMessage
+ {
+ get { return (IBM.XMS.IMapMessage)(this.xmsMessage); }
+ set { this.xmsMessage = value; }
+ }
+
+ /// <summary>
+ /// Constructs a <c>MapMessage</c> object.
+ /// </summary>
+ /// <param name="message">XMS map message.</param>
+ public MapMessage(IBM.XMS.IMapMessage message)
+ : base(message)
+ {
+ }
+
+ #endregion
+
+ #region IMapMessage Members
+
+ public Apache.NMS.IPrimitiveMap Body
+ {
+ get { return this; }
+ }
+
+ #endregion
+
+ #region IPrimitiveMap Members
+
+ #region General methods
+
+ /// <summary>
+ /// Clears the contents of the message body.
+ /// </summary>
+ public void Clear()
+ {
+ try
+ {
+ this.ReadOnlyBody = false;
+ this.xmsMapMessage.ClearBody();
+ }
+ catch(Exception ex)
+ {
+ ExceptionUtil.WrapAndThrowNMSException(ex);
+ }
+ }
+
+ /// <summary>
+ /// Checks if the body contains the specified item.
+ /// </summary>
+ /// <param name="key">Item key.</param>
+ public bool Contains(object key)
+ {
+ try
+ {
+ return this.xmsMapMessage.ItemExists(key.ToString());
+ }
+ catch(Exception ex)
+ {
+ ExceptionUtil.WrapAndThrowNMSException(ex);
+ return false;
+ }
+ }
+
+ /// <summary>
+ /// Removes an item from the map message body.
+ /// </summary>
+ /// <param name="key">Item key.</param>
+ public void Remove(object key)
+ {
+ try
+ {
+ // Best guess at equivalent implementation.
+ this.xmsMapMessage.SetObject(key.ToString(), null);
+ }
+ catch(Exception ex)
+ {
+ ExceptionUtil.WrapAndThrowNMSException(ex);
+ }
+ }
+
+ /// <summary>
+ /// Count of key/value pairs in the message body.
+ /// </summary>
+ public int Count
+ {
+ get
+ {
+ int count = 0;
+
+ try
+ {
+ IEnumerator mapNames = this.xmsMapMessage.MapNames;
+ while(mapNames.MoveNext())
+ {
+ count++;
+ }
+ }
+ catch(Exception ex)
+ {
+ ExceptionUtil.WrapAndThrowNMSException(ex);
+ }
+
+ return count;
+ }
+ }
+
+ /// <summary>
+ /// The collection of keys in the mep message body.
+ /// </summary>
+ public ICollection Keys
+ {
+ get
+ {
+ ArrayList keys = new ArrayList();
+
+ try
+ {
+ IEnumerator mapNames = this.xmsMapMessage.MapNames;
+ while(mapNames.MoveNext())
+ {
+ keys.Add(mapNames.Current);
+ }
+ }
+ catch(Exception ex)
+ {
+ ExceptionUtil.WrapAndThrowNMSException(ex);
+ }
+
+ return keys;
+ }
+ }
+
+ /// <summary>
+ /// The collection of values in the mep message body.
+ /// </summary>
+ public ICollection Values
+ {
+ get
+ {
+ ArrayList values = new ArrayList();
+
+ try
+ {
+ IEnumerator mapNames = this.xmsMapMessage.MapNames;
+ while(mapNames.MoveNext())
+ {
+ string key = (string)mapNames.Current;
+ values.Add(this.xmsMapMessage.GetObject(key));
+ }
+ }
+ catch(Exception ex)
+ {
+ ExceptionUtil.WrapAndThrowNMSException(ex);
+ }
+
+ return values;
+ }
+ }
+
+ /// <summary>
+ /// Accesses an item by its key.
+ /// </summary>
+ /// <param name="key">Item key.</param>
+ public object this[string key]
+ {
+ get
+ {
+ try
+ {
+ return this.xmsMapMessage.GetObject(key);
+ }
+ catch(Exception ex)
+ {
+ ExceptionUtil.WrapAndThrowNMSException(ex);
+ return null;
+ }
+ }
+ set
+ {
+ try
+ {
+ this.xmsMapMessage.SetObject(key, value);
+ }
+ catch(Exception ex)
+ {
+ ExceptionUtil.WrapAndThrowNMSException(ex);
+ }
+ }
+ }
+
+ #endregion
+
+ #region String items
+
+ /// <summary>
+ /// Gets the value of a <c>string</c> item.
+ /// </summary>
+ /// <param name="key">Item key.</param>
+ /// <returns>Item value.</returns>
+ public string GetString(string key)
+ {
+ try
+ {
+ return this.xmsMapMessage.GetString(key);
+ }
+ catch(Exception ex)
+ {
+ ExceptionUtil.WrapAndThrowNMSException(ex);
+ return null;
+ }
+ }
+
+ /// <summary>
+ /// Sets the value of a <c>string</c> item.
+ /// </summary>
+ /// <param name="key">Item key.</param>
+ /// <param name="value">Item value.</param>
+ public void SetString(string key, string value)
+ {
+ try
+ {
+ this.xmsMapMessage.SetString(key, value);
+ }
+ catch(Exception ex)
+ {
+ ExceptionUtil.WrapAndThrowNMSException(ex);
+ }
+ }
+
+ #endregion
+
+ #region Boolean items
+
+ /// <summary>
+ /// Gets the value of a <c>bool</c> item.
+ /// </summary>
+ /// <param name="key">Item key.</param>
+ /// <returns>Item value.</returns>
+ public bool GetBool(string key)
+ {
+ try
+ {
+ return this.xmsMapMessage.GetBoolean(key);
+ }
+ catch(Exception ex)
+ {
+ ExceptionUtil.WrapAndThrowNMSException(ex);
+ return false;
+ }
+ }
+
+ /// <summary>
+ /// Sets the value of a <c>bool</c> item.
+ /// </summary>
+ /// <param name="key">Item key.</param>
+ /// <param name="value">Item value.</param>
+ public void SetBool(string key, bool value)
+ {
+ try
+ {
+ this.xmsMapMessage.SetBoolean(key, value);
+ }
+ catch(Exception ex)
+ {
+ ExceptionUtil.WrapAndThrowNMSException(ex);
+ }
+ }
+
+ #endregion
+
+ #region Byte items
+
+ /// <summary>
+ /// Gets the value of a <c>byte</c> item.
+ /// </summary>
+ /// <param name="key">Item key.</param>
+ /// <returns>Item value.</returns>
+ public byte GetByte(string key)
+ {
+ try
+ {
+ return this.xmsMapMessage.GetByte(key);
+ }
+ catch(Exception ex)
+ {
+ ExceptionUtil.WrapAndThrowNMSException(ex);
+ return 0;
+ }
+ }
+
+ /// <summary>
+ /// Sets the value of a <c>byte</c> item.
+ /// </summary>
+ /// <param name="key">Item key.</param>
+ /// <param name="value">Item value.</param>
+ public void SetByte(string key, byte value)
+ {
+ try
+ {
+ this.xmsMapMessage.SetByte(key, value);
+ }
+ catch(Exception ex)
+ {
+ ExceptionUtil.WrapAndThrowNMSException(ex);
+ }
+ }
+
+ #endregion
+
+ #region Char items
+
+ /// <summary>
+ /// Gets the value of a <c>char</c> item.
+ /// </summary>
+ /// <param name="key">Item key.</param>
+ /// <returns>Item value.</returns>
+ public char GetChar(string key)
+ {
+ try
+ {
+ return this.xmsMapMessage.GetChar(key);
+ }
+ catch(Exception ex)
+ {
+ ExceptionUtil.WrapAndThrowNMSException(ex);
+ return (char) 0;
+ }
+ }
+
+ /// <summary>
+ /// Sets the value of a <c>char</c> item.
+ /// </summary>
+ /// <param name="key">Item key.</param>
+ /// <param name="value">Item value.</param>
+ public void SetChar(string key, char value)
+ {
+ try
+ {
+ this.xmsMapMessage.SetChar(key, value);
+ }
+ catch(Exception ex)
+ {
+ ExceptionUtil.WrapAndThrowNMSException(ex);
+ }
+ }
+
+ #endregion
+
+ #region Short items
+
+ /// <summary>
+ /// Gets the value of a 16 bits <c>short</c> integer item.
+ /// </summary>
+ /// <param name="key">Item key.</param>
+ /// <returns>Item value.</returns>
+ public short GetShort(string key)
+ {
+ try
+ {
+ return this.xmsMapMessage.GetShort(key);
+ }
+ catch(Exception ex)
+ {
+ ExceptionUtil.WrapAndThrowNMSException(ex);
+ return 0;
+ }
+ }
+
+ /// <summary>
+ /// Sets the value of a 16 bits <c>short</c> integer item.
+ /// </summary>
+ /// <param name="key">Item key.</param>
+ /// <param name="value">Item value.</param>
+ public void SetShort(string key, short value)
+ {
+ try
+ {
+ this.xmsMapMessage.SetShort(key, value);
+ }
+ catch(Exception ex)
+ {
+ ExceptionUtil.WrapAndThrowNMSException(ex);
+ }
+ }
+
+ #endregion
+
+ #region Int items
+
+ /// <summary>
+ /// Gets the value of a 32 bits <c>int</c> integer item.
+ /// </summary>
+ /// <param name="key">Item key.</param>
+ /// <returns>Item value.</returns>
+ public int GetInt(string key)
+ {
+ try
+ {
+ return this.xmsMapMessage.GetInt(key);
+ }
+ catch(Exception ex)
+ {
+ ExceptionUtil.WrapAndThrowNMSException(ex);
+ return 0;
+ }
+ }
+
+ /// <summary>
+ /// Sets the value of a 32 bits <c>int</c> integer item.
+ /// </summary>
+ /// <param name="key">Item key.</param>
+ /// <param name="value">Item value.</param>
+ public void SetInt(string key, int value)
+ {
+ try
+ {
+ this.xmsMapMessage.SetInt(key, value);
+ }
+ catch(Exception ex)
+ {
+ ExceptionUtil.WrapAndThrowNMSException(ex);
+ }
+ }
+
+ #endregion
+
+ #region Long items
+
+ /// <summary>
+ /// Gets the value of a 64 bits <c>long</c> integer item.
+ /// </summary>
+ /// <param name="key">Item key.</param>
+ /// <returns>Item value.</returns>
+ public long GetLong(string key)
+ {
+ try
+ {
+ return this.xmsMapMessage.GetLong(key);
+ }
+ catch(Exception ex)
+ {
+ ExceptionUtil.WrapAndThrowNMSException(ex);
+ return 0;
+ }
+ }
+
+ /// <summary>
+ /// Sets the value of a 64 bits <c>long</c> integer item.
+ /// </summary>
+ /// <param name="key">Item key.</param>
+ /// <param name="value">Item value.</param>
+ public void SetLong(string key, long value)
+ {
+ try
+ {
+ this.xmsMapMessage.SetLong(key, value);
+ }
+ catch(Exception ex)
+ {
+ ExceptionUtil.WrapAndThrowNMSException(ex);
+ }
+ }
+
+ #endregion
+
+ #region Float items
+
+ /// <summary>
+ /// Gets the value of a <c>float</c> item.
+ /// </summary>
+ /// <param name="key">Item key.</param>
+ /// <returns>Item value.</returns>
+ public float GetFloat(string key)
+ {
+ try
+ {
+ return this.xmsMapMessage.GetFloat(key);
+ }
+ catch(Exception ex)
+ {
+ ExceptionUtil.WrapAndThrowNMSException(ex);
+ return 0;
+ }
+ }
+
+ /// <summary>
+ /// Sets the value of a <c>float</c> item.
+ /// </summary>
+ /// <param name="key">Item key.</param>
+ /// <param name="value">Item value.</param>
+ public void SetFloat(string key, float value)
+ {
+ try
+ {
+ this.xmsMapMessage.SetFloat(key, value);
+ }
+ catch(Exception ex)
+ {
+ ExceptionUtil.WrapAndThrowNMSException(ex);
+ }
+ }
+
+ #endregion
+
+ #region Double items
+
+ /// <summary>
+ /// Gets the value of a <c>double</c> item.
+ /// </summary>
+ /// <param name="key">Item key.</param>
+ /// <returns>Item value.</returns>
+ public double GetDouble(string key)
+ {
+ try
+ {
+ return this.xmsMapMessage.GetDouble(key);
+ }
+ catch(Exception ex)
+ {
+ ExceptionUtil.WrapAndThrowNMSException(ex);
+ return 0;
+ }
+ }
+
+ /// <summary>
+ /// Sets the value of a <c>double</c> item.
+ /// </summary>
+ /// <param name="key">Item key.</param>
+ /// <param name="value">Item value.</param>
+ public void SetDouble(string key, double value)
+ {
+ try
+ {
+ this.xmsMapMessage.SetDouble(key, value);
+ }
+ catch(Exception ex)
+ {
+ ExceptionUtil.WrapAndThrowNMSException(ex);
+ }
+ }
+
+ #endregion
+
+ #region List items
+
+ /// <summary>
+ /// Gets the value of an <c>IList</c> item.
+ /// </summary>
+ /// <param name="key">Item key.</param>
+ /// <returns>Item value.</returns>
+ public IList GetList(string key)
+ {
+ try
+ {
+ return (IList) this.xmsMapMessage.GetObject(key);
+ }
+ catch(Exception ex)
+ {
+ ExceptionUtil.WrapAndThrowNMSException(ex);
+ return null;
+ }
+ }
+
+ /// <summary>
+ /// Sets the value of an <c>IList</c> item.
+ /// </summary>
+ /// <param name="key">Item key.</param>
+ /// <param name="list">Item value.</param>
+ public void SetList(string key, IList list)
+ {
+ try
+ {
+ this.xmsMapMessage.SetObject(key, list);
+ }
+ catch(Exception ex)
+ {
+ ExceptionUtil.WrapAndThrowNMSException(ex);
+ }
+ }
+
+ #endregion
+
+ #region Bytes array items
+
+ /// <summary>
+ /// Gets the value of a <c>byte[]</c> byte array item.
+ /// </summary>
+ /// <param name="key">Item key.</param>
+ /// <returns>Item value.</returns>
+ public byte[] GetBytes(string key)
+ {
+ try
+ {
+ return this.xmsMapMessage.GetBytes(key);
+ }
+ catch(Exception ex)
+ {
+ ExceptionUtil.WrapAndThrowNMSException(ex);
+ return null;
+ }
+ }
+
+ /// <summary>
+ /// Sets the value of a <c>byte[]</c> byte array item.
+ /// </summary>
+ /// <param name="key">Item key.</param>
+ /// <param name="value">Item value.</param>
+ public void SetBytes(string key, byte[] value)
+ {
+ try
+ {
+ this.xmsMapMessage.SetBytes(key, value);
+ }
+ catch(Exception ex)
+ {
+ ExceptionUtil.WrapAndThrowNMSException(ex);
+ }
+ }
+
+ /// <summary>
+ /// Sets the value of a <c>byte[]</c> byte array item.
+ /// </summary>
+ /// <param name="key">Item key.</param>
+ /// <param name="value">Byte array from which value is extracted.</param>
+ /// <param name="offset">Index of first byte to extract.</param>
+ /// <param name="length">Number of bytes to extract.</param>
+ public void SetBytes(string key, byte[] value, int offset, int length)
+ {
+ try
+ {
+ this.xmsMapMessage.SetBytes(key, value, offset, length);
+ }
+ catch(Exception ex)
+ {
+ ExceptionUtil.WrapAndThrowNMSException(ex);
+ }
+ }
+
+ #endregion
+
+ #region Dictionary items
+
+ /// <summary>
+ /// Gets the value of an <c>IDictionary</c> item.
+ /// </summary>
+ /// <param name="key">Item key.</param>
+ /// <returns>Item value.</returns>
+ public IDictionary GetDictionary(string key)
+ {
+ try
+ {
+ return (IDictionary) this.xmsMapMessage.GetObject(key);
+ }
+ catch(Exception ex)
+ {
+ ExceptionUtil.WrapAndThrowNMSException(ex);
+ return null;
+ }
+ }
+
+ /// <summary>
+ /// Sets the value of an <c>IDictionary</c> item.
+ /// </summary>
+ /// <param name="key">Item key.</param>
+ /// <param name="dictionary">Item value.</param>
+ public void SetDictionary(string key, IDictionary dictionary)
+ {
+ try
+ {
+ this.xmsMapMessage.SetObject(key, dictionary);
+ }
+ catch(Exception ex)
+ {
+ ExceptionUtil.WrapAndThrowNMSException(ex);
+ }
+ }
+
+ #endregion
+
+ #endregion
+ }
+}
diff --git a/src/main/csharp/Message.cs b/src/main/csharp/Message.cs
new file mode 100644
index 0000000..278b73c
--- /dev/null
+++ b/src/main/csharp/Message.cs
@@ -0,0 +1,526 @@
+/*
+ * 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.
+ */
+using System;
+using Apache.NMS.Util;
+using Apache.NMS.XMS.Util;
+using IBM.XMS;
+
+namespace Apache.NMS.XMS
+{
+ /// <summary>
+ /// Represents a message either to be sent to a message broker or received
+ /// from a message broker.
+ /// </summary>
+ class Message : Apache.NMS.IMessage
+ {
+ public IBM.XMS.IMessage xmsMessage;
+
+ #region Constructors
+
+ /// <summary>
+ /// Constructs a <c>Message</c> object.
+ /// </summary>
+ /// <param name="message">XMS message.</param>
+ public Message(IBM.XMS.IMessage message)
+ {
+ this.xmsMessage = message;
+ }
+
+ #endregion
+
+ #region IMessage Members
+
+ #region Acknowledgement
+
+ /// <summary>
+ /// If using client acknowledgement mode on the session then this
+ /// method will acknowledge that the message has been processed
+ /// correctly.
+ /// </summary>
+ public void Acknowledge()
+ {
+ try
+ {
+ this.xmsMessage.Acknowledge();
+ }
+ catch(Exception ex)
+ {
+ ExceptionUtil.WrapAndThrowNMSException(ex);
+ }
+ }
+
+ #endregion
+
+ #region Message body
+
+ private bool readOnlyMsgBody = false;
+ /// <summary>
+ /// Whether the message body is read-only.
+ /// </summary>
+ public virtual bool ReadOnlyBody
+ {
+ get { return this.readOnlyMsgBody; }
+ set { this.readOnlyMsgBody = value; }
+ }
+
+ /// <summary>
+ /// Clears out the message body. Clearing a message's body does not
+ /// clear its header values or property entries.
+ /// If this message body was read-only, calling this method leaves
+ /// the message body in the same state as an empty body in a newly
+ /// created message.
+ /// </summary>
+ public void ClearBody()
+ {
+ try
+ {
+ this.ReadOnlyBody = false;
+ this.xmsMessage.ClearBody();
+ }
+ catch(Exception ex)
+ {
+ ExceptionUtil.WrapAndThrowNMSException(ex);
+ }
+ }
+
+ #endregion
+
+ #region Message properties
+
+ #region General comments
+
+ // https://docs.oracle.com/cd/E19798-01/821-1841/bnces/index.html
+ // A JMS message has three parts: a header, properties, and a body.
+ // A JMS message header contains a number of predefined fields that
+ // contain values that both clients and providers use to identify
+ // and to route messages:
+ // Header Field Set By
+ // JMSDestination send or publish method
+ // JMSDeliveryMode send or publish method
+ // JMSExpiration send or publish method
+ // JMSPriority send or publish method
+ // JMSMessageID send or publish method
+ // JMSTimestamp send or publish method
+ // JMSCorrelationID Client
+ // JMSReplyTo Client
+ // JMSType Client
+ // JMSRedelivered JMS provider
+ // Properties can be created and set for messages if values are needed
+ // in addition to those provided by the header fields.
+ // The JMS API provides some predefined property names that a provider
+ // can support. The use either of these predefined properties or of
+ // user-defined properties is optional.
+ // The JMS API defines five message body formats:
+ // Message Type Body Contains
+ // TextMessage A java.lang.String object.
+ // MapMessage A set of name-value pairs, with names as String
+ // objects and values as primitive types.
+ // BytesMessage A stream of uninterpreted bytes.
+ // StreamMessage A stream of primitive values, filled and read
+ // sequentially.
+ // ObjectMessage A Serializable object.
+ // Message Nothing. Composed of header fields and properties
+ // only.
+ //
+ // http://www-01.ibm.com/support/knowledgecenter/SSFKSJ_8.0.0/com.ibm.mq.msc.doc/xms_cmesmod.htm?lang=en
+ // The XMS message model is the same as the WebSphere® MQ classes for
+ // JMS message model.
+ // In particular, XMS implements the same message header fields and
+ // message properties that WebSphere MQ classes for JMS implements:
+ // JMS header fields. These fields have names that commence
+ // with the prefix JMS.
+ // JMS defined properties. These fields have properties whose names
+ // commence with the prefix JMSX.
+ // IBM® defined properties. These fields have properties whose names
+ // commence with the prefix JMS_IBM_.
+ //
+ // Apache.NMS redefines JMS message header fields with an "NMS" prefix:
+ // JMS NMS IBM.XMS
+ // Destination JMSDestination IDestination NMSDestination IDestination JMSDestination
+ // int JMSDeliveryMode MsgDeliveryMode NMSDeliveryMode DeliveryMode JMSDeliveryMode
+ // long JMSExpiration [TimeSpan NMSTimeToLive] Int64 JMSExpiration
+ // int JMSPriority MsgPriority NMSPriority Int32 JMSPriority
+ // String JMSMessageID string NMSMessageId String JMSMessageID
+ // long JMSTimestamp DateTime NMSTimestamp Int64 JMSTimestamp
+ // String JMSCorrelationID string NMSCorrelationID String JMSCorrelationID
+ // Destination JMSReplyTo IDestination NMSReplyTo IDestination JMSReplyTo
+ // String JMSType string NMSType String JMSType
+ // boolean JMSRedelivered bool NMSRedelivered Boolean JMSRedelivered
+ // Properties are set and retrieved through typed SetXxxProperty and
+ // GetXxxProperty methods.
+ // Unlike JMS, Apache.NMS does not expose those methods in the
+ // IMessage interface, but through the IPrimitiveMap interface,
+ // implemented by the MessageProperties class, exposed through
+ // the IMessage.Properties property.
+ // The MessagePropertyIntercepter propertyHelper intercepts get and
+ // set invocations on properties whose name starts with "NMS", and
+ // maps them to the equivalent message header fields through
+ // reflection. Other invocations are routed to the
+ // MessageProperties.Get/SetObjetProperty methods, which in turn
+ // invokes xmsMessage.Get/SetObjectProperty.
+ //
+ // XMS message properties are:
+ // XMSC.JMS_DESTINATION = "JMSDestination"
+ // XMSC.JMS_DELIVERY_MODE = "JMSDeliveryMode"
+ // XMSC.JMS_EXPIRATION = "JMSExpiration"
+ // XMSC.JMS_PRIORITY = "JMSPriority"
+ // XMSC.JMS_MESSAGEID = "JMSMessageID"
+ // XMSC.JMS_TIMESTAMP = "JMSTimestamp"
+ // XMSC.JMS_CORRELATIONID = "JMSCorrelationID"
+ // XMSC.JMS_REPLYTO = "JMSReplyto"
+ // XMSC.JMS_TYPE = "JMSType"
+ // XMSC.JMS_REDELIVERED = "JMSRedelivered"
+ //
+ // XMSC.JMSX_USERID = "JMSXUserID"
+ // XMSC.JMSX_APPID = "JMSXAppID"
+ // XMSC.JMSX_DELIVERY_COUNT = "JMSXDeliveryCount"
+ // XMSC.JMSX_GROUPID = "JMSXGroupID"
+ // XMSC.JMSX_GROUPSEQ = "JMSXGroupSeq"
+ // XMSC.JMSX_STATE = "JMSXState"
+ // XMSC.JMSX_PRODUCER_TXID = "JMSXProducerTXID"
+ // XMSC.JMSX_CONSUMER_TXID = "JMSXConsumerTXID"
+ // XMSC.JMSX_RCV_TIMESTAMP = "JMSXRcvTimestamp"
+
+ // XMSC.JMS_IBM_REPORT_EXCEPTION = "JMS_IBM_Report_Exception"
+ // XMSC.JMS_IBM_REPORT_EXPIRATION = "JMS_IBM_Report_Expiration"
+ // XMSC.JMS_IBM_REPORT_COA = "JMS_IBM_Report_COA"
+ // XMSC.JMS_IBM_REPORT_COD = "JMS_IBM_Report_COD"
+ // XMSC.JMS_IBM_REPORT_NAN = "JMS_IBM_Report_NAN"
+ // XMSC.JMS_IBM_REPORT_PAN = "JMS_IBM_Report_PAN"
+ // XMSC.JMS_IBM_REPORT_PASS_MSG_ID = "JMS_IBM_Report_Pass_Msg_ID"
+ // XMSC.JMS_IBM_REPORT_PASS_CORREL_ID = "JMS_IBM_Report_Pass_Correl_ID"
+ // XMSC.JMS_IBM_REPORT_DISCARD_MSG = "JMS_IBM_Report_Discard_Msg"
+ // XMSC.JMS_IBM_MSGTYPE = "JMS_IBM_MsgType"
+ // XMSC.JMS_IBM_FEEDBACK = "JMS_IBM_Feedback"
+ // XMSC.JMS_IBM_FORMAT = "JMS_IBM_Format"
+ // XMSC.JMS_IBM_PUTAPPLTYPE = "JMS_IBM_PutApplType"
+ // XMSC.JMS_IBM_ENCODING = "JMS_IBM_Encoding"
+ // XMSC.JMS_IBM_CHARACTER_SET = "JMS_IBM_Character_Set"
+ // XMSC.JMS_IBM_PUTDATE = "JMS_IBM_PutDate"
+ // XMSC.JMS_IBM_PUTTIME = "JMS_IBM_PutTime"
+ // XMSC.JMS_IBM_LAST_MSG_IN_GROUP = "JMS_IBM_Last_Msg_In_Group"
+ // XMSC.JMS_IBM_EXCEPTIONREASON = "JMS_IBM_ExceptionReason"
+ // XMSC.JMS_IBM_EXCEPTIONTIMESTAMP = "JMS_IBM_ExceptionTimestamp"
+ // XMSC.JMS_IBM_EXCEPTIONMESSAGE = "JMS_IBM_ExceptionMessage"
+ // XMSC.JMS_IBM_SYSTEM_MESSAGEID = "JMS_IBM_System_MessageID"
+ // XMSC.JMS_IBM_EXCEPTIONPROBLEMDESTINATION = "JMS_IBM_ExceptionProblemDestination"
+ // XMSC.JMS_IBM_ARM_CORRELATOR = "JMS_IBM_ArmCorrelator"
+ // XMSC.JMS_IBM_WAS_RM_CORRELATOR = "JMS_IBM_RMCorrelator"
+ // XMSC.JMS_IBM_CONNECTIONID = "JMS_IBM_ConnectionID"
+ // XMSC.JMS_IBM_RETAIN = "JMS_IBM_Retain"
+ // XMSC.JMS_IBM_MQMD_REPORT = "JMS_IBM_MQMD_Report"
+ // XMSC.JMS_IBM_MQMD_MSGTYPE = "JMS_IBM_MQMD_MsgType"
+ // XMSC.JMS_IBM_MQMD_EXPIRY = "JMS_IBM_MQMD_Expiry"
+ // XMSC.JMS_IBM_MQMD_FEEDBACK = "JMS_IBM_MQMD_Feedback"
+ // XMSC.JMS_IBM_MQMD_ENCODING = "JMS_IBM_MQMD_Encoding"
+ // XMSC.JMS_IBM_MQMD_CODEDCHARSETID = "JMS_IBM_MQMD_CodedCharSetId"
+ // XMSC.JMS_IBM_MQMD_FORMAT = "JMS_IBM_MQMD_Format"
+ // XMSC.JMS_IBM_MQMD_PRIORITY = "JMS_IBM_MQMD_Priority"
+ // XMSC.JMS_IBM_MQMD_PERSISTENCE = "JMS_IBM_MQMD_Persistence"
+ // XMSC.JMS_IBM_MQMD_MSGID = "JMS_IBM_MQMD_MsgId"
+ // XMSC.JMS_IBM_MQMD_CORRELID = "JMS_IBM_MQMD_CorrelId"
+ // XMSC.JMS_IBM_MQMD_BACKOUTCOUNT = "JMS_IBM_MQMD_BackoutCount"
+ // XMSC.JMS_IBM_MQMD_REPLYTOQ = "JMS_IBM_MQMD_ReplyToQ"
+ // XMSC.JMS_IBM_MQMD_REPLYTOQMGR = "JMS_IBM_MQMD_ReplyToQMgr"
+ // XMSC.JMS_IBM_MQMD_USERIDENTIFIER = "JMS_IBM_MQMD_UserIdentifier"
+ // XMSC.JMS_IBM_MQMD_ACCOUNTINGTOKEN = "JMS_IBM_MQMD_AccountingToken"
+ // XMSC.JMS_IBM_MQMD_APPLIDENTITYDATA = "JMS_IBM_MQMD_ApplIdentityData"
+ // XMSC.JMS_IBM_MQMD_PUTAPPLTYPE = "JMS_IBM_MQMD_PutApplType"
+ // XMSC.JMS_IBM_MQMD_PUTAPPLNAME = "JMS_IBM_MQMD_PutApplName"
+ // XMSC.JMS_IBM_MQMD_PUTDATE = "JMS_IBM_MQMD_PutDate"
+ // XMSC.JMS_IBM_MQMD_PUTTIME = "JMS_IBM_MQMD_PutTime"
+ // XMSC.JMS_IBM_MQMD_APPLORIGINDATA = "JMS_IBM_MQMD_ApplOriginData"
+ // XMSC.JMS_IBM_MQMD_GROUPID = "JMS_IBM_MQMD_GroupId"
+ // XMSC.JMS_IBM_MQMD_MSGSEQNUMBER = "JMS_IBM_MQMD_MsgSeqNumber"
+ // XMSC.JMS_IBM_MQMD_OFFSET = "JMS_IBM_MQMD_Offset"
+ // XMSC.JMS_IBM_MQMD_MSGFLAGS = "JMS_IBM_MQMD_MsgFlags"
+ // XMSC.JMS_IBM_MQMD_ORIGINALLENGTH = "JMS_IBM_MQMD_OriginalLength"
+ // XMSC.JMS_TOG_ARM_CORRELATOR = "JMS_TOG_ARM_Correlator"
+
+ #endregion
+
+ #region General methods
+
+ private bool readOnlyMsgProperties = false;
+ /// <summary>
+ /// Whether the message properties is read-only.
+ /// </summary>
+ public virtual bool ReadOnlyProperties
+ {
+ get { return this.readOnlyMsgProperties; }
+
+ set
+ {
+ if(this.propertyHelper != null)
+ {
+ this.propertyHelper.ReadOnly = value;
+ }
+ this.readOnlyMsgProperties = value;
+ }
+ }
+
+ /// <summary>
+ /// Clears a message's properties.
+ /// The message's header fields and body are not cleared.
+ /// </summary>
+ public void ClearProperties()
+ {
+ try
+ {
+ this.ReadOnlyProperties = false;
+ this.xmsMessage.ClearProperties();
+ }
+ catch(Exception ex)
+ {
+ ExceptionUtil.WrapAndThrowNMSException(ex);
+ }
+ }
+
+ private Apache.NMS.IPrimitiveMap properties = null;
+ private Apache.NMS.Util.MessagePropertyIntercepter propertyHelper;
+ /// <summary>
+ /// Provides access to the message properties (headers)
+ /// </summary>
+ public Apache.NMS.IPrimitiveMap Properties
+ {
+ get
+ {
+ if(properties == null)
+ {
+ properties = XMSConvert.ToMessageProperties(this.xmsMessage);
+ propertyHelper = new Apache.NMS.Util.MessagePropertyIntercepter(
+ this, properties, this.ReadOnlyProperties);
+ }
+
+ return propertyHelper;
+ }
+ }
+
+ #endregion
+
+ #region Message header fields
+
+ /// <summary>
+ /// The correlation ID used to correlate messages from conversations
+ /// or long running business processes.
+ /// </summary>
+ public string NMSCorrelationID
+ {
+ get
+ {
+ try
+ {
+ return this.xmsMessage.JMSCorrelationID;
+ }
+ catch(Exception ex)
+ {
+ ExceptionUtil.WrapAndThrowNMSException(ex);
+ return null;
+ }
+ }
+ set
+ {
+ try
+ {
+ this.xmsMessage.JMSCorrelationID = value;
+ }
+ catch(Exception ex)
+ {
+ ExceptionUtil.WrapAndThrowNMSException(ex);
+ }
+ }
+ }
+
+ /// <summary>
+ /// The destination of the message.
+ /// </summary>
+ public Apache.NMS.IDestination NMSDestination
+ {
+ get
+ {
+ return XMSConvert.ToNMSDestination(
+ this.xmsMessage.JMSDestination);
+ }
+ set
+ {
+ try
+ {
+ this.xmsMessage.JMSDestination =
+ XMSConvert.ToXMSDestination(value);
+ }
+ catch(Exception ex)
+ {
+ ExceptionUtil.WrapAndThrowNMSException(ex);
+ }
+ }
+ }
+
+ protected TimeSpan timeToLive;
+ /// <summary>
+ /// The amount of time that this message is valid for.
+ /// <c>null</c> if this message does not expire.
+ /// </summary>
+ public TimeSpan NMSTimeToLive
+ {
+ get { return this.timeToLive; }
+ set { this.timeToLive = value; }
+ }
+
+ /// <summary>
+ /// The message ID which is set by the provider.
+ /// </summary>
+ public string NMSMessageId
+ {
+ get { return this.xmsMessage.JMSMessageID; }
+ set { this.xmsMessage.JMSMessageID = value; }
+ }
+
+ /// <summary>
+ /// Whether or not this message is persistent.
+ /// </summary>
+ public MsgDeliveryMode NMSDeliveryMode
+ {
+ get
+ {
+ return XMSConvert.ToNMSMsgDeliveryMode(
+ this.xmsMessage.JMSDeliveryMode);
+ }
+ set
+ {
+ try
+ {
+ this.xmsMessage.JMSDeliveryMode =
+ XMSConvert.ToJMSDeliveryMode(value);
+ }
+ catch(Exception ex)
+ {
+ ExceptionUtil.WrapAndThrowNMSException(ex);
+ }
+ }
+ }
+
+ /// <summary>
+ /// The Priority on this message.
+ /// </summary>
+ public MsgPriority NMSPriority
+ {
+ get
+ {
+ return (MsgPriority)this.xmsMessage.JMSPriority;
+ }
+ set
+ {
+ try
+ {
+ this.xmsMessage.JMSPriority = (int)value;
+ }
+ catch(Exception ex)
+ {
+ ExceptionUtil.WrapAndThrowNMSException(ex);
+ }
+ }
+ }
+
+ /// <summary>
+ /// Returns true if this message has been redelivered to this or
+ /// another consumer before being acknowledged successfully.
+ /// </summary>
+ public bool NMSRedelivered
+ {
+ get { return this.xmsMessage.JMSRedelivered; }
+ set
+ {
+ throw new NMSException("JMSRedelivered cannot be set.");
+ }
+ }
+
+ /// <summary>
+ /// The destination that the consumer of this message should send
+ /// replies to.
+ /// </summary>
+ public Apache.NMS.IDestination NMSReplyTo
+ {
+ get
+ {
+ return XMSConvert.ToNMSDestination(
+ this.xmsMessage.JMSReplyTo);
+ }
+ set
+ {
+ try
+ {
+ this.xmsMessage.JMSReplyTo =
+ XMSConvert.ToXMSDestination(value);
+ }
+ catch(Exception ex)
+ {
+ ExceptionUtil.WrapAndThrowNMSException(ex);
+ }
+ }
+ }
+
+ /// <summary>
+ /// The timestamp of when the message was pubished in UTC time. If the
+ /// publisher disables setting the timestamp on the message, the time
+ /// will be set to the start of the UNIX epoch (1970-01-01 00:00:00).
+ /// </summary>
+ public DateTime NMSTimestamp
+ {
+ get { return DateUtils.ToDateTime(this.xmsMessage.JMSTimestamp); }
+ set { this.xmsMessage.JMSTimestamp = DateUtils.ToJavaTime(value); }
+ }
+
+ /// <summary>
+ /// The type name of this message.
+ /// </summary>
+ public string NMSType
+ {
+ get { return this.xmsMessage.JMSType; }
+ set
+ {
+ try
+ {
+ this.xmsMessage.JMSType = value;
+ }
+ catch(Exception ex)
+ {
+ ExceptionUtil.WrapAndThrowNMSException(ex);
+ }
+ }
+ }
+
+ #endregion
+
+ #endregion
+
+ #endregion
+
+ #region Event handlers
+
+ public virtual void OnSend()
+ {
+ this.ReadOnlyProperties = true;
+ this.ReadOnlyBody = true;
+ }
+
+ public virtual void OnMessageRollback()
+ {
+ }
+
+ #endregion
+ }
+}
diff --git a/src/main/csharp/MessageConsumer.cs b/src/main/csharp/MessageConsumer.cs
new file mode 100644
index 0000000..1ad2949
--- /dev/null
+++ b/src/main/csharp/MessageConsumer.cs
@@ -0,0 +1,201 @@
+/*
+ * 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.
+ */
+using System;
+using Apache.NMS;
+using Apache.NMS.Util;
+using Apache.NMS.XMS.Util;
+
+namespace Apache.NMS.XMS
+{
+ class MessageConsumer : Apache.NMS.IMessageConsumer
+ {
+ private readonly Apache.NMS.XMS.Util.Dispatcher dispatcher
+ = new Apache.NMS.XMS.Util.Dispatcher();
+ protected readonly Apache.NMS.XMS.Session nmsSession;
+ public IBM.XMS.IMessageConsumer xmsMessageConsumer;
+ private bool closed = false;
+ private bool disposed = false;
+
+ public MessageConsumer(Apache.NMS.XMS.Session session,
+ IBM.XMS.IMessageConsumer consumer)
+ {
+ this.nmsSession = session;
+ this.xmsMessageConsumer = consumer;
+ this.xmsMessageConsumer.MessageListener = this.HandleXmsMessage;
+ }
+
+ ~MessageConsumer()
+ {
+ Dispose(false);
+ }
+
+ #region IMessageConsumer Members
+
+ private ConsumerTransformerDelegate consumerTransformer;
+ /// <summary>
+ /// A Delegate that is called each time a Message is dispatched to allow the client to do
+ /// any necessary transformations on the received message before it is delivered.
+ /// </summary>
+ public ConsumerTransformerDelegate ConsumerTransformer
+ {
+ get { return this.consumerTransformer; }
+ set { this.consumerTransformer = value; }
+ }
+
+ /// <summary>
+ /// Waits until a message is available and returns it
+ /// </summary>
+ public Apache.NMS.IMessage Receive()
+ {
+ return this.dispatcher.Dequeue();
+ }
+
+ /// <summary>
+ /// If a message is available within the timeout duration it is returned otherwise this method returns null
+ /// </summary>
+ public Apache.NMS.IMessage Receive(TimeSpan timeout)
+ {
+ return this.dispatcher.Dequeue(timeout);
+ }
+
+ /// <summary>
+ /// If a message is available immediately it is returned otherwise this method returns null
+ /// </summary>
+ public Apache.NMS.IMessage ReceiveNoWait()
+ {
+ return this.dispatcher.DequeueNoWait();
+ }
+
+ /// <summary>
+ /// An asynchronous listener which can be used to consume messages asynchronously
+ /// </summary>
+ public event Apache.NMS.MessageListener Listener;
+
+ /// <summary>
+ /// Closes the message consumer.
+ /// </summary>
+ /// <remarks>
+ /// Clients should close message consumers them when they are not needed.
+ /// This call blocks until a receive or message listener in progress has completed.
+ /// A blocked message consumer receive call returns null when this message consumer is closed.
+ /// </remarks>
+ public void Close()
+ {
+ lock(this)
+ {
+ if(closed)
+ {
+ return;
+ }
+ }
+
+ // wake up any pending dequeue() call on the dispatcher
+ this.dispatcher.Close();
+
+ lock(this)
+ {
+ try
+ {
+ this.xmsMessageConsumer.MessageListener = null;
+ this.xmsMessageConsumer.Close();
+ }
+ catch(Exception ex)
+ {
+ ExceptionUtil.WrapAndThrowNMSException(ex);
+ }
+ finally
+ {
+ closed = true;
+ }
+ }
+ }
+
+ #endregion
+
+ #region IDisposable Members
+
+ ///<summary>
+ /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.
+ ///</summary>
+ ///<filterpriority>2</filterpriority>
+ public void Dispose()
+ {
+ Dispose(true);
+ GC.SuppressFinalize(this);
+ }
+
+ protected void Dispose(bool disposing)
+ {
+ if(disposed)
+ {
+ return;
+ }
+
+ if(disposing)
+ {
+ // Dispose managed code here.
+ }
+
+ try
+ {
+ Close();
+ }
+ catch
+ {
+ // Ignore errors.
+ }
+
+ disposed = true;
+ }
+
+ #endregion
+
+ private void HandleXmsMessage(IBM.XMS.IMessage xmsMessage)
+ {
+ Apache.NMS.IMessage message = XMSConvert.ToNMSMessage(xmsMessage);
+
+ if(message != null)
+ {
+ if(this.ConsumerTransformer != null)
+ {
+ IMessage newMessage = ConsumerTransformer(this.nmsSession, this, message);
+
+ if(newMessage != null)
+ {
+ message = newMessage;
+ }
+ }
+
+ if(Listener != null)
+ {
+ try
+ {
+ Listener(message);
+ }
+ catch(Exception ex)
+ {
+ Apache.NMS.Tracer.Debug("Error handling message: " + ex.Message);
+ }
+ }
+ else
+ {
+ this.dispatcher.Enqueue(message);
+ }
+ }
+ }
+ }
+}
diff --git a/src/main/csharp/MessageProducer.cs b/src/main/csharp/MessageProducer.cs
new file mode 100644
index 0000000..34da42c
--- /dev/null
+++ b/src/main/csharp/MessageProducer.cs
@@ -0,0 +1,416 @@
+/*
+ * 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.
+ */
+using System;
+using System.Threading;
+using Apache.NMS;
+using Apache.NMS.Util;
+using Apache.NMS.XMS.Util;
+
+namespace Apache.NMS.XMS
+{
+ class MessageProducer : Apache.NMS.IMessageProducer
+ {
+ protected readonly Apache.NMS.XMS.Session nmsSession;
+ public IBM.XMS.IMessageProducer xmsMessageProducer;
+ private TimeSpan requestTimeout = NMSConstants.defaultRequestTimeout;
+ private bool closed = false;
+ private bool disposed = false;
+
+ public MessageProducer(Apache.NMS.XMS.Session session,
+ IBM.XMS.IMessageProducer producer)
+ {
+ this.nmsSession = session;
+ this.xmsMessageProducer = producer;
+ this.RequestTimeout = session.RequestTimeout;
+ }
+
+ ~MessageProducer()
+ {
+ Dispose(false);
+ }
+
+ private Apache.NMS.XMS.Message GetXMSMessage(Apache.NMS.IMessage message)
+ {
+ Apache.NMS.XMS.Message msg = (Apache.NMS.XMS.Message) message;
+
+ if(this.ProducerTransformer != null)
+ {
+ IMessage transformed = this.ProducerTransformer(this.nmsSession, this, message);
+ if(transformed != null)
+ {
+ msg = (Apache.NMS.XMS.Message) transformed;
+ }
+ }
+
+ return msg;
+ }
+
+ #region IMessageProducer Members
+
+ /// <summary>
+ /// Sends the message to the default destination for this producer.
+ /// </summary>
+ public void Send(Apache.NMS.IMessage message)
+ {
+ Apache.NMS.XMS.Message msg = GetXMSMessage(message);
+ long timeToLive = (long) message.NMSTimeToLive.TotalMilliseconds;
+
+ if(0 == timeToLive)
+ {
+ timeToLive = this.xmsMessageProducer.TimeToLive;
+ }
+
+ try
+ {
+ msg.OnSend();
+ this.xmsMessageProducer.Send(
+ msg.xmsMessage,
+ this.xmsMessageProducer.DeliveryMode,
+ this.xmsMessageProducer.Priority,
+ timeToLive);
+ }
+ catch(Exception ex)
+ {
+ ExceptionUtil.WrapAndThrowNMSException(ex);
+ }
+ }
+
+ /// <summary>
+ /// Sends the message to the default destination with the explicit QoS
+ /// configuration.
+ /// </summary>
+ public void Send(Apache.NMS.IMessage message,
+ MsgDeliveryMode deliveryMode, MsgPriority priority,
+ TimeSpan timeToLive)
+ {
+ Apache.NMS.XMS.Message msg = GetXMSMessage(message);
+
+ try
+ {
+ this.xmsMessageProducer.Send(
+ msg.xmsMessage,
+ XMSConvert.ToJMSDeliveryMode(deliveryMode),
+ (int)priority,
+ (long)timeToLive.TotalMilliseconds);
+ }
+ catch(Exception ex)
+ {
+ ExceptionUtil.WrapAndThrowNMSException(ex);
+ }
+ }
+
+ /// <summary>
+ /// Sends the message to the given destination.
+ /// </summary>
+ public void Send(Apache.NMS.IDestination destination,
+ Apache.NMS.IMessage message)
+ {
+ Apache.NMS.XMS.Destination dest =
+ (Apache.NMS.XMS.Destination)destination;
+
+ Apache.NMS.XMS.Message msg = GetXMSMessage(message);
+ long timeToLive = (long)message.NMSTimeToLive.TotalMilliseconds;
+
+ if(0 == timeToLive)
+ {
+ timeToLive = this.xmsMessageProducer.TimeToLive;
+ }
+
+ try
+ {
+ this.xmsMessageProducer.Send(
+ dest.xmsDestination,
+ msg.xmsMessage,
+ this.xmsMessageProducer.DeliveryMode,
+ this.xmsMessageProducer.Priority,
+ timeToLive);
+ }
+ catch(Exception ex)
+ {
+ ExceptionUtil.WrapAndThrowNMSException(ex);
+ }
+ }
+
+ /// <summary>
+ /// Sends the message to the given destination with the explicit QoS
+ /// configuration.
+ /// </summary>
+ public void Send(Apache.NMS.IDestination destination,
+ Apache.NMS.IMessage message, MsgDeliveryMode deliveryMode,
+ MsgPriority priority, TimeSpan timeToLive)
+ {
+ Apache.NMS.XMS.Destination dest =
+ (Apache.NMS.XMS.Destination)destination;
+
+ Apache.NMS.XMS.Message msg = GetXMSMessage(message);
+
+ try
+ {
+ this.xmsMessageProducer.Send(
+ dest.xmsDestination,
+ msg.xmsMessage,
+ XMSConvert.ToJMSDeliveryMode(deliveryMode),
+ (int)priority,
+ (long)timeToLive.TotalMilliseconds);
+ }
+ catch(Exception ex)
+ {
+ ExceptionUtil.WrapAndThrowNMSException(ex);
+ }
+ }
+
+ private ProducerTransformerDelegate producerTransformer;
+ /// <summary>
+ /// A delegate that is called each time a Message is sent from this
+ /// Producer which allows the application to perform any needed
+ /// transformations on the Message before it is sent.
+ /// </summary>
+ public ProducerTransformerDelegate ProducerTransformer
+ {
+ get { return this.producerTransformer; }
+ set { this.producerTransformer = value; }
+ }
+
+ public MsgDeliveryMode DeliveryMode
+ {
+ get
+ {
+ return XMSConvert.ToNMSMsgDeliveryMode(
+ this.xmsMessageProducer.DeliveryMode);
+ }
+ set
+ {
+ try
+ {
+ this.xmsMessageProducer.DeliveryMode =
+ XMSConvert.ToJMSDeliveryMode(value);
+ }
+ catch(Exception ex)
+ {
+ ExceptionUtil.WrapAndThrowNMSException(ex);
+ }
+ }
+ }
+
+ public TimeSpan TimeToLive
+ {
+ get
+ {
+ return TimeSpan.FromMilliseconds(
+ this.xmsMessageProducer.TimeToLive);
+ }
+ set
+ {
+ try
+ {
+ this.xmsMessageProducer.TimeToLive =
+ (long)value.TotalMilliseconds;
+ }
+ catch(Exception ex)
+ {
+ ExceptionUtil.WrapAndThrowNMSException(ex);
+ }
+ }
+ }
+
+ /// <summary>
+ /// The default timeout for network requests.
+ /// </summary>
+ public TimeSpan RequestTimeout
+ {
+ get { return requestTimeout; }
+ set { this.requestTimeout = value; }
+ }
+
+ public MsgPriority Priority
+ {
+ get { return (MsgPriority) this.xmsMessageProducer.Priority; }
+ set
+ {
+ try
+ {
+ this.xmsMessageProducer.Priority = (int) value;
+ }
+ catch(Exception ex)
+ {
+ ExceptionUtil.WrapAndThrowNMSException(ex);
+ }
+ }
+ }
+
+ public bool DisableMessageID
+ {
+ get { return this.xmsMessageProducer.DisableMessageID; }
+ set
+ {
+ try
+ {
+ this.xmsMessageProducer.DisableMessageID = value;
+ }
+ catch(Exception ex)
+ {
+ ExceptionUtil.WrapAndThrowNMSException(ex);
+ }
+ }
+ }
+
+ public bool DisableMessageTimestamp
+ {
+ get { return this.xmsMessageProducer.DisableMessageTimestamp; }
+ set
+ {
+ try
+ {
+ this.xmsMessageProducer.DisableMessageTimestamp = value;
+ }
+ catch(Exception ex)
+ {
+ ExceptionUtil.WrapAndThrowNMSException(ex);
+ }
+ }
+ }
+
+ /// <summary>
+ /// Creates a new message with an empty body
+ /// </summary>
+ public Apache.NMS.IMessage CreateMessage()
+ {
+ return this.nmsSession.CreateMessage();
+ }
+
+ /// <summary>
+ /// Creates a new text message with an empty body.
+ /// </summary>
+ public Apache.NMS.ITextMessage CreateTextMessage()
+ {
+ return this.nmsSession.CreateTextMessage();
+ }
+
+ /// <summary>
+ /// Creates a new text message with the given body.
+ /// </summary>
+ public Apache.NMS.ITextMessage CreateTextMessage(string text)
+ {
+ return this.nmsSession.CreateTextMessage(text);
+ }
+
+ /// <summary>
+ /// Creates a new Map message which contains primitive key and value
+ /// pairs.
+ /// </summary>
+ public Apache.NMS.IMapMessage CreateMapMessage()
+ {
+ return this.nmsSession.CreateMapMessage();
+ }
+
+ /// <summary>
+ /// Creates a new object message containing the given .NET object as
+ /// the body.
+ /// </summary>
+ public Apache.NMS.IObjectMessage CreateObjectMessage(object body)
+ {
+ return this.nmsSession.CreateObjectMessage(body);
+ }
+
+ /// <summary>
+ /// Creates a new binary message.
+ /// </summary>
+ public Apache.NMS.IBytesMessage CreateBytesMessage()
+ {
+ return this.nmsSession.CreateBytesMessage();
+ }
+
+ /// <summary>
+ /// Creates a new binary message with the given body.
+ /// </summary>
+ public Apache.NMS.IBytesMessage CreateBytesMessage(byte[] body)
+ {
+ return this.nmsSession.CreateBytesMessage(body);
+ }
+
+ /// <summary>
+ /// Creates a new stream message.
+ /// </summary>
+ public Apache.NMS.IStreamMessage CreateStreamMessage()
+ {
+ return this.nmsSession.CreateStreamMessage();
+ }
+
+ #endregion
+
+ #region IDisposable Members
+
+ public void Close()
+ {
+ lock(this)
+ {
+ if(closed)
+ {
+ return;
+ }
+
+ try
+ {
+ this.xmsMessageProducer.Close();
+ }
+ catch(Exception ex)
+ {
+ ExceptionUtil.WrapAndThrowNMSException(ex);
+ }
+ finally
+ {
+ closed = true;
+ }
+ }
+ }
+ ///<summary>
+ ///Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.
+ ///</summary>
+ ///<filterpriority>2</filterpriority>
+ public void Dispose()
+ {
+ Dispose(true);
+ GC.SuppressFinalize(this);
+ }
+
+ protected void Dispose(bool disposing)
+ {
+ if(disposed)
+ {
+ return;
+ }
+
+ if(disposing)
+ {
+ // Dispose managed code here.
+ }
+
+ try
+ {
+ Close();
+ }
+ catch
+ {
+ // Ignore errors.
+ }
+
+ disposed = true;
+ }
+
+ #endregion
+ }
+}
diff --git a/src/main/csharp/MessageProperties.cs b/src/main/csharp/MessageProperties.cs
new file mode 100644
index 0000000..3edd086
--- /dev/null
+++ b/src/main/csharp/MessageProperties.cs
@@ -0,0 +1,485 @@
+/*
+ * 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.
+ */
+using System;
+using System.Collections;
+using Apache.NMS;
+using Apache.NMS.Util;
+using Apache.NMS.XMS.Util;
+
+namespace Apache.NMS.XMS
+{
+ public class MessageProperties : Apache.NMS.IPrimitiveMap
+ {
+ public IBM.XMS.IMessage xmsMessage;
+
+ public MessageProperties(IBM.XMS.IMessage message)
+ {
+ this.xmsMessage = message;
+ }
+
+ #region IPrimitiveMap Members
+
+ public void Clear()
+ {
+ try
+ {
+ this.xmsMessage.ClearProperties();
+ }
+ catch(Exception ex)
+ {
+ ExceptionUtil.WrapAndThrowNMSException(ex);
+ }
+ }
+
+ public bool Contains(object key)
+ {
+ return this.xmsMessage.PropertyExists(key.ToString());
+ }
+
+ public void Remove(object key)
+ {
+ try
+ {
+ // Best guess at equivalent implementation.
+ this.xmsMessage.SetObjectProperty(key.ToString(), null);
+ }
+ catch(Exception ex)
+ {
+ ExceptionUtil.WrapAndThrowNMSException(ex);
+ }
+ }
+
+ public int Count
+ {
+ get
+ {
+ int count = 0;
+ try
+ {
+ IEnumerator propertyNamesEnumerator =
+ this.xmsMessage.PropertyNames;
+
+ if(null != propertyNamesEnumerator)
+ {
+ while(propertyNamesEnumerator.MoveNext())
+ {
+ count++;
+ }
+ }
+ }
+ catch(Exception ex)
+ {
+ ExceptionUtil.WrapAndThrowNMSException(ex);
+ }
+
+ return count;
+ }
+ }
+
+ public ICollection Keys
+ {
+ get
+ {
+ ArrayList keys = new ArrayList();
+
+ try
+ {
+ foreach(string propertyName in XMSConvert.ToEnumerable(this.xmsMessage.PropertyNames))
+ {
+ keys.Add(propertyName);
+ }
+ }
+ catch(Exception ex)
+ {
+ ExceptionUtil.WrapAndThrowNMSException(ex);
+ }
+
+ return keys;
+ }
+ }
+
+ public ICollection Values
+ {
+ get
+ {
+ ArrayList values = new ArrayList();
+
+ try
+ {
+ foreach(string propertyName in XMSConvert.ToEnumerable(this.xmsMessage.PropertyNames))
+ {
+ values.Add(this.xmsMessage.GetObjectProperty(propertyName));
+ }
+ }
+ catch(Exception ex)
+ {
+ ExceptionUtil.WrapAndThrowNMSException(ex);
+ }
+
+ return values;
+ }
+ }
+
+ public object this[string key]
+ {
+ get
+ {
+ try
+ {
+ return this.xmsMessage.GetObjectProperty(key);
+ }
+ catch(Exception ex)
+ {
+ ExceptionUtil.WrapAndThrowNMSException(ex);
+ return null;
+ }
+ }
+ set
+ {
+ try
+ {
+ this.xmsMessage.SetObjectProperty(key, value);
+ }
+ catch(Exception ex)
+ {
+ ExceptionUtil.WrapAndThrowNMSException(ex);
+ }
+ }
+ }
+
+ public string GetString(string key)
+ {
+ try
+ {
+ return this.xmsMessage.GetStringProperty(key);
+ }
+ catch(Exception ex)
+ {
+ ExceptionUtil.WrapAndThrowNMSException(ex);
+ return null;
+ }
+ }
+
+ public void SetString(string key, string value)
+ {
+ try
+ {
+ this.xmsMessage.SetStringProperty(key, value);
+ }
+ catch(Exception ex)
+ {
+ ExceptionUtil.WrapAndThrowNMSException(ex);
+ }
+ }
+
+ public bool GetBool(string key)
+ {
+ try
+ {
+ return this.xmsMessage.GetBooleanProperty(key);
+ }
+ catch(Exception ex)
+ {
+ ExceptionUtil.WrapAndThrowNMSException(ex);
+ return false;
+ }
+ }
+
+ public void SetBool(string key, bool value)
+ {
+ try
+ {
+ this.xmsMessage.SetBooleanProperty(key, value);
+ }
+ catch(Exception ex)
+ {
+ ExceptionUtil.WrapAndThrowNMSException(ex);
+ }
+ }
+
+ public byte GetByte(string key)
+ {
+ try
+ {
+ return this.xmsMessage.GetByteProperty(key);
+ }
+ catch(Exception ex)
+ {
+ ExceptionUtil.WrapAndThrowNMSException(ex);
+ return 0;
+ }
+ }
+
+ public void SetByte(string key, byte value)
+ {
+ try
+ {
+ this.xmsMessage.SetByteProperty(key, value);
+ }
+ catch(Exception ex)
+ {
+ ExceptionUtil.WrapAndThrowNMSException(ex);
+ }
+ }
+
+ public char GetChar(string key)
+ {
+ try
+ {
+ return this.xmsMessage.GetCharProperty(key);
+ }
+ catch(Exception ex)
+ {
+ ExceptionUtil.WrapAndThrowNMSException(ex);
+ return (char) 0;
+ }
+ }
+
+ public void SetChar(string key, char value)
+ {
+ try
+ {
+ this.xmsMessage.SetCharProperty(key, value);
+ }
+ catch(Exception ex)
+ {
+ ExceptionUtil.WrapAndThrowNMSException(ex);
+ }
+ }
+
+ public short GetShort(string key)
+ {
+ try
+ {
+ return this.xmsMessage.GetShortProperty(key);
+ }
+ catch(Exception ex)
+ {
+ ExceptionUtil.WrapAndThrowNMSException(ex);
+ return 0;
+ }
+ }
+
+ public void SetShort(string key, short value)
+ {
+ try
+ {
+ this.xmsMessage.SetShortProperty(key, value);
+ }
+ catch(Exception ex)
+ {
+ ExceptionUtil.WrapAndThrowNMSException(ex);
+ }
+ }
+
+ public int GetInt(string key)
+ {
+ try
+ {
+ return this.xmsMessage.GetIntProperty(key);
+ }
+ catch(Exception ex)
+ {
+ ExceptionUtil.WrapAndThrowNMSException(ex);
+ return 0;
+ }
+ }
+
+ public void SetInt(string key, int value)
+ {
+ try
+ {
+ this.xmsMessage.SetIntProperty(key, value);
+ }
+ catch(Exception ex)
+ {
+ ExceptionUtil.WrapAndThrowNMSException(ex);
+ }
+ }
+
+ public long GetLong(string key)
+ {
+ try
+ {
+ return this.xmsMessage.GetLongProperty(key);
+ }
+ catch(Exception ex)
+ {
+ ExceptionUtil.WrapAndThrowNMSException(ex);
+ return 0;
+ }
+ }
+
+ public void SetLong(string key, long value)
+ {
+ try
+ {
+ this.xmsMessage.SetLongProperty(key, value);
+ }
+ catch(Exception ex)
+ {
+ ExceptionUtil.WrapAndThrowNMSException(ex);
+ }
+ }
+
+ public float GetFloat(string key)
+ {
+ try
+ {
+ return this.xmsMessage.GetFloatProperty(key);
+ }
+ catch(Exception ex)
+ {
+ ExceptionUtil.WrapAndThrowNMSException(ex);
+ return 0;
+ }
+ }
+
+ public void SetFloat(string key, float value)
+ {
+ try
+ {
+ this.xmsMessage.SetFloatProperty(key, value);
+ }
+ catch(Exception ex)
+ {
+ ExceptionUtil.WrapAndThrowNMSException(ex);
+ }
+ }
+
+ public double GetDouble(string key)
+ {
+ try
+ {
+ return this.xmsMessage.GetDoubleProperty(key);
+ }
+ catch(Exception ex)
+ {
+ ExceptionUtil.WrapAndThrowNMSException(ex);
+ return 0;
+ }
+ }
+
+ public void SetDouble(string key, double value)
+ {
+ try
+ {
+ this.xmsMessage.SetDoubleProperty(key, value);
+ }
+ catch(Exception ex)
+ {
+ ExceptionUtil.WrapAndThrowNMSException(ex);
+ }
+ }
+
+ public IList GetList(string key)
+ {
+ try
+ {
+ return (IList) this.xmsMessage.GetObjectProperty(key);
+ }
+ catch(Exception ex)
+ {
+ ExceptionUtil.WrapAndThrowNMSException(ex);
+ return null;
+ }
+ }
+
+ public void SetList(string key, IList list)
+ {
+ try
+ {
+ this.xmsMessage.SetObjectProperty(key, list);
+ }
+ catch(Exception ex)
+ {
+ ExceptionUtil.WrapAndThrowNMSException(ex);
+ }
+ }
+
+ public void SetBytes(string key, byte[] value)
+ {
+ try
+ {
+ this.xmsMessage.SetBytesProperty(key, value);
+ }
+ catch(Exception ex)
+ {
+ ExceptionUtil.WrapAndThrowNMSException(ex);
+ }
+ }
+
+ public void SetBytes(string key, byte[] value, int offset, int length)
+ {
+ try
+ {
+ byte[] byteSection = new byte[length];
+
+ for(int srcIndex = offset, destIndex = 0; srcIndex < (offset + length); srcIndex++, destIndex++)
+ {
+ byteSection[destIndex] = value[srcIndex];
+ }
+
+ this.xmsMessage.SetBytesProperty(key, byteSection);
+ }
+ catch(Exception ex)
+ {
+ ExceptionUtil.WrapAndThrowNMSException(ex);
+ }
+ }
+
+ public byte[] GetBytes(string key)
+ {
+ try
+ {
+ return (byte[]) this.xmsMessage.GetBytesProperty(key);
+ }
+ catch(Exception ex)
+ {
+ ExceptionUtil.WrapAndThrowNMSException(ex);
+ return null;
+ }
+ }
+
+ public IDictionary GetDictionary(string key)
+ {
+ try
+ {
+ return (IDictionary) this.xmsMessage.GetObjectProperty(key);
+ }
+ catch(Exception ex)
+ {
+ ExceptionUtil.WrapAndThrowNMSException(ex);
+ return null;
+ }
+ }
+
+ public void SetDictionary(string key, IDictionary dictionary)
+ {
+ try
+ {
+ this.xmsMessage.SetObjectProperty(key, dictionary);
+ }
+ catch(Exception ex)
+ {
+ ExceptionUtil.WrapAndThrowNMSException(ex);
+ }
+ }
+
+ #endregion
+ }
+}
diff --git a/src/main/csharp/ObjectMessage.cs b/src/main/csharp/ObjectMessage.cs
new file mode 100644
index 0000000..b777674
--- /dev/null
+++ b/src/main/csharp/ObjectMessage.cs
@@ -0,0 +1,65 @@
+/*
+ * 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.
+ */
+using System;
+using Apache.NMS;
+using Apache.NMS.Util;
+using Apache.NMS.XMS.Util;
+using IBM.XMS;
+
+namespace Apache.NMS.XMS
+{
+ /// <summary>
+ /// Represents an object message which contains a serializable .NET object.
+ /// </summary>
+ class ObjectMessage : Apache.NMS.XMS.Message, Apache.NMS.IObjectMessage
+ {
+ #region Constructors and access to internal map message
+
+ /// <summary>
+ /// Internal IBM XMS object message.
+ /// </summary>
+ public IBM.XMS.IObjectMessage xmsObjectMessage
+ {
+ get { return (IBM.XMS.IObjectMessage)this.xmsMessage; }
+ set { this.xmsMessage = value; }
+ }
+
+ /// <summary>
+ /// Constructs a <c>MapMessage</c> object.
+ /// </summary>
+ /// <param name="message">XMS map message.</param>
+ public ObjectMessage(IBM.XMS.IObjectMessage message)
+ : base(message)
+ {
+ }
+
+ #endregion
+
+ #region IObjectMessage Members
+
+ /// <summary>
+ /// Object message body.
+ /// </summary>
+ public object Body
+ {
+ get { return this.xmsObjectMessage.Object; }
+ set { this.xmsObjectMessage.Object = value; }
+ }
+
+ #endregion
+ }
+}
diff --git a/src/main/csharp/Queue.cs b/src/main/csharp/Queue.cs
new file mode 100644
index 0000000..579a65a
--- /dev/null
+++ b/src/main/csharp/Queue.cs
@@ -0,0 +1,75 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+using System;
+using Apache.NMS;
+using Apache.NMS.Util;
+using Apache.NMS.XMS.Util;
+using IBM.XMS;
+
+namespace Apache.NMS.XMS
+{
+ public class Queue : Apache.NMS.XMS.Destination, Apache.NMS.IQueue
+ {
+ #region Constructors and destructors
+
+ /// <summary>
+ /// Constructs a <c>Queue</c> object.
+ /// </summary>
+ /// <param name="queue">IBM XMS queue</param>
+ public Queue(IBM.XMS.IDestination queue)
+ : base(queue)
+ {
+ }
+
+ /// <summary>
+ /// Constructs a <c>Queue</c> object.
+ /// </summary>
+ /// <param name="queue">IBM XMS queue</param>
+ /// <param name="isTemporary">Whether the queue is temporary</param>
+ public Queue(IBM.XMS.IDestination queue, bool isTemporary)
+ : base(queue, isTemporary)
+ {
+ }
+
+ #endregion
+
+ #region IQueue Members
+
+ /// <summary>
+ /// Queue name.
+ /// </summary>
+ public string QueueName
+ {
+ get { return this.xmsDestination.Name; }
+ }
+
+ #endregion
+
+ #region ToString
+
+ /// <summary>
+ /// Returns a string representation of this instance.
+ /// </summary>
+ /// <returns>String representation of this instance</returns>
+ public override System.String ToString()
+ {
+ return "queue://" + QueueName;
+ }
+
+ #endregion
+ }
+}
\ No newline at end of file
diff --git a/src/main/csharp/QueueBrowser.cs b/src/main/csharp/QueueBrowser.cs
new file mode 100644
index 0000000..2ef3690
--- /dev/null
+++ b/src/main/csharp/QueueBrowser.cs
@@ -0,0 +1,145 @@
+/*
+ * 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.
+ */
+using System;
+using System.Collections;
+using Apache.NMS;
+using Apache.NMS.Util;
+using Apache.NMS.XMS.Util;
+
+namespace Apache.NMS.XMS
+{
+ public class QueueBrowser : Apache.NMS.IQueueBrowser
+ {
+ public IBM.XMS.IQueueBrowser xmsQueueBrowser;
+ private bool closed = false;
+ private bool disposed = false;
+
+ public QueueBrowser(IBM.XMS.IQueueBrowser queueBrowser)
+ {
+ this.xmsQueueBrowser = queueBrowser;
+ }
+
+ ~QueueBrowser()
+ {
+ Dispose(false);
+ }
+
+ #region IDisposable Members
+
+ ///<summary>
+ /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.
+ ///</summary>
+ public void Dispose()
+ {
+ Dispose(true);
+ GC.SuppressFinalize(this);
+ }
+
+ protected void Dispose(bool disposing)
+ {
+ if(disposed)
+ {
+ return;
+ }
+
+ if(disposing)
+ {
+ // Dispose managed code here.
+ }
+
+ try
+ {
+ Close();
+ }
+ catch
+ {
+ // Ignore errors.
+ }
+
+ disposed = true;
+ }
+
+ #endregion
+
+ public void Close()
+ {
+ lock(this)
+ {
+ if(closed)
+ {
+ return;
+ }
+
+ try
+ {
+ this.xmsQueueBrowser.Close();
+ }
+ catch(Exception ex)
+ {
+ ExceptionUtil.WrapAndThrowNMSException(ex);
+ }
+ finally
+ {
+ closed = true;
+ }
+ }
+ }
+
+ public string MessageSelector
+ {
+ get { return this.xmsQueueBrowser.MessageSelector; }
+ }
+
+ public IQueue Queue
+ {
+ get { return XMSConvert.ToNMSQueue(this.xmsQueueBrowser.Queue); }
+ }
+
+ internal class Enumerator : IEnumerator
+ {
+ private IEnumerator innerEnumerator;
+
+ public Enumerator(IEnumerator innerEnumerator)
+ {
+ this.innerEnumerator = innerEnumerator;
+ }
+
+ public object Current
+ {
+ get
+ {
+ return XMSConvert.ToNMSMessage((IBM.XMS.IMessage)this.innerEnumerator.Current);
+ }
+ }
+
+ public bool MoveNext()
+ {
+ return this.innerEnumerator.MoveNext();
+ }
+
+ public void Reset()
+ {
+ this.innerEnumerator.Reset();
+ }
+ }
+
+ public IEnumerator GetEnumerator()
+ {
+ return new Enumerator(this.xmsQueueBrowser.GetEnumerator());
+ }
+ }
+}
diff --git a/src/main/csharp/Session.cs b/src/main/csharp/Session.cs
new file mode 100644
index 0000000..8e01827
--- /dev/null
+++ b/src/main/csharp/Session.cs
@@ -0,0 +1,551 @@
+/*
+ * 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.
+ */
+using System;
+using Apache.NMS;
+using Apache.NMS.Util;
+using Apache.NMS.XMS.Util;
+using IBM.XMS;
+
+namespace Apache.NMS.XMS
+{
+ /// <summary>
+ /// Represents a NMS session to IBM XMS.
+ /// </summary>
+ public class Session : Apache.NMS.ISession
+ {
+ public readonly IBM.XMS.ISession xmsSession;
+ private bool closed = false;
+ private bool disposed = false;
+
+ public Session(IBM.XMS.ISession session)
+ {
+ this.xmsSession = session;
+ }
+
+ ~Session()
+ {
+ Dispose(false);
+ }
+
+ #region ISession Members
+
+ public Apache.NMS.IMessageProducer CreateProducer()
+ {
+ return CreateProducer(null);
+ }
+
+ public Apache.NMS.IMessageProducer CreateProducer(
+ Apache.NMS.IDestination destination)
+ {
+ Apache.NMS.XMS.Destination destinationObj =
+ (Apache.NMS.XMS.Destination)destination;
+
+ try
+ {
+ Apache.NMS.IMessageProducer producer =
+ XMSConvert.ToNMSMessageProducer(this,
+ this.xmsSession.CreateProducer(
+ destinationObj.xmsDestination));
+ ConfigureProducer(producer);
+ return producer;
+ }
+ catch(Exception ex)
+ {
+ ExceptionUtil.WrapAndThrowNMSException(ex);
+ return null;
+ }
+ }
+
+ public Apache.NMS.IMessageConsumer CreateConsumer(
+ Apache.NMS.IDestination destination)
+ {
+ Apache.NMS.XMS.Destination destinationObj =
+ (Apache.NMS.XMS.Destination)destination;
+
+ try
+ {
+ Apache.NMS.IMessageConsumer consumer =
+ XMSConvert.ToNMSMessageConsumer(this,
+ this.xmsSession.CreateConsumer(
+ destinationObj.xmsDestination));
+ ConfigureConsumer(consumer);
+ return consumer;
+ }
+ catch(Exception ex)
+ {
+ ExceptionUtil.WrapAndThrowNMSException(ex);
+ return null;
+ }
+ }
+
+ public Apache.NMS.IMessageConsumer CreateConsumer(
+ Apache.NMS.IDestination destination, string selector)
+ {
+ Apache.NMS.XMS.Destination destinationObj =
+ (Apache.NMS.XMS.Destination)destination;
+
+ try
+ {
+ Apache.NMS.IMessageConsumer consumer =
+ XMSConvert.ToNMSMessageConsumer(this,
+ this.xmsSession.CreateConsumer(
+ destinationObj.xmsDestination, selector));
+ ConfigureConsumer(consumer);
+ return consumer;
+ }
+ catch(Exception ex)
+ {
+ ExceptionUtil.WrapAndThrowNMSException(ex);
+ return null;
+ }
+ }
+
+ public Apache.NMS.IMessageConsumer CreateConsumer(
+ Apache.NMS.IDestination destination, string selector, bool noLocal)
+ {
+ Apache.NMS.XMS.Destination destinationObj =
+ (Apache.NMS.XMS.Destination)destination;
+
+ try
+ {
+ Apache.NMS.IMessageConsumer consumer =
+ XMSConvert.ToNMSMessageConsumer(this,
+ this.xmsSession.CreateConsumer(
+ destinationObj.xmsDestination, selector, noLocal));
+ ConfigureConsumer(consumer);
+ return consumer;
+ }
+ catch(Exception ex)
+ {
+ ExceptionUtil.WrapAndThrowNMSException(ex);
+ return null;
+ }
+ }
+
+ public Apache.NMS.IMessageConsumer CreateDurableConsumer(
+ Apache.NMS.ITopic destination, string name, string selector,
+ bool noLocal)
+ {
+ Apache.NMS.XMS.Topic topicObj = (Apache.NMS.XMS.Topic)destination;
+
+ try
+ {
+ Apache.NMS.IMessageConsumer consumer =
+ XMSConvert.ToNMSMessageConsumer(this,
+ this.xmsSession.CreateDurableSubscriber(
+ topicObj.xmsDestination, name, selector, noLocal));
+ ConfigureConsumer(consumer);
+ return consumer;
+ }
+ catch(Exception ex)
+ {
+ ExceptionUtil.WrapAndThrowNMSException(ex);
+ return null;
+ }
+ }
+
+ private void ConfigureProducer(Apache.NMS.IMessageProducer producer)
+ {
+ producer.ProducerTransformer = this.ProducerTransformer;
+ }
+
+ private void ConfigureConsumer(Apache.NMS.IMessageConsumer consumer)
+ {
+ consumer.ConsumerTransformer = this.ConsumerTransformer;
+ }
+
+ public void DeleteDurableConsumer(string name)
+ {
+ try
+ {
+ this.xmsSession.Unsubscribe(name);
+ }
+ catch(Exception ex)
+ {
+ ExceptionUtil.WrapAndThrowNMSException(ex);
+ }
+ }
+
+ public IQueueBrowser CreateBrowser(IQueue queue)
+ {
+ Apache.NMS.XMS.Queue queueObj = (Apache.NMS.XMS.Queue)queue;
+
+ try
+ {
+ return XMSConvert.ToNMSQueueBrowser(this.xmsSession.CreateBrowser(
+ queueObj.xmsDestination));
+ }
+ catch(Exception ex)
+ {
+ ExceptionUtil.WrapAndThrowNMSException(ex);
+ return null;
+ }
+ }
+
+ public IQueueBrowser CreateBrowser(IQueue queue, string selector)
+ {
+ Apache.NMS.XMS.Queue queueObj = (Apache.NMS.XMS.Queue) queue;
+
+ try
+ {
+ return XMSConvert.ToNMSQueueBrowser(this.xmsSession.CreateBrowser(
+ queueObj.xmsDestination, selector));
+ }
+ catch(Exception ex)
+ {
+ ExceptionUtil.WrapAndThrowNMSException(ex);
+ return null;
+ }
+ }
+
+ public Apache.NMS.IQueue GetQueue(string name)
+ {
+ try
+ {
+ return XMSConvert.ToNMSQueue(this.xmsSession.CreateQueue(name));
+ }
+ catch(Exception ex)
+ {
+ ExceptionUtil.WrapAndThrowNMSException(ex);
+ return null;
+ }
+ }
+
+ public Apache.NMS.ITopic GetTopic(string name)
+ {
+ try
+ {
+ return XMSConvert.ToNMSTopic(this.xmsSession.CreateTopic(name));
+ }
+ catch(Exception ex)
+ {
+ ExceptionUtil.WrapAndThrowNMSException(ex);
+ return null;
+ }
+ }
+
+ public Apache.NMS.ITemporaryQueue CreateTemporaryQueue()
+ {
+ try
+ {
+ return XMSConvert.ToNMSTemporaryQueue(
+ this.xmsSession.CreateTemporaryQueue());
+ }
+ catch(Exception ex)
+ {
+ ExceptionUtil.WrapAndThrowNMSException(ex);
+ return null;
+ }
+ }
+
+ public Apache.NMS.ITemporaryTopic CreateTemporaryTopic()
+ {
+ try
+ {
+ return XMSConvert.ToNMSTemporaryTopic(
+ this.xmsSession.CreateTemporaryTopic());
+ }
+ catch(Exception ex)
+ {
+ ExceptionUtil.WrapAndThrowNMSException(ex);
+ return null;
+ }
+ }
+
+ /// <summary>
+ /// Delete a destination (Queue, Topic, Temp Queue, Temp Topic).
+ /// </summary>
+ public void DeleteDestination(IDestination destination)
+ {
+ // The IBM.XMS API does not support destination deletion
+ throw new NotSupportedException();
+ }
+
+ public Apache.NMS.IMessage CreateMessage()
+ {
+ try
+ {
+ return XMSConvert.ToNMSMessage(
+ this.xmsSession.CreateMessage());
+ }
+ catch(Exception ex)
+ {
+ ExceptionUtil.WrapAndThrowNMSException(ex);
+ return null;
+ }
+ }
+
+ public Apache.NMS.ITextMessage CreateTextMessage()
+ {
+ try
+ {
+ return XMSConvert.ToNMSTextMessage(
+ this.xmsSession.CreateTextMessage());
+ }
+ catch(Exception ex)
+ {
+ ExceptionUtil.WrapAndThrowNMSException(ex);
+ return null;
+ }
+ }
+
+ public Apache.NMS.ITextMessage CreateTextMessage(string text)
+ {
+ try
+ {
+ return XMSConvert.ToNMSTextMessage(
+ this.xmsSession.CreateTextMessage(text));
+ }
+ catch(Exception ex)
+ {
+ ExceptionUtil.WrapAndThrowNMSException(ex);
+ return null;
+ }
+ }
+
+ public Apache.NMS.IMapMessage CreateMapMessage()
+ {
+ try
+ {
+ return XMSConvert.ToNMSMapMessage(
+ this.xmsSession.CreateMapMessage());
+ }
+ catch(Exception ex)
+ {
+ ExceptionUtil.WrapAndThrowNMSException(ex);
+ return null;
+ }
+ }
+
+ public Apache.NMS.IBytesMessage CreateBytesMessage()
+ {
+ try
+ {
+ return XMSConvert.ToNMSBytesMessage(
+ this.xmsSession.CreateBytesMessage());
+ }
+ catch(Exception ex)
+ {
+ ExceptionUtil.WrapAndThrowNMSException(ex);
+ return null;
+ }
+ }
+
+ public Apache.NMS.IBytesMessage CreateBytesMessage(byte[] body)
+ {
+ try
+ {
+ Apache.NMS.IBytesMessage bytesMessage = CreateBytesMessage();
+
+ if(null != bytesMessage)
+ {
+ bytesMessage.Content = body;
+ }
+
+ return bytesMessage;
+ }
+ catch(Exception ex)
+ {
+ ExceptionUtil.WrapAndThrowNMSException(ex);
+ return null;
+ }
+ }
+
+ public Apache.NMS.IStreamMessage CreateStreamMessage()
+ {
+ try
+ {
+ return XMSConvert.ToNMSStreamMessage(
+ this.xmsSession.CreateStreamMessage());
+ }
+ catch(Exception ex)
+ {
+ ExceptionUtil.WrapAndThrowNMSException(ex);
+ return null;
+ }
+ }
+
+ public Apache.NMS.IObjectMessage CreateObjectMessage(Object body)
+ {
+ try
+ {
+ IBM.XMS.IObjectMessage xmsObjectMessage =
+ this.xmsSession.CreateObjectMessage();
+ xmsObjectMessage.Object = body;
+ return XMSConvert.ToNMSObjectMessage(xmsObjectMessage);
+ }
+ catch(Exception ex)
+ {
+ ExceptionUtil.WrapAndThrowNMSException(ex);
+ return null;
+ }
+ }
+
+ public void Commit()
+ {
+ try
+ {
+ this.xmsSession.Commit();
+ }
+ catch(Exception ex)
+ {
+ ExceptionUtil.WrapAndThrowNMSException(ex);
+ }
+ }
+
+ public void Rollback()
+ {
+ try
+ {
+ this.xmsSession.Rollback();
+ }
+ catch(Exception ex)
+ {
+ ExceptionUtil.WrapAndThrowNMSException(ex);
+ }
+ }
+
+ public void Recover()
+ {
+ throw new NotSupportedException();
+ }
+
+ private ConsumerTransformerDelegate consumerTransformer;
+ /// <summary>
+ /// A Delegate that is called each time a Message is dispatched to
+ /// allow the client to do any necessary transformations on the
+ /// received message before it is delivered. The Session instance
+ /// sets the delegate on each Consumer it creates.
+ /// </summary>
+ public ConsumerTransformerDelegate ConsumerTransformer
+ {
+ get { return this.consumerTransformer; }
+ set { this.consumerTransformer = value; }
+ }
+
+ private ProducerTransformerDelegate producerTransformer;
+ /// <summary>
+ /// A delegate that is called each time a Message is sent from this
+ /// Producer which allows the application to perform any needed
+ /// transformations on the Message before it is sent. The Session
+ /// instance sets the delegate on each Producer it creates.
+ /// </summary>
+ public ProducerTransformerDelegate ProducerTransformer
+ {
+ get { return this.producerTransformer; }
+ set { this.producerTransformer = value; }
+ }
+
+ #region Transaction State Events
+
+ #pragma warning disable 0067
+ public event SessionTxEventDelegate TransactionStartedListener;
+ public event SessionTxEventDelegate TransactionCommittedListener;
+ public event SessionTxEventDelegate TransactionRolledBackListener;
+ #pragma warning restore 0067
+
+ #endregion
+
+ // Properties
+
+ /// <summary>
+ /// The default timeout for network requests.
+ /// </summary>
+ private TimeSpan requestTimeout =
+ Apache.NMS.NMSConstants.defaultRequestTimeout;
+ public TimeSpan RequestTimeout
+ {
+ get { return this.requestTimeout; }
+ set { this.requestTimeout = value; }
+ }
+
+ public bool Transacted
+ {
+ get { return this.xmsSession.Transacted; }
+ }
+
+ public Apache.NMS.AcknowledgementMode AcknowledgementMode
+ {
+ get { return XMSConvert.ToAcknowledgementMode(this.xmsSession.AcknowledgeMode); }
+ }
+
+ public void Close()
+ {
+ lock(this)
+ {
+ if(closed)
+ {
+ return;
+ }
+
+ try
+ {
+ this.xmsSession.Close();
+ }
+ catch(Exception ex)
+ {
+ ExceptionUtil.WrapAndThrowNMSException(ex);
+ }
+ finally
+ {
+ closed = true;
+ }
+ }
+ }
+
+ #endregion
+
+ #region IDisposable Members
+
+ ///<summary>
+ /// Performs application-defined tasks associated with freeing,
+ /// releasing, or resetting unmanaged resources.
+ ///</summary>
+ ///<filterpriority>2</filterpriority>
+ public void Dispose()
+ {
+ Dispose(true);
+ GC.SuppressFinalize(this);
+ }
+
+ protected void Dispose(bool disposing)
+ {
+ if(disposed)
+ {
+ return;
+ }
+
+ if(disposing)
+ {
+ // Dispose managed code here.
+ }
+
+ try
+ {
+ Close();
+ }
+ catch
+ {
+ // Ignore errors.
+ }
+
+ disposed = true;
+ }
+
+ #endregion
+ }
+}
diff --git a/src/main/csharp/StreamMessage.cs b/src/main/csharp/StreamMessage.cs
new file mode 100644
index 0000000..b25579b
--- /dev/null
+++ b/src/main/csharp/StreamMessage.cs
@@ -0,0 +1,480 @@
+/*
+ * 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.
+ */
+using System;
+using Apache.NMS;
+using Apache.NMS.Util;
+using Apache.NMS.XMS.Util;
+using IBM.XMS;
+
+namespace Apache.NMS.XMS
+{
+ /// <summary>
+ /// A StreamMessage object is used to send a stream of primitive types in the
+ /// .NET programming language. It is filled and read sequentially. It inherits
+ /// from the Message interface and adds a stream message body.
+ /// </summary>
+ class StreamMessage : Apache.NMS.XMS.Message, Apache.NMS.IStreamMessage
+ {
+ #region Constructors and access to internal stream message
+
+ /// <summary>
+ /// Internal IBM XMS stream message.
+ /// </summary>
+ public IBM.XMS.IStreamMessage xmsStreamMessage
+ {
+ get { return (IBM.XMS.IStreamMessage)this.xmsMessage; }
+ set { this.xmsMessage = value; }
+ }
+
+ /// <summary>
+ /// Constructs a <c>StreamMessage</c> object.
+ /// </summary>
+ /// <param name="message">XMS stream message.</param>
+ public StreamMessage(IBM.XMS.IStreamMessage message)
+ : base(message)
+ {
+ }
+
+ #endregion
+
+ #region IStreamMessage Members
+
+ #region Reset method
+
+ /// <summary>
+ /// Resets the contents of the stream message body.
+ /// </summary>
+ public void Reset()
+ {
+ try
+ {
+ this.xmsStreamMessage.Reset();
+ }
+ catch(Exception ex)
+ {
+ ExceptionUtil.WrapAndThrowNMSException(ex);
+ }
+ }
+
+ #endregion
+
+ #region Read methods
+
+ /// <summary>
+ /// Reads a boolean from the stream message.
+ /// </summary>
+ /// <returns>A <see cref="System.Boolean"/></returns>
+ public bool ReadBoolean()
+ {
+ try
+ {
+ return this.xmsStreamMessage.ReadBoolean();
+ }
+ catch(Exception ex)
+ {
+ ExceptionUtil.WrapAndThrowNMSException(ex);
+ return false;
+ }
+ }
+
+ /// <summary>
+ /// Reads a byte from the stream message.
+ /// </summary>
+ /// <returns>A <see cref="System.Byte"/></returns>
+ public byte ReadByte()
+ {
+ try
+ {
+ return this.xmsStreamMessage.ReadByte();
+ }
+ catch(Exception ex)
+ {
+ ExceptionUtil.WrapAndThrowNMSException(ex);
+ return 0;
+ }
+ }
+
+ /// <summary>
+ /// Reads a byte array from the stream message.
+ /// </summary>
+ /// <param name="value">A <see cref="System.Byte"/> array</param>
+ /// <returns>The total number of bytes read into the buffer, or -1 if
+ /// there is no more data because the end of the byte field has been
+ /// reached</returns>
+ public int ReadBytes(byte[] value)
+ {
+ try
+ {
+ return this.xmsStreamMessage.ReadBytes(value);
+ }
+ catch(Exception ex)
+ {
+ ExceptionUtil.WrapAndThrowNMSException(ex);
+ return 0;
+ }
+ }
+
+ /// <summary>
+ /// Reads a character from the stream message.
+ /// </summary>
+ /// <returns>A <see cref="System.Char"/></returns>
+ public char ReadChar()
+ {
+ try
+ {
+ return this.xmsStreamMessage.ReadChar();
+ }
+ catch(Exception ex)
+ {
+ ExceptionUtil.WrapAndThrowNMSException(ex);
+ return (char) 0;
+ }
+ }
+
+ /// <summary>
+ /// Reads a 16 bits (short) integer number from the stream message.
+ /// </summary>
+ /// <returns>A <see cref="System.Int16"/></returns>
+ public short ReadInt16()
+ {
+ try
+ {
+ return this.xmsStreamMessage.ReadShort();
+ }
+ catch(Exception ex)
+ {
+ ExceptionUtil.WrapAndThrowNMSException(ex);
+ return 0;
+ }
+ }
+
+ /// <summary>
+ /// Reads a 32 bits (int) integer number from the stream message.
+ /// </summary>
+ /// <returns>A <see cref="System.Int32"/></returns>
+ public int ReadInt32()
+ {
+ try
+ {
+ return this.xmsStreamMessage.ReadInt();
+ }
+ catch(Exception ex)
+ {
+ ExceptionUtil.WrapAndThrowNMSException(ex);
+ return 0;
+ }
+ }
+
+ /// <summary>
+ /// Reads a 64 bits (long) integer number from the stream message.
+ /// </summary>
+ /// <returns>A <see cref="System.Int64"/></returns>
+ public long ReadInt64()
+ {
+ try
+ {
+ return this.xmsStreamMessage.ReadLong();
+ }
+ catch(Exception ex)
+ {
+ ExceptionUtil.WrapAndThrowNMSException(ex);
+ return 0;
+ }
+ }
+
+ /// <summary>
+ /// Reads a single precision floating point number from the stream
+ /// message.
+ /// </summary>
+ /// <returns>A <see cref="System.Single"/></returns>
+ public float ReadSingle()
+ {
+ try
+ {
+ return this.xmsStreamMessage.ReadFloat();
+ }
+ catch(Exception ex)
+ {
+ ExceptionUtil.WrapAndThrowNMSException(ex);
+ return 0;
+ }
+ }
+
+ /// <summary>
+ /// Reads a double precision floating point number from the stream
+ /// message.
+ /// </summary>
+ /// <returns>A <see cref="System.Double"/></returns>
+ public double ReadDouble()
+ {
+ try
+ {
+ return this.xmsStreamMessage.ReadDouble();
+ }
+ catch(Exception ex)
+ {
+ ExceptionUtil.WrapAndThrowNMSException(ex);
+ return 0;
+ }
+ }
+
+ /// <summary>
+ /// Reads a character string from the stream message.
+ /// </summary>
+ /// <returns>A <see cref="System.String"/></returns>
+ public string ReadString()
+ {
+ try
+ {
+ return this.xmsStreamMessage.ReadString();
+ }
+ catch(Exception ex)
+ {
+ ExceptionUtil.WrapAndThrowNMSException(ex);
+ return null;
+ }
+ }
+
+ /// <summary>
+ /// Reads an object from the stream message.
+ /// </summary>
+ /// <returns>A <see cref="System.Object"/></returns>
+ public object ReadObject()
+ {
+ try
+ {
+ return this.xmsStreamMessage.ReadObject();
+ }
+ catch(Exception ex)
+ {
+ ExceptionUtil.WrapAndThrowNMSException(ex);
+ return 0;
+ }
+ }
+
+ #endregion
+
+ #region Write methods
+
+ /// <summary>
+ /// Writes a boolean to the stream message.
+ /// </summary>
+ /// <param name="value">A <see cref="System.Boolean"/></param>
+ public void WriteBoolean(bool value)
+ {
+ try
+ {
+ this.xmsStreamMessage.WriteBoolean(value);
+ }
+ catch(Exception ex)
+ {
+ ExceptionUtil.WrapAndThrowNMSException(ex);
+ }
+ }
+
+ /// <summary>
+ /// Writes a byte to the stream message.
+ /// </summary>
+ /// <param name="value">A <see cref="System.Byte"/></param>
+ public void WriteByte(byte value)
+ {
+ try
+ {
+ this.xmsStreamMessage.WriteByte(value);
+ }
+ catch(Exception ex)
+ {
+ ExceptionUtil.WrapAndThrowNMSException(ex);
+ }
+ }
+
+ /// <summary>
+ /// Writes a byte array to the stream message.
+ /// </summary>
+ /// <param name="value">A <see cref="System.Byte"/> array</param>
+ public void WriteBytes(byte[] value)
+ {
+ try
+ {
+ this.xmsStreamMessage.WriteBytes(value);
+ }
+ catch(Exception ex)
+ {
+ ExceptionUtil.WrapAndThrowNMSException(ex);
+ }
+ }
+
+ /// <summary>
+ /// Writes a portion of a byte array as a byte array field to the
+ /// stream message.
+ /// </summary>
+ /// <param name="value">A <see cref="System.Byte"/> array</param>
+ /// <param name="offset">A <see cref="System.Int32"/> value that
+ /// indicates the point in the buffer to begin writing to the stream
+ /// message.</param>
+ /// <param name="length">A <see cref="System.Int32"/> value that
+ /// indicates how many bytes in the buffer to write to the stream
+ /// message.</param>
+ public void WriteBytes(byte[] value, int offset, int length)
+ {
+ try
+ {
+ this.xmsStreamMessage.WriteBytes(value, offset, length);
+ }
+ catch(Exception ex)
+ {
+ ExceptionUtil.WrapAndThrowNMSException(ex);
+ }
+ }
+
+ /// <summary>
+ /// Writes a character to the stream message.
+ /// </summary>
+ /// <param name="value">A <see cref="System.Char"/></param>
+ public void WriteChar(char value)
+ {
+ try
+ {
+ this.xmsStreamMessage.WriteChar(value);
+ }
+ catch(Exception ex)
+ {
+ ExceptionUtil.WrapAndThrowNMSException(ex);
+ }
+ }
+
+ /// <summary>
+ /// Writes a 16 bts (short) integer to the stream message.
+ /// </summary>
+ /// <param name="value">A <see cref="System.Int16"/></param>
+ public void WriteInt16(short value)
+ {
+ try
+ {
+ this.xmsStreamMessage.WriteShort(value);
+ }
+ catch(Exception ex)
+ {
+ ExceptionUtil.WrapAndThrowNMSException(ex);
+ }
+ }
+
+ /// <summary>
+ /// Writes a 32 bts (int) integer to the stream message.
+ /// </summary>
+ /// <param name="value">A <see cref="System.Int32"/></param>
+ public void WriteInt32(int value)
+ {
+ try
+ {
+ this.xmsStreamMessage.WriteInt(value);
+ }
+ catch(Exception ex)
+ {
+ ExceptionUtil.WrapAndThrowNMSException(ex);
+ }
+ }
+
+ /// <summary>
+ /// Writes a 64 bts (long) integer to the stream message.
+ /// </summary>
+ /// <param name="value">A <see cref="System.Int64"/></param>
+ public void WriteInt64(long value)
+ {
+ try
+ {
+ this.xmsStreamMessage.WriteLong(value);
+ }
+ catch(Exception ex)
+ {
+ ExceptionUtil.WrapAndThrowNMSException(ex);
+ }
+ }
+
+ /// <summary>
+ /// Writes a single precision floating point number to the stream
+ /// message.
+ /// </summary>
+ /// <param name="value">A <see cref="System.Single"/></param>
+ public void WriteSingle(float value)
+ {
+ try
+ {
+ this.xmsStreamMessage.WriteFloat(value);
+ }
+ catch(Exception ex)
+ {
+ ExceptionUtil.WrapAndThrowNMSException(ex);
+ }
+ }
+
+ /// <summary>
+ /// Writes a double precision floating point number to the stream
+ /// message.
+ /// </summary>
+ /// <param name="value">A <see cref="System.Double"/></param>
+ public void WriteDouble(double value)
+ {
+ try
+ {
+ this.xmsStreamMessage.WriteDouble(value);
+ }
+ catch(Exception ex)
+ {
+ ExceptionUtil.WrapAndThrowNMSException(ex);
+ }
+ }
+
+ /// <summary>
+ /// Writes a character string to the stream
+ /// message.
+ /// </summary>
+ /// <param name="value">A <see cref="System.String"/></param>
+ public void WriteString(string value)
+ {
+ try
+ {
+ this.xmsStreamMessage.WriteString(value);
+ }
+ catch(Exception ex)
+ {
+ ExceptionUtil.WrapAndThrowNMSException(ex);
+ }
+ }
+
+ /// <summary>
+ /// Writes an object to the stream
+ /// message.
+ /// </summary>
+ /// <param name="value">A <see cref="System.Object"/></param>
+ public void WriteObject(object value)
+ {
+ try
+ {
+ this.xmsStreamMessage.WriteObject(value);
+ }
+ catch(Exception ex)
+ {
+ ExceptionUtil.WrapAndThrowNMSException(ex);
+ }
+ }
+
+ #endregion
+
+ #endregion
+ }
+}
diff --git a/src/main/csharp/TemporaryQueue.cs b/src/main/csharp/TemporaryQueue.cs
new file mode 100644
index 0000000..4d896c5
--- /dev/null
+++ b/src/main/csharp/TemporaryQueue.cs
@@ -0,0 +1,62 @@
+/*
+ * 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.
+ */
+
+namespace Apache.NMS.XMS
+{
+ class TemporaryQueue : Apache.NMS.XMS.Queue, Apache.NMS.ITemporaryQueue
+ {
+ #region Constructors and destructors
+
+ /// <summary>
+ /// Constructs a <c>TemporaryQueue</c> object.
+ /// </summary>
+ /// <param name="temporaryQueue">IBM XMS queue</param>
+ public TemporaryQueue(IBM.XMS.IDestination temporaryQueue)
+ : base(temporaryQueue, true)
+ {
+ }
+
+ #endregion
+
+ #region ITemporaryQueue Members
+
+ /// <summary>
+ /// Deletes the temporary queue.
+ /// </summary>
+ public void Delete()
+ {
+ // IBM.XMS does not provide a method for deleting a destination.
+ // Should we throw an exception or ignore the request ?
+ //this.xmsDestination.Delete();
+ }
+
+ #endregion
+
+ #region ToString
+
+ /// <summary>
+ /// Returns a string representation of this instance.
+ /// </summary>
+ /// <returns>String representation of this instance</returns>
+ public override System.String ToString()
+ {
+ return "temp-queue://" + QueueName;
+ }
+
+ #endregion
+ }
+}
diff --git a/src/main/csharp/TemporaryTopic.cs b/src/main/csharp/TemporaryTopic.cs
new file mode 100644
index 0000000..374b528
--- /dev/null
+++ b/src/main/csharp/TemporaryTopic.cs
@@ -0,0 +1,62 @@
+/*
+ * 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.
+ */
+
+namespace Apache.NMS.XMS
+{
+ class TemporaryTopic : Apache.NMS.XMS.Topic, Apache.NMS.ITemporaryTopic
+ {
+ #region Constructors and destructors
+
+ /// <summary>
+ /// Constructs a <c>TemporaryTopic</c> object.
+ /// </summary>
+ /// <param name="temporaryTopic">IBM XMS queue</param>
+ public TemporaryTopic(IBM.XMS.IDestination temporaryTopic)
+ : base(temporaryTopic, true)
+ {
+ }
+
+ #endregion
+
+ #region ITemporaryTopic Members
+
+ /// <summary>
+ /// Deletes the temporary topic.
+ /// </summary>
+ public void Delete()
+ {
+ // IBM.XMS does not provide a method for deleting a destination.
+ // Should we throw an exception or ignore the request ?
+ //this.xmsDestination.Delete();
+ }
+
+ #endregion
+
+ #region ToString
+
+ /// <summary>
+ /// Returns a string representation of this instance.
+ /// </summary>
+ /// <returns>string representation of this instance</returns>
+ public override System.String ToString()
+ {
+ return "temp-topic://" + TopicName;
+ }
+
+ #endregion
+ }
+}
diff --git a/src/main/csharp/TextMessage.cs b/src/main/csharp/TextMessage.cs
new file mode 100644
index 0000000..d98cd03
--- /dev/null
+++ b/src/main/csharp/TextMessage.cs
@@ -0,0 +1,86 @@
+/*
+ * 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.
+ */
+using System;
+using Apache.NMS;
+using Apache.NMS.Util;
+using Apache.NMS.XMS.Util;
+using IBM.XMS;
+
+namespace Apache.NMS.XMS
+{
+ /// <summary>
+ /// Represents a text based message.
+ /// </summary>
+ class TextMessage : Apache.NMS.XMS.Message, Apache.NMS.ITextMessage
+ {
+ #region Constructors and access to internal stream message
+
+ /// <summary>
+ /// Internal IBM XMS text message.
+ /// </summary>
+ public IBM.XMS.ITextMessage xmsTextMessage
+ {
+ get { return (IBM.XMS.ITextMessage)this.xmsMessage; }
+ set { this.xmsMessage = value; }
+ }
+
+ /// <summary>
+ /// Constructs a <c>TextMessage</c> object.
+ /// </summary>
+ /// <param name="message">XMS text message.</param>
+ public TextMessage(IBM.XMS.ITextMessage message)
+ : base(message)
+ {
+ }
+
+ #endregion
+
+ #region ITextMessage Members
+
+ /// <summary>
+ /// The text contents of the message body.
+ /// </summary>
+ public string Text
+ {
+ get
+ {
+ try
+ {
+ return this.xmsTextMessage.Text;
+ }
+ catch(Exception ex)
+ {
+ ExceptionUtil.WrapAndThrowNMSException(ex);
+ return null;
+ }
+ }
+ set
+ {
+ try
+ {
+ this.xmsTextMessage.Text = value;
+ }
+ catch(Exception ex)
+ {
+ ExceptionUtil.WrapAndThrowNMSException(ex);
+ }
+ }
+ }
+
+ #endregion
+ }
+}
diff --git a/src/main/csharp/Topic.cs b/src/main/csharp/Topic.cs
new file mode 100644
index 0000000..c4cc4c2
--- /dev/null
+++ b/src/main/csharp/Topic.cs
@@ -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.
+ */
+using System;
+using Apache.NMS;
+using Apache.NMS.Util;
+using Apache.NMS.XMS.Util;
+using IBM.XMS;
+
+namespace Apache.NMS.XMS
+{
+ public class Topic : Apache.NMS.XMS.Destination, Apache.NMS.ITopic
+ {
+ #region Constructors and destructors
+
+ /// <summary>
+ /// Constructs a <c>Topic</c> object.
+ /// </summary>
+ /// <param name="topic">IBM XMS topic</param>
+ public Topic(IBM.XMS.IDestination topic)
+ : base(topic)
+ {
+ }
+
+ /// <summary>
+ /// Constructs a <c>Topic</c> object.
+ /// </summary>
+ /// <param name="topic">IBM XMS topic</param>
+ /// <param name="isTemporary">Whether the topic is temporary</param>
+ public Topic(IBM.XMS.IDestination topic, bool isTemporary)
+ : base(topic, isTemporary)
+ {
+ }
+
+ #endregion
+
+ #region ITopic Members
+
+ public string TopicName
+ {
+ get { return this.xmsDestination.Name; }
+ }
+
+ #endregion
+
+ #region ToString
+
+ /// <summary>
+ /// Returns a String representation of this instance.
+ /// </summary>
+ /// <returns>String representation of this instance</returns>
+ public override System.String ToString()
+ {
+ return "topic://" + TopicName;
+ }
+
+ #endregion
+ }
+}
\ No newline at end of file
diff --git a/src/main/csharp/Util/Dispatcher.cs b/src/main/csharp/Util/Dispatcher.cs
new file mode 100644
index 0000000..d036cb3
--- /dev/null
+++ b/src/main/csharp/Util/Dispatcher.cs
@@ -0,0 +1,173 @@
+/*
+ * 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.
+ */
+using System;
+using System.Collections;
+using System.Threading;
+
+namespace Apache.NMS.XMS.Util
+{
+ /// <summary>
+ /// Handles the multi-threaded dispatching between the transport and the consumers
+ /// </summary>
+ public class Dispatcher
+ {
+ System.Collections.Queue queue = new System.Collections.Queue();
+ readonly Object semaphore = new Object();
+ readonly ArrayList messagesToRedeliver = new ArrayList();
+
+ // TODO can't use EventWaitHandle on MONO 1.0
+ AutoResetEvent messageReceivedEventHandle = new AutoResetEvent(false);
+ bool m_bAsyncDelivery = false;
+ bool m_bClosed = false;
+
+ public void SetAsyncDelivery(AutoResetEvent eventHandle)
+ {
+ lock (semaphore)
+ {
+ messageReceivedEventHandle = eventHandle;
+ m_bAsyncDelivery = true;
+ if (queue.Count > 0)
+ {
+ messageReceivedEventHandle.Set();
+ }
+ }
+ }
+
+ /// <summary>
+ /// Whem we start a transaction we must redeliver any rolled back messages
+ /// </summary>
+ public void RedeliverRolledBackMessages()
+ {
+ lock (semaphore)
+ {
+ System.Collections.Queue replacement = new System.Collections.Queue(queue.Count + messagesToRedeliver.Count);
+ foreach (Apache.NMS.IMessage element in messagesToRedeliver)
+ {
+ replacement.Enqueue(element);
+ }
+ messagesToRedeliver.Clear();
+
+ while (queue.Count > 0)
+ {
+ Apache.NMS.IMessage element = (Apache.NMS.IMessage) queue.Dequeue();
+ replacement.Enqueue(element);
+ }
+
+ queue = replacement;
+ if (queue.Count > 0)
+ {
+ messageReceivedEventHandle.Set();
+ }
+ }
+ }
+
+ /// <summary>
+ /// Redeliver the given message, putting it at the head of the queue
+ /// </summary>
+ public void Redeliver(Apache.NMS.IMessage message)
+ {
+ lock (semaphore)
+ {
+ messagesToRedeliver.Add(message);
+ }
+ }
+
+ /// <summary>
+ /// Method Enqueue
+ /// </summary>
+ public void Enqueue(Apache.NMS.IMessage message)
+ {
+ lock (semaphore)
+ {
+ queue.Enqueue(message);
+ messageReceivedEventHandle.Set();
+ }
+ }
+
+ /// <summary>
+ /// Method DequeueNoWait
+ /// </summary>
+ public Apache.NMS.IMessage DequeueNoWait()
+ {
+ Apache.NMS.XMS.Message rc = null;
+ lock (semaphore)
+ {
+ if (!m_bClosed && queue.Count > 0)
+ {
+ rc = (Apache.NMS.XMS.Message) queue.Dequeue();
+ if(null != rc)
+ {
+ rc.ReadOnlyBody = true;
+ rc.ReadOnlyProperties = true;
+ }
+ }
+ }
+ return rc;
+ }
+
+ /// <summary>
+ /// Method Dequeue
+ /// </summary>
+ public Apache.NMS.IMessage Dequeue(TimeSpan timeout)
+ {
+ Apache.NMS.IMessage rc;
+ bool bClosed = false;
+ lock (semaphore)
+ {
+ bClosed = m_bClosed;
+ rc = DequeueNoWait();
+ }
+
+ while (!bClosed && rc == null)
+ {
+ if( !messageReceivedEventHandle.WaitOne(timeout, false))
+ {
+ break;
+ }
+
+ lock (semaphore)
+ {
+ rc = DequeueNoWait();
+ bClosed = m_bClosed;
+ }
+ }
+ return rc;
+ }
+
+ /// <summary>
+ /// Method Dequeue
+ /// </summary>
+ public Apache.NMS.IMessage Dequeue()
+ {
+ TimeSpan indefiniteWait = TimeSpan.FromMilliseconds(Timeout.Infinite);
+ return Dequeue(indefiniteWait);
+ }
+
+ public void Close()
+ {
+ lock (semaphore)
+ {
+ m_bClosed = true;
+ queue.Clear();
+ if(m_bAsyncDelivery)
+ {
+ messageReceivedEventHandle.Set();
+ }
+ }
+ }
+ }
+}
diff --git a/src/main/csharp/Util/ExceptionUtil.cs b/src/main/csharp/Util/ExceptionUtil.cs
new file mode 100644
index 0000000..14ee5d1
--- /dev/null
+++ b/src/main/csharp/Util/ExceptionUtil.cs
@@ -0,0 +1,147 @@
+/*
+ * 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.
+ */
+using System;
+using System.Text;
+using System.Collections.Generic;
+using IBM.XMS;
+
+namespace Apache.NMS.XMS.Util
+{
+ class ExceptionUtil
+ {
+ /// <summary>
+ /// Wrap the provider specific exception inside an NMS exception to
+ /// more tightly integrate the provider extensions into the NMS API.
+ /// </summary>
+ /// <param name="ex">Original exception.</param>
+ public static void WrapAndThrowNMSException(Exception ex)
+ {
+ if(ex is Apache.NMS.NMSException)
+ {
+ // Already derived from NMSException
+ throw ex;
+ }
+
+ if(ex is IBM.XMS.IllegalStateException)
+ {
+ IBM.XMS.IllegalStateException xmsEx =
+ (IBM.XMS.IllegalStateException)ex;
+ throw new Apache.NMS.IllegalStateException(
+ xmsEx.Message, xmsEx.ErrorCode, xmsEx);
+ }
+
+ if(ex is IBM.XMS.InvalidClientIDException)
+ {
+ IBM.XMS.InvalidClientIDException xmsEx =
+ (IBM.XMS.InvalidClientIDException)ex;
+ throw new Apache.NMS.InvalidClientIDException(
+ xmsEx.Message, xmsEx.ErrorCode, xmsEx);
+ }
+
+ if(ex is IBM.XMS.InvalidDestinationException)
+ {
+ IBM.XMS.InvalidDestinationException xmsEx =
+ (IBM.XMS.InvalidDestinationException)ex;
+ throw new Apache.NMS.InvalidDestinationException(
+ xmsEx.Message, xmsEx.ErrorCode, xmsEx);
+ }
+
+ if(ex is IBM.XMS.InvalidSelectorException)
+ {
+ IBM.XMS.InvalidSelectorException xmsEx =
+ (IBM.XMS.InvalidSelectorException)ex;
+ throw new Apache.NMS.InvalidSelectorException(
+ xmsEx.Message, xmsEx.ErrorCode, xmsEx);
+ }
+
+ if(ex is IBM.XMS.MessageEOFException)
+ {
+ IBM.XMS.MessageEOFException xmsEx =
+ (IBM.XMS.MessageEOFException)ex;
+ throw new Apache.NMS.MessageEOFException(
+ xmsEx.Message, xmsEx.ErrorCode, xmsEx);
+ }
+
+ if(ex is IBM.XMS.MessageFormatException)
+ {
+ IBM.XMS.MessageFormatException xmsEx =
+ (IBM.XMS.MessageFormatException)ex;
+ throw new Apache.NMS.MessageFormatException(
+ xmsEx.Message, xmsEx.ErrorCode, xmsEx);
+ }
+
+ if(ex is IBM.XMS.MessageNotReadableException)
+ {
+ IBM.XMS.MessageNotReadableException xmsEx =
+ (IBM.XMS.MessageNotReadableException)ex;
+ throw new Apache.NMS.MessageNotReadableException(
+ xmsEx.Message, xmsEx.ErrorCode, xmsEx);
+ }
+
+ if(ex is IBM.XMS.MessageNotWriteableException)
+ {
+ IBM.XMS.MessageNotWriteableException xmsEx =
+ (IBM.XMS.MessageNotWriteableException)ex;
+ throw new Apache.NMS.MessageNotWriteableException(
+ xmsEx.Message, xmsEx.ErrorCode, xmsEx);
+ }
+
+ if(ex is IBM.XMS.ResourceAllocationException)
+ {
+ IBM.XMS.ResourceAllocationException xmsEx =
+ (IBM.XMS.ResourceAllocationException)ex;
+ throw new Apache.NMS.ResourceAllocationException(
+ xmsEx.Message, xmsEx.ErrorCode, xmsEx);
+ }
+
+ if(ex is IBM.XMS.SecurityException)
+ {
+ IBM.XMS.SecurityException xmsEx =
+ (IBM.XMS.SecurityException)ex;
+ throw new Apache.NMS.NMSSecurityException(
+ xmsEx.Message, xmsEx.ErrorCode, xmsEx);
+ }
+
+ if(ex is IBM.XMS.TransactionInProgressException)
+ {
+ IBM.XMS.TransactionInProgressException xmsEx =
+ (IBM.XMS.TransactionInProgressException)ex;
+ throw new Apache.NMS.TransactionInProgressException(
+ xmsEx.Message, xmsEx.ErrorCode, xmsEx);
+ }
+
+ if(ex is IBM.XMS.TransactionRolledBackException)
+ {
+ IBM.XMS.TransactionRolledBackException xmsEx =
+ (IBM.XMS.TransactionRolledBackException)ex;
+ throw new Apache.NMS.TransactionRolledBackException(
+ xmsEx.Message, xmsEx.ErrorCode, xmsEx);
+ }
+
+ if(ex is IBM.XMS.XMSException)
+ {
+ IBM.XMS.XMSException xmsEx =
+ (IBM.XMS.XMSException)ex;
+ throw new Apache.NMS.NMSException(
+ xmsEx.Message, xmsEx.ErrorCode, xmsEx);
+ }
+
+ // Not an EMS exception that should be wrapped.
+ throw ex;
+ }
+ }
+}
diff --git a/src/main/csharp/Util/IntrospectionSupport.cs b/src/main/csharp/Util/IntrospectionSupport.cs
new file mode 100644
index 0000000..175135f
--- /dev/null
+++ b/src/main/csharp/Util/IntrospectionSupport.cs
@@ -0,0 +1,434 @@
+/*
+ * 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.
+ */
+
+using System;
+using System.Reflection;
+using System.Globalization;
+using System.Collections.Generic;
+using System.Collections.Specialized;
+using Apache.NMS;
+using Apache.NMS.Util;
+
+namespace Apache.NMS.XMS.Util
+{
+ /// <summary>
+ /// Utility class used to provide convenience methods that apply named
+ /// property settings to objects.
+ /// </summary>
+ public class IntrospectionSupport
+ {
+ #region Manage maps of member names and URI aliases
+
+ private static Dictionary<Type, StringDictionary> nameMaps =
+ new Dictionary<Type, StringDictionary>();
+ private static readonly object nameMapsLock = new object();
+
+ /// <summary>
+ /// Gets the member names map for the specified type.
+ /// </summary>
+ /// <param name="type">Type whose names map is requested.</param>
+ /// <returns>Names map for the specified type.</returns>
+ /// <remarks>
+ /// The map is created and registered if it is not found in the
+ /// <c>nameMaps</c> registry.
+ /// </remarks>
+ public static StringDictionary GetNameMap(Type type)
+ {
+ StringDictionary nameMap;
+ lock(IntrospectionSupport.nameMapsLock)
+ {
+ if(!IntrospectionSupport.nameMaps.TryGetValue(
+ type, out nameMap))
+ {
+ nameMap = CreateNameMap(type);
+ IntrospectionSupport.nameMaps.Add(type, nameMap);
+ }
+ }
+ return nameMap;
+ }
+
+ /// <summary>
+ /// Creates a dictionary of public property and attribute names,
+ /// indexed by themselves plus all URI attribute keys associated
+ /// to them.
+ /// </summary>
+ /// <param name="type">Type whose names map is requested.</param>
+ /// <returns>Names map for the specified type.</returns>
+ /// <remarks>
+ /// Applied to this property:
+ /// <code>
+ /// [UriAttribute("My.Test", "MyTest")]
+ /// public string Test
+ /// { get { return(_test); }
+ /// set { _test = value; }
+ /// }
+ /// </code>
+ /// the method returns a dictionary containing
+ /// ("test" -> "Test"), ("my.test" -> "Test"), ("mytest" -> "Test").
+ /// Note that <c>StringDictionary</c> converts keys to lowercase but
+ /// keeps values untouched.
+ /// </remarks>
+ public static StringDictionary CreateNameMap(Type type)
+ {
+ StringDictionary nameMap = new StringDictionary();
+ BindingFlags flags = BindingFlags.FlattenHierarchy
+ | BindingFlags.Public
+ | BindingFlags.Instance;
+
+ // Process public instance self or inherited property
+ foreach(PropertyInfo propertyInfo in type.GetProperties(flags))
+ {
+ AddToNameMap(nameMap, propertyInfo);
+ }
+
+ // Process public instance self or inherited fields
+ foreach(FieldInfo fieldInfo in type.GetFields(flags))
+ {
+ AddToNameMap(nameMap, fieldInfo);
+ }
+
+ return(nameMap);
+ }
+
+ /// <summary>
+ /// Adds a property or field name and URI attribute keys to the
+ /// specified name map.
+ /// </summary>
+ /// <param name="nameMap">Name map.</param>
+ /// <param name="memberInfo">Member information for the property
+ /// or field.</param>
+ private static void AddToNameMap(StringDictionary nameMap,
+ MemberInfo memberInfo)
+ {
+ // Add member name mapped to itself
+ nameMap.Add(memberInfo.Name, memberInfo.Name);
+
+ // For each UriAttribute custom attribute
+ foreach(Attribute attr in memberInfo.GetCustomAttributes(
+ typeof(UriAttributeAttribute), true))
+ {
+ // For each URI attribute key
+ foreach(string key in
+ ((UriAttributeAttribute)attr).AttributeKeys)
+ {
+ // Index property name by URI attribute key
+ if(!nameMap.ContainsKey(key))
+ {
+ nameMap.Add(key, memberInfo.Name);
+ }
+ }
+ }
+
+ return;
+ }
+
+ #endregion
+
+ #region Set properties
+
+ /// <summary>
+ /// Sets the public properties of a target object using a string map.
+ /// This method uses .Net reflection to identify public properties of
+ /// the target object matching the keys from the passed map.
+ /// </summary>
+ /// <param name="target">Object whose properties will be set.</param>
+ /// <param name="valueMap">Map of key/value pairs.</param>
+ public static void SetProperties(object target,
+ StringDictionary valueMap)
+ {
+ SetProperties(target, valueMap, GetNameMap(target.GetType()));
+ }
+
+ /// <summary>
+ /// Sets the public properties of a target object using a string map.
+ /// This method uses .Net reflection to access public properties of
+ /// the target object matching the keys from the passed map.
+ /// </summary>
+ /// <param name="target">The object whose properties will be set.</param>
+ /// <param name="valueMap">Map of key/value pairs.</param>
+ /// <param name="nameMap">Map of key/property name pairs.</param>
+ public static void SetProperties(object target,
+ StringDictionary valueMap,
+ StringDictionary nameMap)
+ {
+ Tracer.DebugFormat("SetProperties called with target: {0}",
+ target.GetType().Name);
+
+ // Application of specified values is recursive. If a key does not
+ // correspond to a member of the current target object, it is
+ // supposed to refer to a sub-member of such a member. Since member
+ // keys can contain dot characters, an attempt is made to find the
+ // "longest" key corresponding to a member of the current object
+ // (this identifies the "sub-target"), and extract the remaining
+ // key characters as a sub-key to sub-members.
+ // The following dictionary indexes keys to "sub-targets", and
+ // "sub-key"/value pairs to assign to "sub-targets".
+ Dictionary<string, StringDictionary> subTargetMap = null;
+
+ foreach(string key in valueMap.Keys)
+ {
+ if(nameMap.ContainsKey(key))
+ {
+ // Key refers to a member of the current target
+ string memberName = nameMap[key];
+ MemberInfo member = FindMemberInfo(target, memberName);
+ if(member == null)
+ {
+ // Should not happen if the nameMap was indeed created
+ // for the current target object...
+ throw new NMSException(string.Format(
+ "No such property or field: {0} on class: {1}",
+ memberName, target.GetType().Name));
+ }
+
+ // Set value
+ try
+ {
+ if(member.MemberType == MemberTypes.Property)
+ {
+ PropertyInfo property = (PropertyInfo)member;
+ object value = ConvertValue(valueMap[key],
+ property.PropertyType);
+ property.SetValue(target, value, null);
+ }
+ else
+ {
+ FieldInfo field = (FieldInfo)member;
+ object value = ConvertValue(valueMap[key],
+ field.FieldType);
+ field.SetValue(target, value);
+ }
+ }
+ catch(Exception ex)
+ {
+ throw NMSExceptionSupport.Create(
+ "Error while attempting to apply option.", ex);
+ }
+ }
+ else
+ {
+ // Key does NOT refers to a member of the current target
+ // Extract maximal member key + subkeys
+ string memberKey = key;
+ int dotPos = memberKey.LastIndexOf('.');
+ bool memberFound = false;
+ while(!memberFound && dotPos > 0)
+ {
+ memberKey = memberKey.Substring(0, dotPos);
+ if(nameMap.ContainsKey(memberKey))
+ {
+ memberKey = nameMap[memberKey];
+ memberFound = true;
+ }
+ else
+ {
+ dotPos = memberKey.LastIndexOf('.');
+ }
+ }
+
+ if(!memberFound)
+ {
+ throw new NMSException(string.Format(
+ "Unknown property or field: {0} on class: {1}",
+ key, target.GetType().Name));
+ }
+
+ // Register memberKey, subKey and value for further processing
+ string subKey = key.Substring(dotPos + 1);
+ StringDictionary subValueMap;
+
+ if(subTargetMap == null)
+ {
+ subTargetMap = new Dictionary<string, StringDictionary>();
+ }
+
+ if(!subTargetMap.TryGetValue(memberKey, out subValueMap))
+ {
+ subValueMap = new StringDictionary();
+ subTargetMap.Add(memberKey, subValueMap);
+ }
+
+ // In theory, we can't have the same subkey twice, since
+ // they were unique subkeys from another dictionary.
+ // Therefore, no need to check for subValueMap.ContainsKey.
+ subValueMap.Add(subKey, valueMap[key]);
+ }
+ }
+
+ // Now process any compound assignments.
+ if(subTargetMap != null)
+ {
+ foreach(string subTargetKey in subTargetMap.Keys)
+ {
+ MemberInfo member = FindMemberInfo(target, subTargetKey);
+ object subTarget = GetUnderlyingObject(member, target);
+ SetProperties(subTarget, subTargetMap[subTargetKey]);
+ }
+ }
+ }
+
+ /// <summary>
+ /// Converts the specified string value to the type of the target
+ /// member.
+ /// </summary>
+ private static object ConvertValue(string inputString, Type targetType)
+ {
+ // If the target member is an enumeration, get the enumeration
+ // value or combined (or-ed) values
+ object value;
+ if(targetType.IsEnum)
+ {
+ if(inputString.Contains("+"))
+ {
+ string[] inputValues = inputString.Split('+');
+
+ FieldInfo fieldInfo = targetType.GetField(inputValues[0],
+ BindingFlags.Public
+ | BindingFlags.Static
+ | BindingFlags.IgnoreCase);
+ if(fieldInfo == null)
+ {
+ throw new NMSException(string.Format(
+ "Invalid {0} value \"{1}\"", targetType.Name,
+ inputValues[0]));
+ }
+ dynamic val = fieldInfo.GetValue(null);
+
+ for(int v = 1; v < inputValues.Length; v++)
+ {
+ fieldInfo = targetType.GetField(inputValues[v],
+ BindingFlags.Public
+ | BindingFlags.Static
+ | BindingFlags.IgnoreCase);
+ if(fieldInfo == null)
+ {
+ throw new NMSException(string.Format(
+ "Invalid {0} value \"{1}\"", targetType.Name,
+ inputValues[v]));
+ }
+ val = (dynamic)val | (dynamic)fieldInfo.GetValue(null);
+ }
+
+ value = Convert.ChangeType(val, targetType);
+ }
+ else
+ {
+ FieldInfo fieldInfo = targetType.GetField(inputString,
+ BindingFlags.Public
+ | BindingFlags.Static
+ | BindingFlags.IgnoreCase);
+ if(fieldInfo == null)
+ {
+ throw new NMSException(string.Format(
+ "Invalid {0} value \"{1}\"", targetType.Name,
+ inputString));
+ }
+ value = fieldInfo.GetValue(null);
+ }
+ }
+ else
+ {
+ // Not an enumeration
+ value = Convert.ChangeType(inputString,
+ targetType, CultureInfo.InvariantCulture);
+ }
+ return value;
+ }
+
+ #endregion
+
+ #region Get member information and objects
+
+ /// <summary>
+ /// Gets member information for a property or field of the target
+ /// object.
+ /// </summary>
+ /// <param name="target">Target object.</param>
+ /// <param name="name">Property or field name.</param>
+ /// <returns>Retrieved member information.</returns>
+ private static MemberInfo FindMemberInfo(object target, string name)
+ {
+ BindingFlags flags = BindingFlags.FlattenHierarchy
+ | BindingFlags.Public
+ | BindingFlags.Instance
+ | BindingFlags.IgnoreCase;
+
+ Type type = target.GetType();
+
+ MemberInfo member = type.GetProperty(name, flags);
+
+ if(member == null)
+ {
+ member = type.GetField(name, flags);
+ }
+
+ return member;
+ }
+
+ /// <summary>
+ /// Gets object assigned to the specified property or field member of
+ /// the target object.
+ /// </summary>
+ /// <param name="member">Member information.</param>
+ /// <param name="target">Target object.</param>
+ /// <returns>Retrieved object.</returns>
+ private static object GetUnderlyingObject(
+ MemberInfo member, object target)
+ {
+ object result = null;
+
+ if(member.MemberType == MemberTypes.Field)
+ {
+ FieldInfo field = member as FieldInfo;
+
+ if(field.FieldType.IsPrimitive)
+ {
+ throw new NMSException(string.Format(
+ "The field given is a primitive type: {0}",
+ member.Name));
+ }
+
+ result = field.GetValue(target);
+ }
+ else
+ {
+ PropertyInfo property = member as PropertyInfo;
+ MethodInfo getter = property.GetGetMethod();
+
+ if(getter == null)
+ {
+ throw new NMSException(string.Format(
+ "Cannot access member: {0}",
+ member.Name));
+ }
+
+ result = getter.Invoke(target, null);
+ }
+
+ if(result == null)
+ {
+ throw new NMSException(string.Format(
+ "Could not retrieve the value of member {0}.",
+ member.Name));
+ }
+
+ return result;
+ }
+
+ #endregion
+ }
+}
diff --git a/src/main/csharp/Util/UriAttributeAttribute.cs b/src/main/csharp/Util/UriAttributeAttribute.cs
new file mode 100644
index 0000000..f7278d8
--- /dev/null
+++ b/src/main/csharp/Util/UriAttributeAttribute.cs
@@ -0,0 +1,51 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+
+namespace Apache.NMS.XMS.Util
+{
+ /// <summary>
+ /// Attribute for mapping a URI attribute key to an object's property.
+ /// </summary>
+ public class UriAttributeAttribute : System.Attribute
+ {
+ private readonly string[] attributeKeys;
+
+ /// <summary>
+ /// Constructs an <c>UriAttributeAttribute</c> specifying a list
+ /// of attribute keys.
+ /// </summary>
+ /// <param name="keys">URI attribute keys.</param>
+ public UriAttributeAttribute(params string[] keys)
+ {
+ this.attributeKeys = new string[keys.Length];
+ for(int k = 0; k < keys.Length; k++)
+ {
+ this.attributeKeys[k] = keys[k];
+ }
+ }
+
+ /// <summary>
+ /// URI attribute keys.
+ /// </summary>
+ public string[] AttributeKeys
+ {
+ get { return this.attributeKeys; }
+ }
+ }
+}
diff --git a/src/main/csharp/Util/XMSConvert.cs b/src/main/csharp/Util/XMSConvert.cs
new file mode 100644
index 0000000..06d8e2c
--- /dev/null
+++ b/src/main/csharp/Util/XMSConvert.cs
@@ -0,0 +1,1475 @@
+/*
+ * 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.
+ */
+using System;
+using System.Collections;
+using IBM.XMS;
+
+namespace Apache.NMS.XMS.Util
+{
+ /// <summary>
+ /// This class implements conversion methods between the IBM XMS and
+ /// the Apache NMS models.
+ /// </summary>
+ public class XMSConvert
+ {
+ #region IBM XMS to Apache NMS objects conversion
+
+ /// <summary>
+ /// Converts an IBM XMS connection interface
+ /// into an NMS connection interface.
+ /// </summary>
+ /// <param name="xmsConnection">IBM XMS connection interface.</param>
+ /// <returns>Apache NMS connection interface.</returns>
+ public static Apache.NMS.IConnection ToNMSConnection(
+ IBM.XMS.IConnection xmsConnection)
+ {
+ return (xmsConnection != null
+ ? new Apache.NMS.XMS.Connection(xmsConnection)
+ : null);
+ }
+
+ /// <summary>
+ /// Converts an IBM XMS session interface
+ /// into an NMS session interface.
+ /// </summary>
+ /// <param name="xmsSession">IBM XMS session interface.</param>
+ /// <returns>Apache NMS session interface.</returns>
+ public static Apache.NMS.ISession ToNMSSession(
+ IBM.XMS.ISession xmsSession)
+ {
+ return (xmsSession != null
+ ? new Apache.NMS.XMS.Session(xmsSession)
+ : null);
+ }
+
+ /// <summary>
+ /// Converts an IBM XMS destination interface
+ /// into an NMS destination interface.
+ /// </summary>
+ /// <param name="xmsDestination">XMS destination.</param>
+ /// <returns>Apache NMS destination interface.</returns>
+ public static Apache.NMS.IDestination ToNMSDestination(
+ IBM.XMS.IDestination xmsDestination)
+ {
+ return ToNMSDestination(xmsDestination, false);
+ }
+
+ /// <summary>
+ /// Converts an IBM XMS destination interface
+ /// into an NMS destination interface.
+ /// </summary>
+ /// <param name="xmsDestination">XMS destination.</param>
+ /// <param name="isTemporary">Destination is temporary.</param>
+ /// <returns>Apache NMS destination interface.</returns>
+ public static Apache.NMS.IDestination ToNMSDestination(
+ IBM.XMS.IDestination xmsDestination,
+ bool isTemporary)
+ {
+ if(xmsDestination.TypeId == IBM.XMS.DestinationType.Queue)
+ {
+ return (isTemporary ? ToNMSTemporaryQueue(xmsDestination)
+ : ToNMSQueue(xmsDestination));
+ }
+
+ if(xmsDestination.TypeId == IBM.XMS.DestinationType.Topic)
+ {
+ return (isTemporary ? ToNMSTemporaryTopic(xmsDestination)
+ : ToNMSTopic(xmsDestination));
+ }
+
+ return null;
+ }
+
+ /// <summary>
+ /// Converts an IBM XMS queue interface
+ /// into an NMS queue interface.
+ /// </summary>
+ /// <param name="xmsQueue">XMS destination of type
+ /// <c>DestinationType.Queue</c>.</param>
+ /// <returns>Apache NMS queue interface.</returns>
+ public static Apache.NMS.IQueue ToNMSQueue(
+ IBM.XMS.IDestination xmsQueue)
+ {
+ if((xmsQueue != null) &&
+ (xmsQueue.TypeId != IBM.XMS.DestinationType.Queue))
+ { throw new ArgumentException(
+ "Cannot convert IBM XMS destination to NMS destination: invalid destination type id.",
+ "xmsQueue");
+ }
+ return (xmsQueue != null
+ ? new Apache.NMS.XMS.Queue(xmsQueue)
+ : null);
+ }
+
+ /// <summary>
+ /// Converts an IBM XMS topic interface
+ /// into an NMS topic interface.
+ /// </summary>
+ /// <param name="xmsTopic">XMS destination of type
+ /// <c>DestinationType.Topic</c>.</param>
+ /// <returns>Apache NMS topic interface.</returns>
+ public static Apache.NMS.ITopic ToNMSTopic(
+ IBM.XMS.IDestination xmsTopic)
+ {
+ if((xmsTopic != null) &&
+ (xmsTopic.TypeId != IBM.XMS.DestinationType.Topic))
+ { throw new ArgumentException(
+ "Cannot convert IBM XMS destination to NMS destination: invalid destination type id.",
+ "xmsTopic");
+ }
+ return (xmsTopic != null
+ ? new Apache.NMS.XMS.Topic(xmsTopic)
+ : null);
+ }
+
+ /// <summary>
+ /// Converts an IBM XMS temporary queue interface
+ /// into an NMS temporary queue interface.
+ /// </summary>
+ /// <param name="xmsTemporaryQueue">XMS destination of type
+ /// <c>DestinationType.Queue</c>.</param>
+ /// <returns>Apache NMS temporary queue interface.</returns>
+ // Couldn't find a means to test whether a XMS destination is temporary.
+ public static Apache.NMS.ITemporaryQueue ToNMSTemporaryQueue(
+ IBM.XMS.IDestination xmsTemporaryQueue)
+ {
+ if((xmsTemporaryQueue != null) &&
+ (xmsTemporaryQueue.TypeId != IBM.XMS.DestinationType.Queue))
+ { throw new ArgumentException(
+ "Cannot convert IBM XMS destination to NMS destination: invalid destination type id.",
+ "xmsTemporaryQueue");
+ }
+ return (xmsTemporaryQueue != null
+ ? new Apache.NMS.XMS.TemporaryQueue(xmsTemporaryQueue)
+ : null);
+ }
+
+ /// <summary>
+ /// Converts an IBM XMS temporary topic interface
+ /// into an NMS temporary topic interface.
+ /// </summary>
+ /// <param name="xmsTemporaryTopic">XMS destination of type
+ /// <c>DestinationType.Topic</c>.</param>
+ /// <returns>Apache NMS temporary topic interface.</returns>
+ // Couldn't find a means to test whether a XMS destination is temporary.
+ public static Apache.NMS.ITemporaryTopic ToNMSTemporaryTopic(
+ IBM.XMS.IDestination xmsTemporaryTopic)
+ {
+ if((xmsTemporaryTopic != null) &&
+ (xmsTemporaryTopic.TypeId != IBM.XMS.DestinationType.Queue))
+ { throw new ArgumentException(
+ "Cannot convert IBM XMS destination to NMS destination: invalid destination type id.",
+ "xmsTemporaryTopic");
+ }
+ return (xmsTemporaryTopic != null
+ ? new Apache.NMS.XMS.TemporaryTopic(xmsTemporaryTopic)
+ : null);
+ }
+
+ /// <summary>
+ /// Converts an IBM XMS message producer interface
+ /// into an NMS message producer interface.
+ /// </summary>
+ /// <param name="session">NMS session.</param>
+ /// <param name="xmsMessageProducer">XMS message producer.</param>
+ /// <returns>Apache NMS message producer interface.</returns>
+ public static Apache.NMS.IMessageProducer ToNMSMessageProducer(
+ Apache.NMS.XMS.Session session,
+ IBM.XMS.IMessageProducer xmsMessageProducer)
+ {
+ return (xmsMessageProducer != null
+ ? new Apache.NMS.XMS.MessageProducer(session, xmsMessageProducer)
+ : null);
+ }
+
+ /// <summary>
+ /// Converts an IBM XMS message consumer interface
+ /// into an NMS message consumer interface.
+ /// </summary>
+ /// <param name="session">NMS session.</param>
+ /// <param name="xmsMessageConsumer">XMS message consumer.</param>
+ /// <returns>Apache NMS message consumer interface.</returns>
+ public static Apache.NMS.IMessageConsumer ToNMSMessageConsumer(
+ Apache.NMS.XMS.Session session,
+ IBM.XMS.IMessageConsumer xmsMessageConsumer)
+ {
+ return (xmsMessageConsumer != null
+ ? new Apache.NMS.XMS.MessageConsumer(session, xmsMessageConsumer)
+ : null);
+ }
+
+ /// <summary>
+ /// Converts an IBM XMS queue browser interface
+ /// into an NMS queue browser interface.
+ /// </summary>
+ /// <param name="xmsQueueBrowser">XMS queue browser.</param>
+ /// <returns>Apache NMS queue browser interface.</returns>
+ public static Apache.NMS.IQueueBrowser ToNMSQueueBrowser(
+ IBM.XMS.IQueueBrowser xmsQueueBrowser)
+ {
+ return (xmsQueueBrowser != null
+ ? new Apache.NMS.XMS.QueueBrowser(xmsQueueBrowser)
+ : null);
+ }
+
+ /// <summary>
+ /// Converts an IBM XMS message
+ /// into an NMS message.
+ /// </summary>
+ /// <param name="xmsMessage">IBM XMS message.</param>
+ /// <returns>NMS message.</returns>
+ public static Apache.NMS.IMessage ToNMSMessage(IBM.XMS.IMessage xmsMessage)
+ {
+ if(xmsMessage is IBM.XMS.ITextMessage)
+ {
+ return ToNMSTextMessage((IBM.XMS.ITextMessage)xmsMessage);
+ }
+
+ if(xmsMessage is IBM.XMS.IBytesMessage)
+ {
+ return ToNMSBytesMessage((IBM.XMS.IBytesMessage)xmsMessage);
+ }
+
+ if(xmsMessage is IBM.XMS.IStreamMessage)
+ {
+ return ToNMSStreamMessage((IBM.XMS.IStreamMessage)xmsMessage);
+ }
+
+ if(xmsMessage is IBM.XMS.IMapMessage)
+ {
+ return ToNMSMapMessage((IBM.XMS.IMapMessage)xmsMessage);
+ }
+
+ if(xmsMessage is IBM.XMS.IObjectMessage)
+ {
+ return ToNMSObjectMessage((IBM.XMS.IObjectMessage)xmsMessage);
+ }
+
+ return (xmsMessage != null
+ ? new Apache.NMS.XMS.Message(xmsMessage)
+ : null);
+ }
+
+ /// <summary>
+ /// Converts an IBM XMS text message
+ /// into an NMS text message.
+ /// </summary>
+ /// <param name="xmsTextMessage">IBM XMS text message.</param>
+ /// <returns>NMS text message.</returns>
+ public static Apache.NMS.ITextMessage ToNMSTextMessage(
+ IBM.XMS.ITextMessage xmsTextMessage)
+ {
+ return (xmsTextMessage != null
+ ? new Apache.NMS.XMS.TextMessage(xmsTextMessage)
+ : null);
+ }
+
+ /// <summary>
+ /// Converts an IBM XMS bytes message
+ /// into an NMS bytes message.
+ /// </summary>
+ /// <param name="xmsBytesMessage">IBM XMS bytes message.</param>
+ /// <returns>NMS bytes message.</returns>
+ public static Apache.NMS.IBytesMessage ToNMSBytesMessage(
+ IBM.XMS.IBytesMessage xmsBytesMessage)
+ {
+ return (xmsBytesMessage != null
+ ? new Apache.NMS.XMS.BytesMessage(xmsBytesMessage)
+ : null);
+ }
+
+ /// <summary>
+ /// Converts an IBM XMS stream message
+ /// into an NMS stream message.
+ /// </summary>
+ /// <param name="xmsStreamMessage">IBM XMS stream message.</param>
+ /// <returns>NMS stream message.</returns>
+ public static Apache.NMS.IStreamMessage ToNMSStreamMessage(
+ IBM.XMS.IStreamMessage xmsStreamMessage)
+ {
+ return (xmsStreamMessage != null
+ ? new Apache.NMS.XMS.StreamMessage(xmsStreamMessage)
+ : null);
+ }
+
+ /// <summary>
+ /// Converts an IBM XMS map message
+ /// into an NMS map message.
+ /// </summary>
+ /// <param name="xmsMapMessage">IBM XMS map message.</param>
+ /// <returns>NMS map message.</returns>
+ public static Apache.NMS.IMapMessage ToNMSMapMessage(
+ IBM.XMS.IMapMessage xmsMapMessage)
+ {
+ return (xmsMapMessage != null
+ ? new Apache.NMS.XMS.MapMessage(xmsMapMessage)
+ : null);
+ }
+
+ /// <summary>
+ /// Converts an IBM XMS object message
+ /// into an NMS object message.
+ /// </summary>
+ /// <param name="xmsObjectMessage">IBM XMS object message.</param>
+ /// <returns>NMS object message.</returns>
+ public static Apache.NMS.IObjectMessage ToNMSObjectMessage(
+ IBM.XMS.IObjectMessage xmsObjectMessage)
+ {
+ return (xmsObjectMessage != null
+ ? new Apache.NMS.XMS.ObjectMessage(xmsObjectMessage)
+ : null);
+ }
+
+ /// <summary>
+ /// Converts an IBM XMS message
+ /// into an NMS primitive map.
+ /// </summary>
+ /// <param name="xmsMessage">IBM XMS message.</param>
+ /// <returns>NMS primitive map.</returns>
+ public static Apache.NMS.IPrimitiveMap ToMessageProperties(
+ IBM.XMS.IMessage xmsMessage)
+ {
+ return (xmsMessage != null
+ ? new Apache.NMS.XMS.MessageProperties(xmsMessage)
+ : null);
+ }
+
+ #endregion
+
+ #region Apache NMS to IBM XMS objects conversion
+
+ /// <summary>
+ /// Converts an NMS destination
+ /// into an IBM XMS destination.
+ /// </summary>
+ /// <param name="nmsDestination">NMS destination.</param>
+ /// <returns>IBM XMS destination.</returns>
+ public static IBM.XMS.IDestination ToXMSDestination(
+ Apache.NMS.IDestination nmsDestination)
+ {
+ if(nmsDestination is Apache.NMS.XMS.Destination)
+ {
+ return ((Apache.NMS.XMS.Destination)nmsDestination).xmsDestination;
+ }
+ return null;
+ }
+
+ #endregion
+
+ #region Property values conversion
+
+ #region Exception handling
+
+ /// <summary>
+ /// Throws a conversion exception.
+ /// </summary>
+ private static void ThrowCantConvertValueException(object value,
+ string conversionMethod)
+ {
+ throw new ArgumentException(string.Format(
+ "Cannot convert {0} using {1}.", value, conversionMethod),
+ conversionMethod);
+ }
+
+ #endregion
+
+ #region Encoding
+
+ /// <summary>
+ /// Converts an XMS encoding key.
+ /// </summary>
+ /// <param name="inputValue">Input value.</param>
+ /// <returns>Converted value.</returns>
+ public static Encoding ToEncoding(Int32 inputValue)
+ {
+ return (Encoding)inputValue;
+ }
+
+ /// <summary>
+ /// Converts an encoding to the equivalent XMS value.
+ /// </summary>
+ /// <param name="inputValue">Input value.</param>
+ /// <returns>Converted value.</returns>
+ public static Int32 ToXMSEncoding(Encoding inputValue)
+ {
+ return (Int32)inputValue;
+ }
+
+ #endregion
+
+ #region Message Type
+
+ /// <summary>
+ /// Converts an XMS message type key.
+ /// </summary>
+ /// <param name="inputValue">Input value.</param>
+ /// <returns>Converted value.</returns>
+ public static MessageType ToMessageType(Int32 inputValue)
+ {
+ return (MessageType)inputValue;
+ }
+
+ /// <summary>
+ /// Converts a message type to the equivalent XMS value.
+ /// </summary>
+ /// <param name="inputValue">Input value.</param>
+ /// <returns>Converted value.</returns>
+ public static Int32 ToXMSMessageType(MessageType inputValue)
+ {
+ return (Int32)inputValue;
+ }
+
+ #endregion
+
+ #region Report Confirm On Arrival
+
+ /// <summary>
+ /// Converts an XMS "confirm on arrival" key.
+ /// </summary>
+ /// <param name="inputValue">Input value.</param>
+ /// <returns>Converted value.</returns>
+ public static ReportConfirmOnArrival ToReportConfirmOnArrival(
+ Int32 inputValue)
+ {
+ return (ReportConfirmOnArrival)inputValue;
+ }
+
+ /// <summary>
+ /// Converts a "confirm on arrival" to the equivalent XMS value.
+ /// </summary>
+ /// <param name="inputValue">Input value.</param>
+ /// <returns>Converted value.</returns>
+ public static Int32 ToXMSReportConfirmOnArrival(
+ ReportConfirmOnArrival inputValue)
+ {
+ return (Int32)inputValue;
+ }
+
+ #endregion
+
+ #region Report Confirm On Delivery
+
+ /// <summary>
+ /// Converts an XMS "confirm on delivery" key.
+ /// </summary>
+ /// <param name="inputValue">Input value.</param>
+ /// <returns>Converted value.</returns>
+ public static ReportConfirmOnDelivery ToReportConfirmOnDelivery(
+ Int32 inputValue)
+ {
+ return (ReportConfirmOnDelivery)inputValue;
+ }
+
+ /// <summary>
+ /// Converts a "confirm on delivery" to the equivalent XMS value.
+ /// </summary>
+ /// <param name="inputValue">Input value.</param>
+ /// <returns>Converted value.</returns>
+ public static Int32 ToXMSReportConfirmOnDelivery(
+ ReportConfirmOnDelivery inputValue)
+ {
+ return (Int32)inputValue;
+ }
+
+ #endregion
+
+ #region Report Exception
+
+ /// <summary>
+ /// Converts an XMS "report exceptions" key.
+ /// </summary>
+ /// <param name="inputValue">Input value.</param>
+ /// <returns>Converted value.</returns>
+ public static ReportExceptions ToReportExceptions(
+ Int32 inputValue)
+ {
+ return (ReportExceptions)inputValue;
+ }
+
+ /// <summary>
+ /// Converts a "report exceptions" to the equivalent XMS value.
+ /// </summary>
+ /// <param name="inputValue">Input value.</param>
+ /// <returns>Converted value.</returns>
+ public static Int32 ToXMSReportExceptions(
+ ReportExceptions inputValue)
+ {
+ return (Int32)inputValue;
+ }
+
+ #endregion
+
+ #region Report Expiration
+
+ /// <summary>
+ /// Converts an XMS "report expiration" key.
+ /// </summary>
+ /// <param name="inputValue">Input value.</param>
+ /// <returns>Converted value.</returns>
+ public static ReportExpiration ToReportExpiration(
+ Int32 inputValue)
+ {
+ return (ReportExpiration)inputValue;
+ }
+
+ /// <summary>
+ /// Converts a "report expiration" to the equivalent XMS value.
+ /// </summary>
+ /// <param name="inputValue">Input value.</param>
+ /// <returns>Converted value.</returns>
+ public static Int32 ToXMSReportExpiration(
+ ReportExpiration inputValue)
+ {
+ return (Int32)inputValue;
+ }
+
+ #endregion
+
+ #region Report Correlation Id
+
+ /// <summary>
+ /// Converts an XMS "report correlation id." key.
+ /// </summary>
+ /// <param name="inputValue">Input value.</param>
+ /// <returns>Converted value.</returns>
+ public static ReportCorrelationId ToReportCorrelationId(
+ Int32 inputValue)
+ {
+ return (ReportCorrelationId)inputValue;
+ }
+
+ /// <summary>
+ /// Converts a "report correlation id." to the equivalent XMS value.
+ /// </summary>
+ /// <param name="inputValue">Input value.</param>
+ /// <returns>Converted value.</returns>
+ public static Int32 ToXMSReportCorrelationId(
+ ReportCorrelationId inputValue)
+ {
+ return (Int32)inputValue;
+ }
+
+ #endregion
+
+ #region Report Message Id
+
+ /// <summary>
+ /// Converts an XMS "report message id." key.
+ /// </summary>
+ /// <param name="inputValue">Input value.</param>
+ /// <returns>Converted value.</returns>
+ public static ReportMessageId ToReportMessageId(
+ Int32 inputValue)
+ {
+ return (ReportMessageId)inputValue;
+ }
+
+ /// <summary>
+ /// Converts a "report message id." to the equivalent XMS value.
+ /// </summary>
+ /// <param name="inputValue">Input value.</param>
+ /// <returns>Converted value.</returns>
+ public static Int32 ToXMSReportMessageId(
+ ReportMessageId inputValue)
+ {
+ return (Int32)inputValue;
+ }
+
+ #endregion
+
+ #region Asynchronous Exceptions
+
+ /// <summary>
+ /// Converts an XMS asynchronous exceptions handling directive key.
+ /// </summary>
+ /// <param name="inputValue">Input value.</param>
+ /// <returns>Converted value.</returns>
+ public static AsynchronousExceptions ToAsynchronousExceptions(
+ Int32 inputValue)
+ {
+ return (AsynchronousExceptions)inputValue;
+ }
+
+ /// <summary>
+ /// Converts an asynchronous exceptions handling directive to the
+ /// equivalent XMS value.
+ /// </summary>
+ /// <param name="inputValue">Input value.</param>
+ /// <returns>Converted value.</returns>
+ public static Int32 ToXMSAsynchronousExceptions(
+ AsynchronousExceptions inputValue)
+ {
+ return (Int32)inputValue;
+ }
+
+ #endregion
+
+ #region Connection Type
+
+ /// <summary>
+ /// Converts an XMS connection type key.
+ /// </summary>
+ /// <param name="inputValue">Input value.</param>
+ /// <returns>Converted value.</returns>
+ public static ConnectionType ToConnectionType(Int32 inputValue)
+ {
+ return (ConnectionType)inputValue;
+ }
+
+ /// <summary>
+ /// Converts a connection type to the equivalent XMS value.
+ /// </summary>
+ /// <param name="inputValue">Input value.</param>
+ /// <returns>Converted value.</returns>
+ public static Int32 ToXMSConnectionType(ConnectionType inputValue)
+ {
+ return (Int32)inputValue;
+ }
+
+ #endregion
+
+ #region Delivery Mode
+
+ /// <summary>
+ /// Converts an XMS delivery mode key.
+ /// </summary>
+ /// <param name="inputValue">Input value.</param>
+ /// <returns>Converted value.</returns>
+ public static DeliveryMode ToDeliveryMode(Int32 inputValue)
+ {
+ return (DeliveryMode)inputValue;
+ }
+
+ /// <summary>
+ /// Converts a delivery mode to the equivalent XMS value.
+ /// </summary>
+ /// <param name="inputValue">Input value.</param>
+ /// <returns>Converted value.</returns>
+ public static Int32 ToXMSDeliveryMode(DeliveryMode inputValue)
+ {
+ return (Int32)inputValue;
+ }
+
+ #endregion
+
+ #region Priority
+
+ /// <summary>
+ /// Converts an XMS priority key.
+ /// </summary>
+ /// <param name="inputValue">Input value.</param>
+ /// <returns>Converted value.</returns>
+ public static Priority ToPriority(Int32 inputValue)
+ {
+ return (Priority)inputValue;
+ }
+
+ /// <summary>
+ /// Converts a priority to the equivalent XMS value.
+ /// </summary>
+ /// <param name="inputValue">Input value.</param>
+ /// <returns>Converted value.</returns>
+ public static Int32 ToXMSPriority(Priority inputValue)
+ {
+ return (Int32)inputValue;
+ }
+
+ #endregion
+
+ #region Connection Protocol (RTT)
+
+ /// <summary>
+ /// Converts an RTT connection protocol key.
+ /// </summary>
+ /// <param name="inputValue">Input value.</param>
+ /// <returns>Converted value.</returns>
+ public static RTTConnectionProtocol ToRTTConnectionProtocol(
+ Int32 inputValue)
+ {
+ return (RTTConnectionProtocol)inputValue;
+ }
+
+ /// <summary>
+ /// Converts an RTT connection protocol to the equivalent XMS value.
+ /// </summary>
+ /// <param name="inputValue">Input value.</param>
+ /// <returns>Converted value.</returns>
+ public static Int32 ToXMSRTTConnectionProtocol(
+ RTTConnectionProtocol inputValue)
+ {
+ return (Int32)inputValue;
+ }
+
+ #endregion
+
+ #region Multicast (RTT)
+
+ /// <summary>
+ /// Converts an RTT multicast state key.
+ /// </summary>
+ /// <param name="inputValue">Input value.</param>
+ /// <returns>Converted value.</returns>
+ public static Multicast ToMulticast(Int32 inputValue)
+ {
+ return (Multicast)inputValue;
+ }
+
+ /// <summary>
+ /// Converts a multicast state to the equivalent XMS value.
+ /// </summary>
+ /// <param name="inputValue">Input value.</param>
+ /// <returns>Converted value.</returns>
+ public static Int32 ToXMSMulticast(Multicast inputValue)
+ {
+ return (Int32)inputValue;
+ }
+
+ #endregion
+
+ #region Broker Version (WMQ)
+
+ /// <summary>
+ /// Converts a WMQ broker version key.
+ /// </summary>
+ /// <param name="inputValue">Input value.</param>
+ /// <returns>Converted value.</returns>
+ public static BrokerVersion ToBrokerVersion(Int32 inputValue)
+ {
+ return (BrokerVersion)inputValue;
+ }
+
+ /// <summary>
+ /// Converts a broker version to the equivalent XMS value.
+ /// </summary>
+ /// <param name="inputValue">Input value.</param>
+ /// <returns>Converted value.</returns>
+ public static Int32 ToXMSBrokerVersion(BrokerVersion inputValue)
+ {
+ return (Int32)inputValue;
+ }
+
+ #endregion
+
+ #region Reconnect Options (WMQ)
+
+ /// <summary>
+ /// Converts a WMQ reconnect option key.
+ /// </summary>
+ /// <param name="inputValue">Input value.</param>
+ /// <returns>Converted value.</returns>
+ public static ReconnectOptions ToReconnectOptions(Int32 inputValue)
+ {
+ return (ReconnectOptions)inputValue;
+ }
+
+ /// <summary>
+ /// Converts a reconnect option to the equivalent XMS value.
+ /// </summary>
+ /// <param name="inputValue">Input value.</param>
+ /// <returns>Converted value.</returns>
+ public static Int32 ToXMSReconnectOptions(ReconnectOptions inputValue)
+ {
+ return (Int32)inputValue;
+ }
+
+ #endregion
+
+ #region Connection Mode (WMQ)
+
+ /// <summary>
+ /// Converts a WMQ connection mode key.
+ /// </summary>
+ /// <param name="inputValue">Input value.</param>
+ /// <returns>Converted value.</returns>
+ public static ConnectionMode ToConnectionMode(Int32 inputValue)
+ {
+ return (ConnectionMode)inputValue;
+ }
+
+ /// <summary>
+ /// Converts a connection mode to the equivalent XMS value.
+ /// </summary>
+ /// <param name="inputValue">Input value.</param>
+ /// <returns>Converted value.</returns>
+ public static Int32 ToXMSConnectionMode(ConnectionMode inputValue)
+ {
+ return (Int32)inputValue;
+ }
+
+ #endregion
+
+ #region Fail If Quiesce (WMQ)
+
+ /// <summary>
+ /// Converts a WMQ yes/no key to the equivalent boolean.
+ /// </summary>
+ /// <param name="inputValue">Input value.</param>
+ /// <returns>Converted value.</returns>
+ public static bool ToFailIfQuiesce(Int32 inputValue)
+ {
+ switch(inputValue)
+ {
+ case XMSC.WMQ_FIQ_YES: return true;
+ case XMSC.WMQ_FIQ_NO : return false;
+ default:
+ ThrowCantConvertValueException(inputValue, "ToFailIfQuiesce");
+ return false;
+
+ }
+ }
+
+ /// <summary>
+ /// Converts a WMQ boolean to the equivalent XMS yes/no value.
+ /// </summary>
+ /// <param name="inputValue">Input value.</param>
+ /// <returns>Converted value.</returns>
+ public static Int32 ToXMSFailIfQuiesce(bool inputValue)
+ {
+ return inputValue ? XMSC.WMQ_FIQ_YES : XMSC.WMQ_FIQ_NO;
+ }
+
+ #endregion
+
+ #region Message Body (WMQ)
+
+ /// <summary>
+ /// Converts a WMQ message body key.
+ /// </summary>
+ /// <param name="inputValue">Input value.</param>
+ /// <returns>Converted value.</returns>
+ public static MessageBody ToMessageBody(Int32 inputValue)
+ {
+ return (MessageBody)inputValue;
+ }
+
+ /// <summary>
+ /// Converts a message body to the equivalent XMS value.
+ /// </summary>
+ /// <param name="inputValue">Input value.</param>
+ /// <returns>Converted value.</returns>
+ public static Int32 ToXMSMessageBody(MessageBody inputValue)
+ {
+ return (Int32)inputValue;
+ }
+
+ #endregion
+
+ #region Message Context (WMQ)
+
+ /// <summary>
+ /// Converts a WMQ message context key.
+ /// </summary>
+ /// <param name="inputValue">Input value.</param>
+ /// <returns>Converted value.</returns>
+ public static MessageContext ToMessageContext(Int32 inputValue)
+ {
+ return (MessageContext)inputValue;
+ }
+
+ /// <summary>
+ /// Converts a message context to the equivalent XMS value.
+ /// </summary>
+ /// <param name="inputValue">Input value.</param>
+ /// <returns>Converted value.</returns>
+ public static Int32 ToXMSMessageContext(MessageContext inputValue)
+ {
+ return (Int32)inputValue;
+ }
+
+ #endregion
+
+ #region MQMD Read Enabled (WMQ)
+
+ /// <summary>
+ /// Converts a WMQ yes/no key to the equivalent boolean.
+ /// </summary>
+ /// <param name="inputValue">Input value.</param>
+ /// <returns>Converted value.</returns>
+ public static bool ToMQMDReadEnabled(Int32 inputValue)
+ {
+ return (inputValue != 0);
+ //switch(inputValue)
+ //{
+ //case XMSC.WMQ_READ_ENABLED_YES: return true;
+ //case XMSC.WMQ_READ_ENABLED_NO : return false;
+ //default:
+ // ThrowCantConvertValueException(inputValue, "ToMQMDReadEnabled");
+ // return false;
+ //}
+ }
+
+ /// <summary>
+ /// Converts a WMQ boolean to the equivalent XMS yes/no value.
+ /// </summary>
+ /// <param name="inputValue">Input value.</param>
+ /// <returns>Converted value.</returns>
+ public static Int32 ToXMSMQMDReadEnabled(bool inputValue)
+ {
+ return inputValue ? 1 : 0;
+ // XMSC.WMQ_READ_ENABLED_YES : XMSC.WMQ_READ_ENABLED_NO;
+ }
+
+ #endregion
+
+ #region MQMD Write Enabled (WMQ)
+
+ /// <summary>
+ /// Converts a WMQ yes/no key to the equivalent boolean.
+ /// </summary>
+ /// <param name="inputValue">Input value.</param>
+ /// <returns>Converted value.</returns>
+ public static bool ToMQMDWriteEnabled(Int32 inputValue)
+ {
+ return (inputValue != 0);
+ //switch(inputValue)
+ //{
+ //case XMSC.WMQ_WRITE_ENABLED_YES: return true;
+ //case XMSC.WMQ_WRITE_ENABLED_NO : return false;
+ //default:
+ // ThrowCantConvertValueException(inputValue, "ToMQMDWriteEnabled");
+ // return false;
+ //}
+ }
+
+ /// <summary>
+ /// Converts a WMQ boolean to the equivalent XMS yes/no value.
+ /// </summary>
+ /// <param name="inputValue">Input value.</param>
+ /// <returns>Converted value.</returns>
+ public static Int32 ToXMSMQMDWriteEnabled(bool inputValue)
+ {
+ return inputValue ? 1 : 0;
+ // XMSC.WMQ_WRITE_ENABLED_YES : XMSC.WMQ_WRITE_ENABLED_NO;
+ }
+
+ #endregion
+
+ #region Asynchronous Puts Allowed (WMQ)
+
+ /// <summary>
+ /// Converts a WMQ asynchronous puts allowed key.
+ /// </summary>
+ /// <param name="inputValue">Input value.</param>
+ /// <returns>Converted value.</returns>
+ public static AsynchronousPutsAllowed ToAsynchronousPutsAllowed(
+ Int32 inputValue)
+ {
+ return (AsynchronousPutsAllowed)inputValue;
+ }
+
+ /// <summary>
+ /// Converts a WMQ asynchronous puts allowed to the equivalent
+ /// XMS value.
+ /// </summary>
+ /// <param name="inputValue">Input value.</param>
+ /// <returns>Converted value.</returns>
+ public static Int32 ToXMSAsynchronousPutsAllowed(
+ AsynchronousPutsAllowed inputValue)
+ {
+ return (Int32)inputValue;
+ }
+
+ #endregion
+
+ #region Read Ahead Allowed (WMQ)
+
+ /// <summary>
+ /// Converts a WMQ read ahead allowed key.
+ /// </summary>
+ /// <param name="inputValue">Input value.</param>
+ /// <returns>Converted value.</returns>
+ public static ReadAheadAllowed ToReadAheadAllowed(
+ Int32 inputValue)
+ {
+ return (ReadAheadAllowed)inputValue;
+ }
+
+ /// <summary>
+ /// Converts a WMQ read ahead allowed to the equivalent
+ /// XMS value.
+ /// </summary>
+ /// <param name="inputValue">Input value.</param>
+ /// <returns>Converted value.</returns>
+ public static Int32 ToXMSReadAheadAllowed(
+ ReadAheadAllowed inputValue)
+ {
+ return (Int32)inputValue;
+ }
+
+ #endregion
+
+ #region Read Ahead Close Policy (WMQ)
+
+ /// <summary>
+ /// Converts a WMQ read ahead close policy key.
+ /// </summary>
+ /// <param name="inputValue">Input value.</param>
+ /// <returns>Converted value.</returns>
+ public static ReadAheadClosePolicy ToReadAheadClosePolicy(
+ Int32 inputValue)
+ {
+ return (ReadAheadClosePolicy)inputValue;
+ }
+
+ /// <summary>
+ /// Converts a WMQ read ahead close policy to the equivalent
+ /// XMS value.
+ /// </summary>
+ /// <param name="inputValue">Input value.</param>
+ /// <returns>Converted value.</returns>
+ public static Int32 ToXMSReadAheadClosePolicy(
+ ReadAheadClosePolicy inputValue)
+ {
+ return (Int32)inputValue;
+ }
+
+ #endregion
+
+ #region Message Selection (WMQ)
+
+ /// <summary>
+ /// Converts a WMQ message selection key.
+ /// </summary>
+ /// <param name="inputValue">Input value.</param>
+ /// <returns>Converted value.</returns>
+ public static MessageSelection ToMessageSelection(Int32 inputValue)
+ {
+ return (MessageSelection)inputValue;
+ }
+
+ /// <summary>
+ /// Converts a WMQ message selection to the equivalent XMS value.
+ /// </summary>
+ /// <param name="inputValue">Input value.</param>
+ /// <returns>Converted value.</returns>
+ public static Int32 ToXMSMessageSelection(MessageSelection inputValue)
+ {
+ return (Int32)inputValue;
+ }
+
+ #endregion
+
+ #region Receive Conversion (WMQ)
+
+ /// <summary>
+ /// Converts a WMQ receive conversion key.
+ /// </summary>
+ /// <param name="inputValue">Input value.</param>
+ /// <returns>Converted value.</returns>
+ public static ReceiveConversion ToReceiveConversion(Int32 inputValue)
+ {
+ return (ReceiveConversion)inputValue;
+ }
+
+ /// <summary>
+ /// Converts a WMQ receive conversion to the equivalent XMS value.
+ /// </summary>
+ /// <param name="inputValue">Input value.</param>
+ /// <returns>Converted value.</returns>
+ public static Int32 ToXMSReceiveConversion(ReceiveConversion inputValue)
+ {
+ return (Int32)inputValue;
+ }
+
+ #endregion
+
+ #region Share Socket Allowed (WMQ)
+
+ /// <summary>
+ /// Converts a WMQ yes/no key to the equivalent boolean.
+ /// </summary>
+ /// <param name="inputValue">Input value.</param>
+ /// <returns>Converted value.</returns>
+ public static bool ToShareSocketAllowed(Int32 inputValue)
+ {
+ switch(inputValue)
+ {
+ case XMSC.WMQ_SHARE_CONV_ALLOWED_YES: return true;
+ case XMSC.WMQ_SHARE_CONV_ALLOWED_NO : return false;
+ default:
+ ThrowCantConvertValueException(inputValue, "ShareSocketAllowed");
+ return false;
+ }
+ }
+
+ /// <summary>
+ /// Converts a WMQ boolean to the equivalent XMS yes/no value.
+ /// </summary>
+ /// <param name="inputValue">Input value.</param>
+ /// <returns>Converted value.</returns>
+ public static Int32 ToXMSShareSocketAllowed(bool inputValue)
+ {
+ return inputValue
+ ? XMSC.WMQ_SHARE_CONV_ALLOWED_YES
+ : XMSC.WMQ_SHARE_CONV_ALLOWED_NO;
+ }
+
+ #endregion
+
+ #region Target Client (WMQ)
+
+ /// <summary>
+ /// Converts a WMQ target client key.
+ /// </summary>
+ /// <param name="inputValue">Input value.</param>
+ /// <returns>Converted value.</returns>
+ public static TargetClient ToTargetClient(Int32 inputValue)
+ {
+ return (TargetClient)inputValue;
+ }
+
+ /// <summary>
+ /// Converts a WMQ target client to the equivalent XMS value.
+ /// </summary>
+ /// <param name="inputValue">Input value.</param>
+ /// <returns>Converted value.</returns>
+ public static Int32 ToXMSTargetClient(TargetClient inputValue)
+ {
+ return (Int32)inputValue;
+ }
+
+ #endregion
+
+ #region Wildcard Format (WMQ)
+
+ /// <summary>
+ /// Converts a WMQ wildcard format key.
+ /// </summary>
+ /// <param name="inputValue">Input value.</param>
+ /// <returns>Converted value.</returns>
+ public static WildcardFormat ToWildcardFormat(Int32 inputValue)
+ {
+ return (WildcardFormat)inputValue;
+ }
+
+ /// <summary>
+ /// Converts a WMQ wildcard format to the equivalent XMS value.
+ /// </summary>
+ /// <param name="inputValue">Input value.</param>
+ /// <returns>Converted value.</returns>
+ public static Int32 ToXMSWildcardFormat(WildcardFormat inputValue)
+ {
+ return (Int32)inputValue;
+ }
+
+ #endregion
+
+ #region Connection Protocol (WPM)
+
+ /// <summary>
+ /// Converts a WPM connection protocol key.
+ /// </summary>
+ /// <param name="inputValue">Input value.</param>
+ /// <returns>Converted value.</returns>
+ public static WPMConnectionProtocol ToWPMConnectionProtocol(
+ Int32 inputValue)
+ {
+ return (WPMConnectionProtocol)inputValue;
+ }
+
+ /// <summary>
+ /// Converts a WPM connection protocol to the equivalent XMS value.
+ /// </summary>
+ /// <param name="inputValue">Input value.</param>
+ /// <returns>Converted value.</returns>
+ public static Int32 ToXMSWPMConnectionProtocol(
+ WPMConnectionProtocol inputValue)
+ {
+ return (Int32)inputValue;
+ }
+
+ #endregion
+
+ #region Connection Proximity (WPM)
+
+ /// <summary>
+ /// Converts a WPM connection proximity key.
+ /// </summary>
+ /// <param name="inputValue">Input value.</param>
+ /// <returns>Converted value.</returns>
+ public static ConnectionProximity ToConnectionProximity(
+ Int32 inputValue)
+ {
+ return (ConnectionProximity)inputValue;
+ }
+
+ /// <summary>
+ /// Converts a WPM connection proximity to the equivalent XMS value.
+ /// </summary>
+ /// <param name="inputValue">Input value.</param>
+ /// <returns>Converted value.</returns>
+ public static Int32 ToXMSConnectionProximity(
+ ConnectionProximity inputValue)
+ {
+ return (Int32)inputValue;
+ }
+
+ #endregion
+
+ #region Mapping (WPM)
+
+ /// <summary>
+ /// Converts a WPM mapping key.
+ /// </summary>
+ /// <param name="inputValue">Input value.</param>
+ /// <returns>Converted value.</returns>
+ public static Mapping ToMapping(Int32 inputValue)
+ {
+ return (Mapping)inputValue;
+ }
+
+ /// <summary>
+ /// Converts a WPM mapping to the equivalent XMS value.
+ /// </summary>
+ /// <param name="inputValue">Input value.</param>
+ /// <returns>Converted value.</returns>
+ public static Int32 ToXMSMapping(Mapping inputValue)
+ {
+ return (Int32)inputValue;
+ }
+
+ #endregion
+
+ #region Target Significance (WPM)
+
+ /// <summary>
+ /// Converts a WPM target significance key.
+ /// </summary>
+ /// <param name="inputValue">Input value.</param>
+ /// <returns>Converted value.</returns>
+ public static TargetSignificance ToTargetSignificance(
+ Int32 inputValue)
+ {
+ return (TargetSignificance)inputValue;
+ }
+
+ /// <summary>
+ /// Converts a WPM target significance to the equivalent XMS value.
+ /// </summary>
+ /// <param name="inputValue">Input value.</param>
+ /// <returns>Converted value.</returns>
+ public static Int32 ToXMSTargetSignificance(
+ TargetSignificance inputValue)
+ {
+ return (Int32)inputValue;
+ }
+
+ #endregion
+
+ #region Target Type (WPM)
+
+ /// <summary>
+ /// Converts a WPM target type key.
+ /// </summary>
+ /// <param name="inputValue">Input value.</param>
+ /// <returns>Converted value.</returns>
+ public static TargetType ToTargetType(Int32 inputValue)
+ {
+ return (TargetType)inputValue;
+ }
+
+ /// <summary>
+ /// Converts a WPM target type to the equivalent XMS value.
+ /// </summary>
+ /// <param name="inputValue">Input value.</param>
+ /// <returns>Converted value.</returns>
+ public static Int32 ToXMSTargetType(TargetType inputValue)
+ {
+ return (Int32)inputValue;
+ }
+
+ #endregion
+
+ #endregion
+
+ #region IBM XMS to Apache NMS enumerations conversion
+
+ /// <summary>
+ /// Converts an IBM XMS destination type
+ /// to the equivalent NMS value.
+ /// </summary>
+ /// <param name="xmsDestinationType">XMS destination type.</param>
+ /// <param name="isTemporary">Whether the destination is temporary.
+ /// </param>
+ /// <returns>NMS destination type.</returns>
+ public static DestinationType ToDestinationType(
+ IBM.XMS.DestinationType xmsDestinationType, bool isTemporary)
+ {
+ switch(xmsDestinationType)
+ {
+ case IBM.XMS.DestinationType.Queue:
+ return(isTemporary
+ ? DestinationType.TemporaryQueue
+ : DestinationType.Queue);
+
+ case IBM.XMS.DestinationType.Topic:
+ return(isTemporary
+ ? DestinationType.TemporaryTopic
+ : DestinationType.Queue);
+
+ default:
+ ThrowCantConvertValueException(
+ xmsDestinationType.ToString(),
+ "ToDestinationType");
+ return DestinationType.Queue;
+ }
+ }
+
+ /// <summary>
+ /// Converts an IBM XMS acknowledgement mode
+ /// to the equivalent NMS value.
+ /// </summary>
+ /// <param name="acknowledgeMode">XMS acknowledgement mode.</param>
+ /// <returns>NMS acknowledgement mode.</returns>
+ public static Apache.NMS.AcknowledgementMode ToAcknowledgementMode(
+ IBM.XMS.AcknowledgeMode acknowledgeMode)
+ {
+ Apache.NMS.AcknowledgementMode acknowledge =
+ Apache.NMS.AcknowledgementMode.AutoAcknowledge;
+
+ switch(acknowledgeMode)
+ {
+ case IBM.XMS.AcknowledgeMode.AutoAcknowledge:
+ acknowledge = Apache.NMS.AcknowledgementMode.AutoAcknowledge;
+ break;
+
+ case IBM.XMS.AcknowledgeMode.ClientAcknowledge:
+ acknowledge = Apache.NMS.AcknowledgementMode.ClientAcknowledge;
+ break;
+
+ case IBM.XMS.AcknowledgeMode.DupsOkAcknowledge:
+ acknowledge = Apache.NMS.AcknowledgementMode.DupsOkAcknowledge;
+ break;
+
+ case IBM.XMS.AcknowledgeMode.SessionTransacted:
+ acknowledge = Apache.NMS.AcknowledgementMode.Transactional;
+ break;
+ }
+
+ return acknowledge;
+ }
+
+ /// <summary>
+ /// Converts an IBM XMS delivery mode
+ /// to the equivalent NMS value.
+ /// </summary>
+ /// <param name="deliveryMode">XMS delivery mode.</param>
+ /// <returns>NMS delivery mode.</returns>
+ public static MsgDeliveryMode ToNMSMsgDeliveryMode(
+ IBM.XMS.DeliveryMode deliveryMode)
+ {
+ if(deliveryMode == IBM.XMS.DeliveryMode.Persistent)
+ {
+ return MsgDeliveryMode.Persistent;
+ }
+
+ if(deliveryMode == IBM.XMS.DeliveryMode.NonPersistent)
+ {
+ return MsgDeliveryMode.NonPersistent;
+ }
+
+ // Hard cast it to the enumeration.
+ return (MsgDeliveryMode) deliveryMode;
+ }
+
+ #endregion
+
+ #region Apache NMS to IBM XMS enumerations conversion
+
+ /// <summary>
+ /// Converts an NMS acknowledgement mode
+ /// to the equivalent IBM XMS value.
+ /// </summary>
+ /// <param name="acknowledge">NMS acknowledgement mode.</param>
+ /// <returns>IBM XMS acknowledgement mode.</returns>
+ public static IBM.XMS.AcknowledgeMode ToAcknowledgeMode(
+ Apache.NMS.AcknowledgementMode acknowledge)
+ {
+ IBM.XMS.AcknowledgeMode acknowledgeMode =
+ (IBM.XMS.AcknowledgeMode)0;
+
+ switch(acknowledge)
+ {
+ case Apache.NMS.AcknowledgementMode.AutoAcknowledge:
+ acknowledgeMode = IBM.XMS.AcknowledgeMode.AutoAcknowledge;
+ break;
+
+ case Apache.NMS.AcknowledgementMode.ClientAcknowledge:
+ acknowledgeMode = IBM.XMS.AcknowledgeMode.ClientAcknowledge;
+ break;
+
+ case Apache.NMS.AcknowledgementMode.DupsOkAcknowledge:
+ acknowledgeMode = IBM.XMS.AcknowledgeMode.DupsOkAcknowledge;
+ break;
+
+ case Apache.NMS.AcknowledgementMode.Transactional:
+ acknowledgeMode = IBM.XMS.AcknowledgeMode.SessionTransacted;
+ break;
+ }
+
+ return acknowledgeMode;
+ }
+
+ /// <summary>
+ /// Converts an NMS delivery mode
+ /// to the equivalent IBM XMS value.
+ /// </summary>
+ /// <param name="deliveryMode">NMS delivery mode.</param>
+ /// <returns>IBM XMS delivery mode.</returns>
+ public static IBM.XMS.DeliveryMode ToJMSDeliveryMode(
+ MsgDeliveryMode deliveryMode)
+ {
+ if(deliveryMode == MsgDeliveryMode.Persistent)
+ {
+ return IBM.XMS.DeliveryMode.Persistent;
+ }
+
+ if(deliveryMode == MsgDeliveryMode.NonPersistent)
+ {
+ return IBM.XMS.DeliveryMode.NonPersistent;
+ }
+
+ // Hard cast it to the enumeration.
+ return (IBM.XMS.DeliveryMode) deliveryMode;
+ }
+
+ #endregion
+
+ #region Enumerable adapter
+
+ private class EnumerableAdapter : IEnumerable
+ {
+ private readonly IEnumerator enumerator;
+ public EnumerableAdapter(IEnumerator _enumerator)
+ {
+ this.enumerator = _enumerator;
+ }
+
+ public IEnumerator GetEnumerator()
+ {
+ return this.enumerator;
+ }
+ }
+
+ public static IEnumerable ToEnumerable(IEnumerator enumerator)
+ {
+ return new EnumerableAdapter(enumerator);
+ }
+
+ #endregion
+ }
+}
diff --git a/src/main/csharp/Util/XMSEnum.cs b/src/main/csharp/Util/XMSEnum.cs
new file mode 100644
index 0000000..6a95cef
--- /dev/null
+++ b/src/main/csharp/Util/XMSEnum.cs
@@ -0,0 +1,1167 @@
+/*
+ * 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.
+ */
+
+using System;
+using System.Collections;
+using IBM.XMS;
+
+namespace Apache.NMS.XMS.Util
+{
+
+#region Encoding (IBM JMS)*
+
+// http://www-01.ibm.com/support/knowledgecenter/SSFKSJ_8.0.0/com.ibm.mq.msc.doc/prp_jms_ibm_encoding.htm?lang=en
+/// <summary>
+/// How numerical data in the body of the message is represented when the XMS
+/// client forwards the message to its intended destination.
+/// </summary>
+public enum Encoding
+{
+ /// <summary>
+ /// Normal integer encoding.
+ /// </summary>
+ IntegerNormal = MQC.MQENC_INTEGER_NORMAL,
+
+ /// <summary>
+ /// Reversed integer encoding.
+ /// </summary>
+ IntegerReversed = MQC.MQENC_INTEGER_REVERSED,
+
+ /// <summary>
+ /// Normal packed decimal encoding.
+ /// </summary>
+ DecimalNormal = MQC.MQENC_DECIMAL_NORMAL,
+
+ /// <summary>
+ /// Reversed packed decimal encoding.
+ /// </summary>
+ DecimalReversed = MQC.MQENC_DECIMAL_REVERSED,
+
+ /// <summary>
+ /// Normal IEEE floating point encoding.
+ /// </summary>
+ FloatIEEENormal = MQC.MQENC_FLOAT_IEEE_NORMAL,
+
+ /// <summary>
+ /// Reversed IEEE floating point encoding.
+ /// </summary>
+ FloatIEEEReversed = MQC.MQENC_FLOAT_IEEE_REVERSED,
+
+ /// <summary>
+ /// z/OS® architecture floating point encoding.
+ /// </summary>
+ FloatS390 = MQC.MQENC_FLOAT_S390,
+
+ /// <summary>
+ /// Native machine encoding.
+ /// </summary>
+ Native = MQC.MQENC_NATIVE
+}
+
+#endregion
+
+#region Message Type (IBM JMS)
+
+// http://www-01.ibm.com/support/knowledgecenter/SSFKSJ_8.0.0/com.ibm.mq.msc.doc/prp_jms_ibm_msgtype.htm?lang=en
+/// <summary>
+/// Message type.
+/// </summary>
+public enum MessageType
+{
+ /// <summary>
+ /// The message is one that does not require a reply.
+ /// </summary>
+ Datagram = MQC.MQMT_DATAGRAM,
+
+ /// <summary>
+ /// The message is one that requires a reply.
+ /// </summary>
+ Request = MQC.MQMT_REQUEST,
+
+ /// <summary>
+ /// The message is a reply message.
+ /// </summary>
+ Reply = MQC.MQMT_REPLY,
+
+ /// <summary>
+ /// The message is a report message.
+ /// </summary>
+ Report = MQC.MQMT_REPORT
+}
+
+#endregion
+
+#region Report Confirm On Arrival (IBM JMS)
+
+// http://www-01.ibm.com/support/knowledgecenter/SSFKSJ_8.0.0/com.ibm.mq.msc.doc/prp_jms_ibm_rep_coa.htm?lang=en
+/// <summary>
+/// Request 'confirm on arrival' report messages, specifying how much
+/// application data from the original message must be included in a
+/// report message.
+/// </summary>
+public enum ReportConfirmOnArrival
+{
+ /// <summary>
+ /// Request 'confirm on arrival' report messages, with no application
+ /// data from the original message included in a report message.
+ /// </summary>
+ NoData = MQC.MQRO_COA,
+
+ /// <summary>
+ /// Request 'confirm on arrival' report messages, with the first 100 bytes
+ /// of application data from the original message included in a report
+ /// message.
+ /// </summary>
+ PartialData = MQC.MQRO_COA_WITH_DATA,
+
+ /// <summary>
+ /// Request 'confirm on arrival' report messages, with all the application
+ /// data from the original message included in a report message.
+ /// </summary>
+ FullData = MQC.MQRO_COA_WITH_FULL_DATA
+}
+
+#endregion
+
+#region Report Confirm On Delivery (IBM JMS)
+
+// http://www-01.ibm.com/support/knowledgecenter/SSFKSJ_8.0.0/com.ibm.mq.msc.doc/prp_jms_ibm_rep_cod.htm?lang=en
+/// <summary>
+/// Request 'confirm on delivery' report messages, specifying how much
+/// application data from the original message must be included in a
+/// report message.
+/// </summary>
+public enum ReportConfirmOnDelivery
+{
+ /// <summary>
+ /// Request 'confirm on delivery' report messages, with no application
+ /// data from the original message included in a report message.
+ /// </summary>
+ NoData = MQC.MQRO_COD,
+
+ /// <summary>
+ /// Request 'confirm on delivery' report messages, with the first 100 bytes
+ /// of application data from the original message included in a report
+ /// message.
+ /// </summary>
+ PartialData = MQC.MQRO_COD_WITH_DATA,
+
+ /// <summary>
+ /// Request 'confirm on delivery' report messages, with all the application
+ /// data from the original message included in a report message.
+ /// </summary>
+ FullData = MQC.MQRO_COD_WITH_FULL_DATA
+}
+
+#endregion
+
+#region Report Exception (IBM JMS)
+
+// http://www-01.ibm.com/support/knowledgecenter/SSFKSJ_8.0.0/com.ibm.mq.msc.doc/prp_jms_ibm_rep_excpt.htm?lang=en
+/// <summary>
+/// Request exception report messages, specifying how much application data
+/// from the original message must be included in a report message.
+/// </summary>
+public enum ReportExceptions
+{
+ /// <summary>
+ /// Request exception report messages, with no application data from the
+ /// original message included in a report message.
+ /// </summary>
+ NoData = MQC.MQRO_COD,
+
+ /// <summary>
+ /// Request exception report messages, with the first 100 bytes of
+ /// application data from the original message included in a report
+ /// message.
+ /// </summary>
+ PartialData = MQC.MQRO_COD_WITH_DATA,
+
+ /// <summary>
+ /// Request exception report messages, with all the application data from
+ /// the original message included in a report message.
+ /// </summary>
+ FullData = MQC.MQRO_COD_WITH_FULL_DATA
+}
+
+#endregion
+
+#region Report Expiration (IBM JMS)
+
+// http://www-01.ibm.com/support/knowledgecenter/SSFKSJ_8.0.0/com.ibm.mq.msc.doc/prp_jms_ibm_rep_exprn.htm?lang=en
+/// <summary>
+/// Request expiration report messages, specifying how much application data
+/// from the original message must be included in a report message.
+/// </summary>
+public enum ReportExpiration
+{
+ /// <summary>
+ /// Request expiration report messages, with no application data from the
+ /// original message included in a report message.
+ /// </summary>
+ NoData = MQC.MQRO_EXPIRATION,
+
+ /// <summary>
+ /// Request expiration report messages, with the first 100 bytes of
+ /// application data from the original message included in a report
+ /// message.
+ /// </summary>
+ PartialData = MQC.MQRO_EXPIRATION_WITH_DATA,
+
+ /// <summary>
+ /// Request expiration report messages, with all the application data from
+ /// the original message included in a report message.
+ /// </summary>
+ FullData = MQC.MQRO_EXPIRATION_WITH_FULL_DATA
+}
+
+#endregion
+
+#region Report Correlation Id (IBM JMS)
+
+// http://www-01.ibm.com/support/knowledgecenter/SSFKSJ_8.0.0/com.ibm.mq.msc.doc/prp_jms_ibm_rep_pcid.htm?lang=en
+/// <summary>
+/// Request that the correlation identifier of any report or reply message
+/// is the same as the correlation identifier of the original message.
+/// </summary>
+public enum ReportCorrelationId
+{
+ /// <summary>
+ /// Request that the correlation identifier of any report or reply message
+ /// is the same as the correlation identifier of the original message.
+ /// </summary>
+ OriginalCorrelationId = MQC.MQRO_PASS_CORREL_ID,
+
+ /// <summary>
+ /// Request that the correlation identifier of any report or reply message
+ /// is the same as the message identifier of the original message.
+ /// </summary>
+ OriginalMessageId = MQC.MQRO_COPY_MSG_ID_TO_CORREL_ID
+}
+
+#endregion
+
+#region Report Message Id (IBM JMS)
+
+// http://www-01.ibm.com/support/knowledgecenter/SSFKSJ_8.0.0/com.ibm.mq.msc.doc/prp_jms_ibm_rep_pmid.htm?lang=en
+/// <summary>
+/// Request that the message identifier of any report or reply message is the
+/// same as the message identifier of the original message.
+/// </summary>
+public enum ReportMessageId
+{
+ /// <summary>
+ /// Request that the message identifier of any report or reply message is the same as the message identifier of the original message.
+ /// </summary>
+ OriginalMessageId = MQC.MQRO_PASS_MSG_ID,
+
+ /// <summary>
+ /// Request that a new message identifier is generated for each report or
+ /// reply message.
+ /// </summary>
+ NewMessageId = MQC.MQRO_NEW_MSG_ID
+}
+
+#endregion
+
+#region Asynchronous Exceptions
+
+// http://www-01.ibm.com/support/knowledgecenter/SSFKSJ_8.0.0/com.ibm.mq.msc.doc/xmsc_async_exceptions.htm?lang=en
+/// <summary>
+/// whether XMS informs an ExceptionListener only when a connection is broken,
+/// or when any exception occurs asynchronously to an XMS API call.
+/// </summary>
+public enum AsynchronousExceptions
+{
+ /// <summary>
+ /// Any exception detected asynchronously, outside the scope of a
+ /// synchronous API call, and all connection broken exceptions are sent
+ /// to the <c>ExceptionListener</c>.
+ /// </summary>
+ All = XMSC.ASYNC_EXCEPTIONS_ALL,
+
+ /// <summary>
+ /// Only exceptions indicating a broken connection are sent to the
+ /// <c>ExceptionListener</c>. Any other exceptions occurring during
+ /// asynchronous processing are not reported to the
+ /// <c>ExceptionListener</c>, and hence the application is not informed
+ /// of these exceptions.
+ /// </summary>
+ ConnectionBroken = XMSC.ASYNC_EXCEPTIONS_CONNECTIONBROKEN
+}
+
+#endregion
+
+#region Connection Type
+
+// http://www-01.ibm.com/support/knowledgecenter/SSFKSJ_8.0.0/com.ibm.mq.msc.doc/prx_connection_type.htm?lang=en
+/// <summary>
+/// The type of messaging server to which an application connects.
+/// </summary>
+public enum ConnectionType
+{
+ /// <summary>
+ /// A real-time connection to a broker.
+ /// </summary>
+ RTT = XMSC.CT_RTT,
+
+ /// <summary>
+ /// A connection to a WebSphere® MQ queue manager.
+ /// </summary>
+ WMQ = XMSC.CT_WMQ,
+
+ /// <summary>
+ /// A connection to a WebSphere service integration bus.
+ /// </summary>
+ WPM = XMSC.CT_WPM
+}
+
+#endregion
+
+#region Delivery Mode
+
+/// <summary>
+/// The delivery mode of messages sent to the destination.
+/// </summary>
+public enum DeliveryMode
+{
+ /// <summary>
+ /// A message sent to the destination is nonpersistent. The default
+ /// delivery mode of the message producer, or any delivery mode specified
+ /// on the Send call, is ignored. If the destination is a WebSphere MQ
+ /// queue, the value of the queue attribute <c>DefPersistence</c> is also
+ /// ignored.
+ /// </summary>
+ NotPersistent = XMSC.DELIVERY_NOT_PERSISTENT,
+
+ /// <summary>
+ /// A message sent to the destination is persistent. The default
+ /// delivery mode of the message producer, or any delivery mode specified
+ /// on the Send call, is ignored. If the destination is a WebSphere MQ
+ /// queue, the value of the queue attribute <c>DefPersistence</c> is also
+ /// ignored.
+ /// </summary>
+ Persistent = XMSC.DELIVERY_PERSISTENT,
+
+ /// <summary>
+ /// A message sent to the destination has the delivery mode specified on
+ /// the Send call. If the Send call specifies no delivery mode, the default
+ /// delivery mode of the message producer is used instead. If the
+ /// destination is a WebSphere MQ queue, the value of the queue attribute
+ /// <c>DefPersistence</c> is ignored.
+ /// </summary>
+ AsApplication = XMSC.DELIVERY_AS_APP,
+
+ /// <summary>
+ /// If the destination is a WebSphere MQ queue, a message put on the queue
+ /// has the delivery mode specified by the value of the queue attribute
+ /// <c>DefPersistence</c>. The default delivery mode of the message
+ /// producer, or any delivery mode specified on the Send call, is ignored.
+ /// </summary>
+ AsDestination = XMSC.DELIVERY_AS_DEST
+}
+
+#endregion
+
+#region Priority
+
+// http://www-01.ibm.com/support/knowledgecenter/SSFKSJ_8.0.0/com.ibm.mq.msc.doc/prx_priority.htm?lang=en
+/// <summary>
+/// The priority of messages sent to the destination.
+/// </summary>
+public enum Priority
+{
+ /// <summary>
+ /// Lowest message priority.
+ /// </summary>
+ Lowest = 0,
+
+ /// <summary>
+ /// Between Low and Lowest message priority.
+ /// </summary>
+ VeryLow = 1,
+
+ /// <summary>
+ /// Low message priority.
+ /// </summary>
+ Low = 2,
+
+ /// <summary>
+ /// Normal message priority.
+ /// </summary>
+ Normal = 5,
+
+ /// <summary>
+ /// Between High and Normal message priority.
+ /// </summary>
+ AboveNormal = 6,
+
+ /// <summary>
+ /// High message priority.
+ /// </summary>
+ High = 7,
+
+ /// <summary>
+ /// Between Highest and High message priority.
+ /// </summary>
+ VeryHigh = 8,
+
+ /// <summary>
+ /// Highest message priority.
+ /// </summary>
+ Highest = 9,
+
+ /// <summary>
+ /// A message sent to the destination has the priority specified on the
+ /// Send call. If the Send call specifies no priority, the default
+ /// priority of the message producer is used instead. If the destination
+ /// is a WebSphere MQ queue, the value of the queue attribute
+ /// <c>DefPriority</c> is ignored.
+ /// </summary>
+ AsApplication = XMSC.PRIORITY_AS_APP,
+
+ /// <summary>
+ /// If the destination is a WebSphere MQ queue, a message put on the
+ /// queue has the priority specified by the value of the queue attribute
+ /// <c>DefPriority</c>. The default priority of the message producer,
+ /// or any priority specified on the Send call, is ignored.
+ /// </summary>
+ AsDestination = XMSC.PRIORITY_AS_DEST
+}
+
+#endregion
+
+#region Connection Protocol (RTT)
+
+// http://www-01.ibm.com/support/knowledgecenter/SSFKSJ_8.0.0/com.ibm.mq.msc.doc/prx_rtt_conn_prot.htm?lang=en
+/// <summary>
+/// The communications protocol used for a real-time connection to a broker.
+/// </summary>
+public enum RTTConnectionProtocol
+{
+ /// <summary>
+ /// Real-time connection to a broker over TCP/IP.
+ /// <c>ConnectionFactory</c> object.
+ /// </summary>
+ TCP = XMSC.RTT_CP_TCP
+}
+
+#endregion
+
+#region Multicast (RTT)
+
+// http://www-01.ibm.com/support/knowledgecenter/SSFKSJ_8.0.0/com.ibm.mq.msc.doc/prx_rtt_multicast.htm?lang=en
+/// <summary>
+/// The multicast setting for a connection factory or destination. Only a
+/// destination that is a topic can have this property.
+/// An application uses this property to enable multicast in association with
+/// a real-time connection to a broker and, if multicast is enabled, to
+/// specify the precise way in which multicast is used to deliver messages
+/// from the broker to a message consumer. The property has no effect on how
+/// a message producer sends messages to the broker.
+/// </summary>
+public enum Multicast
+{
+ /// <summary>
+ /// Messages are not delivered to a message consumer using WebSphere® MQ
+ /// Multicast Transport. This value is the default value for a
+ /// <c>ConnectionFactory</c> object.
+ /// </summary>
+ Disabled = XMSC.RTT_MULTICAST_DISABLED,
+
+ /// <summary>
+ /// Messages are delivered to a message consumer according to the multicast
+ /// setting for the connection factory associated with the message consumer.
+ /// The multicast setting for the connection factory is noted at the time
+ /// that the connection is created. This value is valid only for a
+ /// <c>Destination</c> object, and is the default value for a
+ /// <c>Destination</c> object.
+ /// </summary>
+ AsConnectionFactory = XMSC.RTT_MULTICAST_ASCF,
+
+ /// <summary>
+ /// If the topic is configured for multicast in the broker, messages are
+ /// delivered to a message consumer using WebSphere MQ Multicast Transport.
+ /// A reliable quality of service is used if the topic is configured for
+ /// reliable multicast.
+ /// </summary>
+ Enabled = XMSC.RTT_MULTICAST_ENABLED,
+
+ /// <summary>
+ /// If the topic is configured for reliable multicast in the broker,
+ /// messages are delivered to a message consumer using WebSphere MQ
+ /// Multicast Transport with a reliable quality of service. If the topic
+ /// is not configured for reliable multicast, you cannot create a message
+ /// consumer for the topic.
+ /// </summary>
+ Reliable = XMSC.RTT_MULTICAST_RELIABLE,
+
+ /// <summary>
+ /// If the topic is configured for multicast in the broker, messages are
+ /// delivered to a message consumer using WebSphere MQ Multicast Transport.
+ /// A reliable quality of service is not used even if the topic is
+ /// configured for reliable multicast.
+ /// </summary>
+ NotReliable = XMSC.RTT_MULTICAST_NOT_RELIABLE
+}
+
+#endregion
+
+#region Broker Version (WMQ)
+
+// http://www-01.ibm.com/support/knowledgecenter/SSFKSJ_8.0.0/com.ibm.mq.msc.doc/prx_wmq_brkr_version.htm?lang=en
+/// <summary>
+/// The type of broker used by the application for a connection or for the
+/// destination. Only a destination that is a topic can have this property.
+/// </summary>
+public enum BrokerVersion
+{
+ /// <summary>
+ /// The application is using a WebSphere® MQ Publish/Subscribe broker.
+ /// </summary>
+ Version1 = XMSC.WMQ_BROKER_V1,
+
+ /// <summary>
+ /// The application is using a broker of IBM® Integration Bus.
+ /// </summary>
+ Version2 = XMSC.WMQ_BROKER_V2,
+
+ /// <summary>
+ /// After the broker is migrated, set this property so that RFH2 headers
+ /// are no longer used. After migration, this property is no longer
+ /// relevant.
+ /// </summary>
+ Unspecified = XMSC.WMQ_BROKER_UNSPECIFIED
+}
+
+#endregion
+
+#region Reconnect Options (WMQ)
+
+// http://www-01.ibm.com/support/knowledgecenter/SSFKSJ_8.0.0/com.ibm.mq.msc.doc/prx_rtt_client_reconnect_options.htm?lang=en
+/// <summary>
+/// Client reconnect options for new connections created by a factory.
+/// </summary>
+public enum ReconnectOptions
+{
+ /// <summary>
+ /// Use the value specified in the <c>mqclient.ini</c> file. Set the value
+ /// by using the DefRecon property within the Channels stanza.
+ /// </summary>
+ AsDefault = XMSC.WMQ_CLIENT_RECONNECT_AS_DEF,
+
+ /// <summary>
+ /// Reconnect to any of the queue managers specified in the connection name
+ /// list.
+ /// </summary>
+ AnyQueueManager = XMSC.WMQ_CLIENT_RECONNECT,
+
+ /// <summary>
+ /// Reconnects to the same queue manager that it is originally connected to.
+ /// It returns <c>MQRC.RECONNECT_QMID_MISMATCH</c> if the queue manager it
+ /// tries to connect to (specified in the connection name list) has a
+ /// different QMID to the queue manager originally connected to.
+ /// </summary>
+ SameQueueManager = XMSC.WMQ_CLIENT_RECONNECT_Q_MGR,
+
+ /// <summary>
+ /// Reconnection is disabled.
+ /// </summary>
+ Disabled = XMSC.WMQ_CLIENT_RECONNECT_DISABLED
+}
+
+#endregion
+
+#region Connection Mode (WMQ)
+
+// http://www-01.ibm.com/support/knowledgecenter/SSFKSJ_8.0.0/com.ibm.mq.msc.doc/prx_wmq_conn_mode.htm?lang=en
+/// <summary>
+/// The mode by which an application connects to a queue manager.
+/// </summary>
+public enum ConnectionMode
+{
+ /// <summary>
+ /// A connection to a queue manager in bindings mode, for optimal performance. This value is the default value for C/C++.
+ /// </summary>
+ Bindings = XMSC.WMQ_CM_BINDINGS,
+
+ /// <summary>
+ /// A connection to a queue manager in client mode, to ensure a fully managed stack. This value is the default value for .NET.
+ /// </summary>
+ Client = XMSC.WMQ_CM_CLIENT,
+
+ /// <summary>
+ /// A connection to a queue manager which forces an unmanaged client stack.
+ /// </summary>
+ ClientUnmanaged = XMSC.WMQ_CM_CLIENT_UNMANAGED
+}
+
+#endregion
+
+#region Encoding (WMQ)
+
+// http://www-01.ibm.com/support/knowledgecenter/SSFKSJ_8.0.0/com.ibm.mq.msc.doc/prx_wmq_encoding.htm?lang=en
+// cf. "Encoding (IBM JMS)"
+
+#endregion
+
+#region Fail If Quiesce (WMQ)
+
+// http://www-01.ibm.com/support/knowledgecenter/SSFKSJ_8.0.0/com.ibm.mq.msc.doc/prx_wmq_fail_if_quiesce.htm?lang=en
+/// <summary>
+/// Whether calls to certain methods fail if the queue manager to which the
+/// application is connected is in a quiescing state.
+/// </summary>
+public enum FailIfQuiesce
+{
+ /// <summary>
+ /// Calls to certain methods fail if the queue manager is in a quiescing
+ /// state. When the application detects that the queue manager is
+ /// quiescing, the application can complete its immediate task and close
+ /// the connection, allowing the queue manager to stop.
+ /// </summary>
+ Yes = XMSC.WMQ_FIQ_YES,
+
+ /// <summary>
+ /// No method calls fail because the queue manager is in a quiescing
+ /// state. If you specify this value, the application cannot detect that
+ /// the queue manager is quiescing. The application might continue to
+ /// perform operations against the queue manager and therefore prevent
+ /// the queue manager from stopping.
+ /// </summary>
+ No = XMSC.WMQ_FIQ_NO
+}
+
+#endregion
+
+#region Message Body (WMQ)
+
+// http://www-01.ibm.com/support/knowledgecenter/SSFKSJ_8.0.0/com.ibm.mq.msc.doc/xmsc_wmq_message_body.htm?lang=en
+/// <summary>
+/// Whether an XMS application processes the <c>MQRFH2</c> of a WebSphere®
+/// MQ message as part of the message payload (that is, as part of the
+/// message body).
+/// </summary>
+public enum MessageBody
+{
+ /// <summary>
+ /// Receive: The inbound XMS message type and body are determined by the
+ /// contents of the <c>MQRFH2</c> (if present) or the <c>MQMD</c> (if there
+ /// is no <c>MQRFH2</c>) in the received WebSphere MQ message.
+ /// Send: The outbound XMS message body contains a prepended and
+ /// auto-generated <c>MQRFH2</c> header based on XMS Message properties and
+ /// header fields.
+ /// </summary>
+ JMS = XMSC.WMQ_MESSAGE_BODY_JMS,
+
+ /// <summary>
+ /// Receive: The inbound XMS message type is always <c>ByteMessage</c>,
+ /// irrespective of the contents of received WebSphere MQ message or the
+ /// format field of the received <c>MQMD</c>. The XMS message body is the
+ /// unaltered message data returned by the underlying messaging provider
+ /// API call. The character set and encoding of the data in the message
+ /// body is determined by the <c>CodedCharSetId</c> and <c>Encoding</c>
+ /// fields of the <c>MQMD</c>. The format of the data in the message body
+ /// is determined by the <c>Format</c> field of the <c>MQMD</c>.
+ /// Send: The outbound XMS message body contains the application payload
+ /// as-is; and no auto-generated WebSphere MQ header is added to the body.
+ /// </summary>
+ MQ = XMSC.WMQ_MESSAGE_BODY_MQ,
+
+ /// <summary>
+ /// Receive: The XMS client determines a suitable value for this property.
+ /// On receive path, this value is the <c>WMQ_MESSAGE_BODY_JMS</c> property
+ /// value.
+ /// Send: The XMS client determines a suitable value for this property. On
+ /// send path, this value is the <c>XMSC_WMQ_TARGET_CLIENT</c> property
+ /// value.
+ /// </summary>
+ Unspecified = XMSC.WMQ_MESSAGE_BODY_UNSPECIFIED
+}
+
+#endregion
+
+#region Message Context (WMQ)
+
+// http://www-01.ibm.com/support/knowledgecenter/SSFKSJ_8.0.0/com.ibm.mq.msc.doc/xmsc_wmq_mqmd_message_context.htm?lang=en
+/// <summary>
+/// Determines what level of message context is to be set by the XMS
+/// application. The application must be running with appropriate context
+/// authority for this property to take effect.
+/// </summary>
+public enum MessageContext
+{
+ /// <summary>
+ /// For outbound messages, the <c>MQOPEN</c> API call and the <c>MQPMO</c>
+ /// structure specifies no explicit message context options.
+ /// </summary>
+ Default = XMSC.WMQ_MDCTX_DEFAULT,
+
+ /// <summary>
+ /// The <c>MQOPEN</c> API call specifies the message context option
+ /// <c>MQOO_SET_IDENTITY_CONTEXT</c> and the <c>MQPMO</c> structure
+ /// specifies <c>MQPMO_SET_IDENTITY_CONTEXT</c>.
+ /// </summary>
+ SetIdentity = XMSC.WMQ_MDCTX_SET_IDENTITY_CONTEXT,
+
+ /// <summary>
+ /// The <c>MQOPEN</c> API call specifies the message context option
+ /// <c>MQOO_SET_ALL_CONTEXT</c> and the <c>MQPMO</c> structure
+ /// specifies <c>MQPMO_SET_ALL_CONTEXT</c>.
+ /// </summary>
+ SetAll = XMSC.WMQ_MDCTX_SET_ALL_CONTEXT,
+}
+
+#endregion
+
+#region MQMD Read Enabled (WMQ)
+
+// http://www-01.ibm.com/support/knowledgecenter/SSFKSJ_8.0.0/com.ibm.mq.msc.doc/xmsc_wmq_mqmd_read_enabled.htm?lang=en
+/// <summary>
+/// Whether an XMS application can extract the values of MQMD fields or not.
+/// </summary>
+public enum MQMDReadEnabled
+{
+ /// <summary>
+ /// When sending messages, the <c>JMS_IBM_MQMD*</c> properties on a sent
+ /// message are not updated to reflect the updated field values in the
+ /// <c>MQMD</c>.
+ /// When receiving messages, none of the <c>JMS_IBM_MQMD*</c> properties
+ /// are available on a received message, even if some or all of them are
+ /// set by the sender.
+ /// </summary>
+ No = 0, //XMSC.WMQ_READ_ENABLED_NO,
+
+ /// <summary>
+ /// When sending messages, all of the <c>JMS_IBM_MQMD*</c> properties on
+ /// a sent message are updated to reflect the updated field values in the
+ /// <c>MQMD</c>, including those properties that the sender did not set
+ /// explicitly.
+ /// When receiving messages, all of the <c>JMS_IBM_MQMD*</c> properties
+ /// are available on a received message, including those properties that
+ /// the sender did not set explicitly.
+ /// </summary>
+ Yes = 1 //XMSC.WMQ_READ_ENABLED_YES
+}
+
+#endregion
+
+#region MQMD Write Enabled (WMQ)
+
+// http://www-01.ibm.com/support/knowledgecenter/SSFKSJ_8.0.0/com.ibm.mq.msc.doc/xmsc_wmq_mqmd_write_enabled.htm?lang=en
+/// <summary>
+/// Whether an XMS application can write the values of MQMD fields or not.
+/// </summary>
+public enum MQMDWriteEnabled
+{
+ /// <summary>
+ /// All <c>JMS_IBM_MQMD*</c> properties are ignored and their values are
+ /// not copied into the underlying <c>MQMD</c> structure.
+ /// </summary>
+ No = 0, //XMSC.WMQ_WRITE_ENABLED_NO,
+
+ /// <summary>
+ /// <c>JMS_IBM_MQMD*</c> properties are processed. Their values are copied
+ /// into the underlying <c>MQMD</c> structure.
+ /// </summary>
+ Yes = 1 //XMSC.WMQ_WRITE_ENABLED_YES
+}
+
+#endregion
+
+#region Asynchronous Puts Allowed (WMQ)
+
+// http://www-01.ibm.com/support/knowledgecenter/SSFKSJ_8.0.0/com.ibm.mq.msc.doc/xmsc_wmq_put_async_allowed.htm?lang=en
+/// <summary>
+/// Whether message producers are allowed to use asynchronous puts to send
+/// messages to this destination.
+/// </summary>
+public enum AsynchronousPutsAllowed
+{
+ /// <summary>
+ /// Determine whether asynchronous puts are allowed by referring to the
+ /// queue or topic definition.
+ /// </summary>
+ AsDestination = XMSC.WMQ_PUT_ASYNC_ALLOWED_AS_DEST,
+
+ /// <summary>
+ /// Determine whether asynchronous puts are allowed by referring to the
+ /// queue definition.
+ /// </summary>
+ AsQueueDefinition = XMSC.WMQ_PUT_ASYNC_ALLOWED_AS_Q_DEF,
+
+ /// <summary>
+ /// Determine whether asynchronous puts are allowed by referring to the
+ /// topic definition.
+ /// </summary>
+ AsTopicDefinition = XMSC.WMQ_PUT_ASYNC_ALLOWED_AS_TOPIC_DEF,
+
+ /// <summary>
+ /// Asynchronous puts are not allowed.
+ /// </summary>
+ Disabled = XMSC.WMQ_PUT_ASYNC_ALLOWED_DISABLED,
+
+ /// <summary>
+ /// Asynchronous puts are allowed.
+ /// </summary>
+ Enabled = XMSC.WMQ_PUT_ASYNC_ALLOWED_ENABLED
+}
+
+#endregion
+
+#region Read Ahead Allowed (WMQ)
+
+// http://www-01.ibm.com/support/knowledgecenter/SSFKSJ_8.0.0/com.ibm.mq.msc.doc/xmsc_wmq_read_ahead_allowed.htm?lang=en
+/// <summary>
+/// Whether message consumers and queue browsers are allowed to use read ahead
+/// to get non-persistent, non-transactional messages from this destination
+/// into an internal buffer before receiving them.
+/// </summary>
+public enum ReadAheadAllowed
+{
+ /// <summary>
+ /// Determine whether read ahead is allowed by referring to the queue
+ /// definition.
+ /// </summary>
+ AsQueueDefinition = XMSC.WMQ_READ_AHEAD_ALLOWED_AS_Q_DEF,
+
+ /// <summary>
+ /// Determine whether read ahead is allowed by referring to the topic
+ /// definition.
+ /// </summary>
+ AsTopicDefinition = XMSC.WMQ_READ_AHEAD_ALLOWED_AS_TOPIC_DEF,
+
+ /// <summary>
+ /// Determine whether read ahead is allowed by referring to the queue
+ /// or topic definition.
+ /// </summary>
+ AsDestinationDefinition = XMSC.WMQ_READ_AHEAD_ALLOWED_AS_DEST,
+
+ /// <summary>
+ /// Read ahead is not allowed while consuming or browsing messages.
+ /// </summary>
+ Disabled = XMSC.WMQ_READ_AHEAD_ALLOWED_DISABLED,
+
+ /// <summary>
+ /// Read ahead is allowed.
+ /// </summary>
+ Enabled = XMSC.WMQ_READ_AHEAD_ALLOWED_ENABLED
+}
+
+#endregion
+
+#region Read Ahead Close Policy (WMQ)
+
+// http://www-01.ibm.com/support/knowledgecenter/SSFKSJ_8.0.0/com.ibm.mq.msc.doc/xmsc_wmq_read_ahead_close_policy.htm?lang=en
+/// <summary>
+/// This property determines, for messages being delivered to an asynchronous
+/// message listener, what happens to messages in the internal read ahead buffer
+/// when the message consumer is closed.
+/// </summary>
+public enum ReadAheadClosePolicy
+{
+ /// <summary>
+ /// Only the current message listener invocation completes before returning,
+ /// potentially leaving messages in the internal read ahead buffer, which
+ /// are then discarded.
+ /// </summary>
+ DeliverCurrent = XMSC.WMQ_READ_AHEAD_DELIVERCURRENT,
+
+ /// <summary>
+ /// All messages in the internal read ahead buffer are delivered to the
+ /// application message listener before returning.
+ /// </summary>
+ DeliverAll = XMSC.WMQ_READ_AHEAD_DELIVERALL
+}
+
+#endregion
+
+#region Message Selection (WMQ)
+
+// http://www-01.ibm.com/support/knowledgecenter/SSFKSJ_8.0.0/com.ibm.mq.msc.doc/prx_wmq_mes_selection.htm?lang=en
+/// <summary>
+/// Determines whether message selection is done by the XMS client or by
+/// the broker.
+/// </summary>
+public enum MessageSelection
+{
+ /// <summary>
+ /// Message selection is done by the XMS client.
+ /// </summary>
+ Client = XMSC.WMQ_MSEL_CLIENT,
+
+ /// <summary>
+ /// Message selection is done by the broker.
+ /// </summary>
+ Broker = XMSC.WMQ_MSEL_BROKER
+}
+
+#endregion
+
+#region Receive Conversion (WMQ)
+
+// http://www-01.ibm.com/support/knowledgecenter/SSFKSJ_8.0.0/com.ibm.mq.msc.doc/xmsc_wmq_receive_conversion.htm?lang=en
+/// <summary>
+/// Whether data conversion is going to be performed by the queue manager.
+/// </summary>
+public enum ReceiveConversion
+{
+ /// <summary>
+ /// Perform data conversion on the XMS client only. Conversion is always
+ /// done using codepage 1208.
+ /// </summary>
+ Client = XMSC.WMQ_RECEIVE_CONVERSION_CLIENT_MSG,
+
+ /// <summary>
+ /// Perform data conversion on the queue manager before sending a message
+ /// to the XMS client.
+ /// </summary>
+ QueueManager = XMSC.WMQ_RECEIVE_CONVERSION_QMGR
+}
+
+#endregion
+
+#region Share Socket Allowed (WMQ)
+
+// http://www-01.ibm.com/support/knowledgecenter/SSFKSJ_8.0.0/com.ibm.mq.msc.doc/xmsc_wmq_share_conv_allowed.htm?lang=en
+/// <summary>
+/// Whether a client connection can share its socket with other top-level XMS
+/// connections from the same process to the same queue manager, if the channel
+/// definitions match.
+/// </summary>
+public enum ShareSocketAllowed
+{
+ /// <summary>
+ /// Connections do not share a socket.
+ /// </summary>
+ False = XMSC.WMQ_SHARE_CONV_ALLOWED_NO,
+
+ /// <summary>
+ /// Connections share a socket.
+ /// </summary>
+ True = XMSC.WMQ_SHARE_CONV_ALLOWED_YES
+}
+
+#endregion
+
+#region Target Client (WMQ)
+
+// http://www-01.ibm.com/support/knowledgecenter/SSFKSJ_8.0.0/com.ibm.mq.msc.doc/prx_wmq_target_client.htm?lang=en
+/// <summary>
+/// Whether messages sent to the destination contain an <c>MQRFH2</c> header.
+/// </summary>
+public enum TargetClient
+{
+ /// <summary>
+ /// Messages sent to the destination contain an <c>MQRFH2</c> header.
+ /// Specify this value if the application is sending the messages to
+ /// another XMS application, a WebSphere® JMS application, or a native
+ /// WebSphere MQ application that is designed to handle an <c>MQRFH2</c>
+ /// header.
+ /// </summary>
+ JMS = XMSC.WMQ_TARGET_DEST_JMS,
+
+ /// <summary>
+ /// Messages sent to the destination do not contain an <c>MQRFH2</c>
+ /// header. Specify this value if the application is sending the messages
+ /// to a native WebSphere MQ application that is not designed to handle
+ /// an <c>MQRFH2</c> header.
+ /// </summary>
+ MQ = XMSC.WMQ_TARGET_DEST_MQ
+}
+
+#endregion
+
+#region Wildcard Format (WMQ)
+
+// http://www-01.ibm.com/support/knowledgecenter/SSFKSJ_8.0.0/com.ibm.mq.msc.doc/xmsc_wmq_wildcard_format.htm?lang=en
+/// <summary>
+/// This property determines which version of wildcard syntax is to be used.
+/// </summary>
+public enum WildcardFormat
+{
+ /// <summary>
+ /// Recognizes the topic level wildcards only i.e. '#' and '+' are treated
+ /// as wildcards.
+ /// </summary>
+ TopicOnly = XMSC.WMQ_WILDCARD_TOPIC_ONLY,
+
+ /// <summary>
+ /// Recognizes the character wildcards only i.e. '*' and '?' are treated
+ /// as wildcards.
+ /// </summary>
+ CharacterOnly = XMSC.WMQ_WILDCARD_CHAR_ONLY
+}
+
+#endregion
+
+#region Connection Protocol (WPM)
+
+// http://www-01.ibm.com/support/knowledgecenter/SSFKSJ_8.0.0/com.ibm.mq.msc.doc/prx_wpm_conn_prot.htm?lang=en
+/// <summary>
+/// The communications protocol used for the connection to the messaging
+/// engine.
+/// </summary>
+public enum WPMConnectionProtocol
+{
+ /// <summary>
+ /// The connection uses HTTP over TCP/IP.
+ /// </summary>
+ HTTP = XMSC.WPM_CP_HTTP,
+
+ /// <summary>
+ /// The connection uses TCP/IP.
+ /// </summary>
+ TCP = XMSC.WPM_CP_TCP
+}
+
+#endregion
+
+#region Connection Proximity (WPM)
+
+// http://www-01.ibm.com/support/knowledgecenter/SSFKSJ_8.0.0/com.ibm.mq.msc.doc/prx_wpm_conn_prox.htm?lang=en
+/// <summary>
+/// The connection proximity setting for the connection. This property
+/// determines how close the messaging engine that the application connects
+/// to must be to the bootstrap server.
+/// </summary>
+public enum ConnectionProximity
+{
+ /// <summary>
+ /// Bus.
+ /// </summary>
+ Bus, // XMSC.WPM_CONNECTION_PROXIMITY_BUS = "Bus"
+
+ /// <summary>
+ /// Cluster.
+ /// </summary>
+ Cluster, // XMSC.WPM_CONNECTION_PROXIMITY_CLUSTER = "Cluster"
+
+ /// <summary>
+ /// Host.
+ /// </summary>
+ Host, // XMSC.WPM_CONNECTION_PROXIMITY_HOST = "Host"
+
+ /// <summary>
+ /// Server.
+ /// </summary>
+ Server // XMSC.WPM_CONNECTION_PROXIMITY_SERVER = "Server"
+}
+
+#endregion
+
+#region Mapping (WPM)
+
+// http://www-01.ibm.com/support/knowledgecenter/SSFKSJ_8.0.0/com.ibm.mq.msc.doc/prx_wpm_non_pers_m.htm?lang=en
+// http://www-01.ibm.com/support/knowledgecenter/SSFKSJ_8.0.0/com.ibm.mq.msc.doc/prx_wpm_pers_m.htm?lang=en
+/// <summary>
+/// The reliability level of messages that are sent using the connection.
+/// </summary>
+public enum Mapping
+{
+ /// <summary>
+ /// Determined by the default reliability level specified for the queue
+ /// or topic space in the service integration bus.
+ /// </summary>
+ AsDestination = XMSC.WPM_MAPPING_AS_DESTINATION,
+
+ /// <summary>
+ /// Best effort nonpersistent.
+ /// </summary>
+ BestEffortNonPersistent = XMSC.WPM_MAPPING_BEST_EFFORT_NON_PERSISTENT,
+
+ /// <summary>
+ /// Express nonpersistent.
+ /// </summary>
+ ExpressNonPersistent = XMSC.WPM_MAPPING_EXPRESS_NON_PERSISTENT,
+
+ /// <summary>
+ /// Reliable nonpersistent.
+ /// </summary>
+ ReliableNonPersistent = XMSC.WPM_MAPPING_RELIABLE_NON_PERSISTENT,
+
+ /// <summary>
+ /// Reliable persistent.
+ /// </summary>
+ ReliablePersistent = XMSC.WPM_MAPPING_RELIABLE_PERSISTENT,
+
+ /// <summary>
+ /// Assured persistent.
+ /// </summary>
+ AssuredPersistent = XMSC.WPM_MAPPING_ASSURED_PERSISTENT
+}
+
+#endregion
+
+#region Target Significance (WPM)
+
+// http://www-01.ibm.com/support/knowledgecenter/SSFKSJ_8.0.0/com.ibm.mq.msc.doc/prx_wpm_target_signf.htm?lang=en
+/// <summary>
+/// The significance of the target group of messaging engines.
+/// </summary>
+public enum TargetSignificance
+{
+ /// <summary>
+ /// A messaging engine in the target group is selected if one is available.
+ /// Otherwise, a messaging engine outside the target group is selected,
+ /// provided it is in the same service integration bus.
+ /// </summary>
+ Preferred, // XMSC.WPM_TARGET_SIGNIFICANCE_PREFERRED = "Preferred"
+
+ /// <summary>
+ /// The selected messaging engine must be in the target group. If a
+ /// messaging engine in the target group is not available, the connection
+ /// process fails.
+ /// </summary>
+ Required // XMSC.WPM_TARGET_SIGNIFICANCE_REQUIRED = "Required"
+}
+
+#endregion
+
+#region Target Type (WPM)
+
+// http://www-01.ibm.com/support/knowledgecenter/SSFKSJ_8.0.0/com.ibm.mq.msc.doc/prx_wpm_target_type.htm?lang=en
+/// <summary>
+/// The type of the target group of messaging engines. This property
+/// determines the nature of the target group identified by the
+/// <c>XMSC_WPM_TARGET_GROUP</c> property.
+/// </summary>
+public enum TargetType
+{
+ /// <summary>
+ /// The name of the target group is the name of a bus member. The target
+ /// group is all the messaging engines in the bus member.
+ /// </summary>
+ BusMember, // XMSC.WPM_TARGET_TYPE_BUSMEMBER = "BusMember"
+
+ /// <summary>
+ /// The name of the target group is the name of a user-defined group of
+ /// messaging engines. The target group is all the messaging engines that
+ /// are registered with the user-defined group.
+ /// </summary>
+ Custom, // XMSC.WPM_TARGET_TYPE_CUSTOM = "Custom"
+
+ /// <summary>
+ /// The name of the target group is the name of a messaging engine. The
+ /// target group is the specified messaging engine.
+ /// </summary>
+ MessagingEngine // XMSC.WPM_TARGET_TYPE_ME = "ME"
+}
+
+#endregion
+
+}
\ No newline at end of file
diff --git a/src/main/csharp/_TODO_.txt b/src/main/csharp/_TODO_.txt
new file mode 100644
index 0000000..d14384c
--- /dev/null
+++ b/src/main/csharp/_TODO_.txt
@@ -0,0 +1,29 @@
+ ~ BytesMessage.cs // Ajouter commentaires
+ X Connection.cs
+ X ConnectionFactory.cs
+ X ConnectionMetaData.cs
+ X Destination.cs
+ X InitialContext.cs
+ X MapMessage.cs
+ X Message.cs
+ ~ MessageConsumer.cs // Ajouter commentaires
+ ~ MessageProducer.cs // Ajouter commentaires
+ ~ MessageProperties.cs // Ajouter commentaires
+ X ObjectMessage.cs
+ X Queue.cs
+ ~ QueueBrowser.cs // Ajouter commentaires
+ ~ Session.cs // Ajouter commentaires
+ X StreamMessage.cs
+ X TemporaryQueue.cs
+ X TemporaryTopic.cs
+ X TextMessage.cs
+ X Topic.cs
+ ? Util\Dispatcher.cs
+ X Util\ExceptionUtil.cs
+ X Util\IntrospectionSupport.cs
+ X Util\UriAttributeAttribute.cs
+ X Util\XMSConvert.cs
+ X Util\XMSEnum.cs
+
+
+Temporary Queue / Topic
\ No newline at end of file
diff --git a/src/main/ndoc/NamespaceSummary.xml b/src/main/ndoc/NamespaceSummary.xml
new file mode 100644
index 0000000..e4aa15e
--- /dev/null
+++ b/src/main/ndoc/NamespaceSummary.xml
@@ -0,0 +1,21 @@
+<!--
+ 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.
+-->
+<namespaces>
+ <namespace name="XMS">
+ The <b>XMS</b> namespace defines the IBM XMS provider API for the .Net Message System (NMS) API, which is an interface to messaging systems rather like JMS is for Java.
+ </namespace>
+</namespaces>
diff --git a/src/main/sandcastle/feedback_content.xml b/src/main/sandcastle/feedback_content.xml
new file mode 100644
index 0000000..ee30a12
--- /dev/null
+++ b/src/main/sandcastle/feedback_content.xml
@@ -0,0 +1,32 @@
+<content xml:space="preserve">
+
+ <item id="fb_alias">activemq.docs@apache.org</item>
+ <item id="fb_product"></item>
+ <item id="fb_deliverable"></item>
+
+ <item id="fb_subject">Customer%20Feedback</item>
+ <item id="fb_body">%0\dThank%20you%20for%20your%20feedback.%20The%20developer%20writing%20teams%20use%20your%20feedback%20to%20improve%20documentation.%20While%20we%20are%20reviewing%20your%20feedback,%20we%20may%20send%20you%20e-mail%20to%20ask%20for%20clarification%20or%20feedback%20on%20a%20solution.%20We%20do%20not%20use%20your%20e-mail%20address%20for%20any%20other%20purpose.%0\d</item>
+
+ <item id="fb_headerFeedBack">Send Feedback</item>
+
+
+ <!-- feedback values for sandcastle scenario -->
+
+ <item id="feedback_alias"></item>
+ <item id="feedback_product"></item>
+ <item id="feedback_deliverable"></item>
+ <item id="feedback_fileVersion"></item>
+ <item id="feedback_topicVersion"></item>
+ <item id="feedback_body"></item>
+ <item id="feedback_subject"></item>
+
+ <item id="fb_Introduction">We value your feedback. To rate this topic and send feedback about this topic to the documentation team, click a rating, and then click <b>Send Feedback</b>. For assistance with support issues, refer to the technical support information included with the product.</item>
+
+ <item id="fb_Send">Send Feedback</item>
+ <item id="fb_Poor">Poor</item>
+ <item id="fb_Excellent">Outstanding</item>
+ <item id="fb_EnterFeedbackText">To e-mail your feedback, click here:</item>
+ <item id="fb_Title">Documentation Feedback</item>
+ <item id="fb_altIcon">Display feedback instructions at the bottom of the page.</item>
+
+</content>
\ No newline at end of file
diff --git a/src/test/csharp/AsyncConsumeTest.cs b/src/test/csharp/AsyncConsumeTest.cs
new file mode 100644
index 0000000..c414927
--- /dev/null
+++ b/src/test/csharp/AsyncConsumeTest.cs
@@ -0,0 +1,228 @@
+/*
+ * 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.
+ */
+
+using System.Threading;
+using NUnit.Framework;
+
+namespace Apache.NMS.Test
+{
+ //[TestFixture]
+ public class AsyncConsumeTest : NMSTest
+ {
+ protected string RESPONSE_CLIENT_ID;
+ protected AutoResetEvent semaphore;
+ protected bool received;
+ protected IMessage receivedMsg;
+
+ public AsyncConsumeTest(NMSTestSupport testSupport)
+ : base(testSupport)
+ {
+ }
+
+ //[SetUp]
+ public override void SetUp()
+ {
+ base.SetUp();
+ semaphore = new AutoResetEvent(false);
+ received = false;
+ receivedMsg = null;
+
+ RESPONSE_CLIENT_ID = GetTestClientId() + ":RESPONSE";
+ }
+
+ //[TearDown]
+ public override void TearDown()
+ {
+ receivedMsg = null;
+ base.TearDown();
+ }
+
+ //[Test]
+ public virtual void TestAsynchronousConsume(
+ //[Values(MsgDeliveryMode.Persistent, MsgDeliveryMode.NonPersistent)]
+ MsgDeliveryMode deliveryMode, string testQueueRef)
+ {
+ // IBM XMS doesn't support both synchronous and asynchronous operations
+ // in the same session. Needs 2 separate sessions.
+ using(IConnection connection = CreateConnectionAndStart(GetTestClientId()))
+ using(ISession producerSession = connection.CreateSession(AcknowledgementMode.AutoAcknowledge))
+ using(ISession consumerSession = connection.CreateSession(AcknowledgementMode.AutoAcknowledge))
+ using(IDestination producerDestination = GetClearDestination(producerSession, DestinationType.Queue, testQueueRef))
+ using(IDestination consumerDestination = GetDestination(consumerSession, DestinationType.Queue, testQueueRef))
+ using(IMessageConsumer consumer = consumerSession.CreateConsumer(consumerDestination))
+ using(IMessageProducer producer = producerSession.CreateProducer(producerDestination))
+ {
+ producer.DeliveryMode = deliveryMode;
+ consumer.Listener += new MessageListener(OnMessage);
+
+ IMessage request = producerSession.CreateMessage();
+ request.NMSCorrelationID = "AsyncConsume";
+ request.NMSType = "Test";
+ producer.Send(request);
+
+ WaitForMessageToArrive();
+ Assert.AreEqual(request.NMSCorrelationID, receivedMsg.NMSCorrelationID, "Invalid correlation ID.");
+ }
+ }
+
+ //[Test]
+ public virtual void TestCreateConsumerAfterSend(
+ //[Values(MsgDeliveryMode.Persistent, MsgDeliveryMode.NonPersistent)]
+ MsgDeliveryMode deliveryMode, string testQueueRef)
+ {
+ using(IConnection connection = CreateConnectionAndStart(GetTestClientId()))
+ using(ISession producerSession = connection.CreateSession(AcknowledgementMode.AutoAcknowledge))
+ using(ISession consumerSession = connection.CreateSession(AcknowledgementMode.AutoAcknowledge))
+ using(IDestination producerDestination = GetClearDestination(producerSession, DestinationType.Queue, testQueueRef))
+ using(IDestination consumerDestination = GetDestination(consumerSession, DestinationType.Queue, testQueueRef))
+ {
+ string correlationId = "AsyncConsumeAfterSend";
+
+ using(IMessageProducer producer = producerSession.CreateProducer(producerDestination))
+ {
+ producer.DeliveryMode = deliveryMode;
+ IMessage request = producerSession.CreateMessage();
+ request.NMSCorrelationID = correlationId;
+ request.NMSType = "Test";
+ producer.Send(request);
+ }
+
+ using(IMessageConsumer consumer = consumerSession.CreateConsumer(consumerDestination))
+ {
+ consumer.Listener += new MessageListener(OnMessage);
+ WaitForMessageToArrive();
+ Assert.AreEqual(correlationId, receivedMsg.NMSCorrelationID, "Invalid correlation ID.");
+ }
+ }
+ }
+
+ //[Test]
+ public virtual void TestCreateConsumerBeforeSendAddListenerAfterSend(
+ //[Values(MsgDeliveryMode.Persistent, MsgDeliveryMode.NonPersistent)]
+ MsgDeliveryMode deliveryMode, string testQueueRef)
+ {
+ using(IConnection connection = CreateConnectionAndStart(GetTestClientId()))
+ using(ISession producerSession = connection.CreateSession(AcknowledgementMode.AutoAcknowledge))
+ using(ISession consumerSession = connection.CreateSession(AcknowledgementMode.AutoAcknowledge))
+ using(IDestination producerDestination = GetClearDestination(producerSession, DestinationType.Queue, testQueueRef))
+ using(IDestination consumerDestination = GetDestination(consumerSession, DestinationType.Queue, testQueueRef))
+ using(IMessageConsumer consumer = consumerSession.CreateConsumer(consumerDestination))
+ using(IMessageProducer producer = producerSession.CreateProducer(producerDestination))
+ {
+ producer.DeliveryMode = deliveryMode;
+
+ IMessage request = producerSession.CreateMessage();
+ request.NMSCorrelationID = "AsyncConsumeAfterSendLateListener";
+ request.NMSType = "Test";
+ producer.Send(request);
+
+ // now lets add the listener
+ consumer.Listener += new MessageListener(OnMessage);
+ WaitForMessageToArrive();
+ Assert.AreEqual(request.NMSCorrelationID, receivedMsg.NMSCorrelationID, "Invalid correlation ID.");
+ }
+ }
+
+ //[Test]
+ public virtual void TestAsynchronousTextMessageConsume(
+ //[Values(MsgDeliveryMode.Persistent, MsgDeliveryMode.NonPersistent)]
+ MsgDeliveryMode deliveryMode, string testQueueRef)
+ {
+ using(IConnection connection = CreateConnectionAndStart(GetTestClientId()))
+ using(ISession producerSession = connection.CreateSession(AcknowledgementMode.AutoAcknowledge))
+ using(ISession consumerSession = connection.CreateSession(AcknowledgementMode.AutoAcknowledge))
+ using(IDestination producerDestination = GetClearDestination(producerSession, DestinationType.Queue, testQueueRef))
+ using(IDestination consumerDestination = GetDestination(consumerSession, DestinationType.Queue, testQueueRef))
+ using(IMessageConsumer consumer = consumerSession.CreateConsumer(consumerDestination))
+ using(IMessageProducer producer = producerSession.CreateProducer(producerDestination))
+ {
+ consumer.Listener += new MessageListener(OnMessage);
+ producer.DeliveryMode = deliveryMode;
+
+ ITextMessage request = producerSession.CreateTextMessage("Hello, World!");
+ request.NMSCorrelationID = "AsyncConsumeTextMessage";
+ request.Properties["NMSXGroupID"] = "cheese";
+ request.Properties["myHeader"] = "James";
+
+ producer.Send(request);
+
+ WaitForMessageToArrive();
+ Assert.AreEqual(request.NMSCorrelationID, receivedMsg.NMSCorrelationID, "Invalid correlation ID.");
+ Assert.AreEqual(request.Properties["NMSXGroupID"], receivedMsg.Properties["NMSXGroupID"], "Invalid NMSXGroupID.");
+ Assert.AreEqual(request.Properties["myHeader"], receivedMsg.Properties["myHeader"], "Invalid myHeader.");
+ Assert.AreEqual(request.Text, ((ITextMessage) receivedMsg).Text, "Invalid text body.");
+ }
+ }
+
+ //[Test]
+ public virtual void TestTemporaryQueueAsynchronousConsume(
+ //[Values(MsgDeliveryMode.Persistent, MsgDeliveryMode.NonPersistent)]
+ MsgDeliveryMode deliveryMode, string testQueueRef)
+ {
+ using(IConnection connection = CreateConnectionAndStart(GetTestClientId()))
+ using(ISession session = connection.CreateSession(AcknowledgementMode.AutoAcknowledge))
+ using(ITemporaryQueue tempReplyDestination = session.CreateTemporaryQueue())
+ using(IDestination destination = GetClearDestination(session, DestinationType.Queue, testQueueRef))
+ using(IMessageConsumer consumer = session.CreateConsumer(destination))
+ using(IMessageConsumer tempConsumer = session.CreateConsumer(tempReplyDestination))
+ using(IMessageProducer producer = session.CreateProducer(destination))
+ {
+ producer.DeliveryMode = deliveryMode;
+ tempConsumer.Listener += new MessageListener(OnMessage);
+ consumer.Listener += new MessageListener(OnQueueMessage);
+
+ IMessage request = session.CreateMessage();
+ request.NMSCorrelationID = "TemqQueueAsyncConsume";
+ request.NMSType = "Test";
+ request.NMSReplyTo = tempReplyDestination;
+ producer.Send(request);
+
+ WaitForMessageToArrive();
+ Assert.AreEqual("TempQueueAsyncResponse", receivedMsg.NMSCorrelationID, "Invalid correlation ID.");
+ }
+ }
+
+ protected void OnQueueMessage(IMessage message)
+ {
+ Assert.AreEqual("TemqQueueAsyncConsume", message.NMSCorrelationID, "Invalid correlation ID.");
+ using(IConnection connection = CreateConnectionAndStart(RESPONSE_CLIENT_ID))
+ using(ISession session = connection.CreateSession(AcknowledgementMode.AutoAcknowledge))
+ using(IMessageProducer producer = session.CreateProducer(message.NMSReplyTo))
+ {
+ producer.DeliveryMode = message.NMSDeliveryMode;
+
+ ITextMessage response = session.CreateTextMessage("Asynchronous Response Message Text");
+ response.NMSCorrelationID = "TempQueueAsyncResponse";
+ response.NMSType = message.NMSType;
+ producer.Send(response);
+ }
+ }
+
+ protected void OnMessage(IMessage message)
+ {
+ receivedMsg = message;
+ received = true;
+ semaphore.Set();
+ }
+
+ protected void WaitForMessageToArrive()
+ {
+ semaphore.WaitOne((int) receiveTimeout.TotalMilliseconds, true);
+ Assert.IsTrue(received, "Should have received a message by now!");
+ }
+ }
+}
diff --git a/src/test/csharp/BadConsumeTest.cs b/src/test/csharp/BadConsumeTest.cs
new file mode 100644
index 0000000..564f9d8
--- /dev/null
+++ b/src/test/csharp/BadConsumeTest.cs
@@ -0,0 +1,69 @@
+/*
+ * 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.
+ */
+using System;
+using NUnit.Framework;
+
+namespace Apache.NMS.Test
+{
+ //[TestFixture]
+ public class BadConsumeTest : NMSTest
+ {
+ protected IConnection connection;
+ protected ISession session;
+
+ protected BadConsumeTest(NMSTestSupport testSupport)
+ : base(testSupport)
+ {
+ }
+
+ //[SetUp]
+ public override void SetUp()
+ {
+ connection = CreateConnection(GetTestClientId());
+ connection.Start();
+ session = connection.CreateSession(AcknowledgementMode.AutoAcknowledge);
+ }
+
+ //[TearDown]
+ public override void TearDown()
+ {
+ if(null != session)
+ {
+ session.Dispose();
+ session = null;
+ }
+
+ if(null != connection)
+ {
+ connection.Dispose();
+ connection = null;
+ }
+ }
+
+ //[Test]
+ //[ExpectedException(Handler="ExceptionValidationCheck")]
+ public virtual void TestBadConsumerException()
+ {
+ session.CreateConsumer(null);
+ }
+
+ public void ExceptionValidationCheck(Exception ex)
+ {
+ Assert.IsNotNull(ex as NMSException, "Invalid exception was thrown.");
+ }
+ }
+}
diff --git a/src/test/csharp/BytesMessageTest.cs b/src/test/csharp/BytesMessageTest.cs
new file mode 100644
index 0000000..d8c3af7
--- /dev/null
+++ b/src/test/csharp/BytesMessageTest.cs
@@ -0,0 +1,138 @@
+/*
+ * 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.
+ */
+
+using System;
+using Apache.NMS.Util;
+using NUnit.Framework;
+
+namespace Apache.NMS.Test
+{
+ //[TestFixture]
+ public class BytesMessageTest : NMSTest
+ {
+ protected byte[] msgContent = {1, 2, 3, 4, 5, 6, 7, 8};
+
+ protected BytesMessageTest(NMSTestSupport testSupport)
+ : base(testSupport)
+ {
+ }
+
+ //[Test]
+ public virtual void SendReceiveBytesMessage(
+ //[Values(MsgDeliveryMode.Persistent, MsgDeliveryMode.NonPersistent)]
+ MsgDeliveryMode deliveryMode, string testQueueRef)
+ {
+ using(IConnection connection = CreateConnection(GetTestClientId()))
+ {
+ connection.Start();
+ using(ISession session = connection.CreateSession(AcknowledgementMode.AutoAcknowledge))
+ {
+ IDestination destination = GetClearDestination(session, DestinationType.Queue, testQueueRef);
+ using(IMessageConsumer consumer = session.CreateConsumer(destination))
+ using(IMessageProducer producer = session.CreateProducer(destination))
+ {
+ producer.DeliveryMode = deliveryMode;
+ IMessage request = session.CreateBytesMessage(msgContent);
+ producer.Send(request);
+
+ IMessage message = consumer.Receive(receiveTimeout);
+ AssertMessageIsReadOnly(message);
+ AssertBytesMessageEqual(request, message);
+ Assert.AreEqual(deliveryMode, message.NMSDeliveryMode, "NMSDeliveryMode does not match");
+
+ }
+ }
+ }
+ }
+
+ //[Test]
+ public virtual void SendReceiveBytesMessageContent(
+ //[Values(MsgDeliveryMode.Persistent, MsgDeliveryMode.NonPersistent)]
+ MsgDeliveryMode deliveryMode, string testQueueRef)
+ {
+ using(IConnection connection = CreateConnection(GetTestClientId()))
+ {
+ connection.Start();
+ using(ISession session = connection.CreateSession(AcknowledgementMode.AutoAcknowledge))
+ {
+ IDestination destination = GetClearDestination(session, DestinationType.Queue, testQueueRef);
+ using(IMessageConsumer consumer = session.CreateConsumer(destination))
+ using(IMessageProducer producer = session.CreateProducer(destination))
+ {
+ producer.DeliveryMode = deliveryMode;
+ IBytesMessage request = session.CreateBytesMessage();
+
+ request.WriteBoolean(true);
+ request.WriteByte((byte) 1);
+ request.WriteBytes(new byte[1]);
+ request.WriteBytes(new byte[3], 0, 2);
+ request.WriteChar('a');
+ request.WriteDouble(1.5);
+ request.WriteSingle((float) 1.5);
+ request.WriteInt32(1);
+ request.WriteInt64(1);
+ request.WriteObject("stringobj");
+ request.WriteInt16((short) 1);
+ request.WriteString("utfstring");
+
+ producer.Send(request);
+
+ IMessage message = consumer.Receive(receiveTimeout);
+ AssertMessageIsReadOnly(message);
+ AssertBytesMessageEqual(request, message);
+ Assert.AreEqual(deliveryMode, message.NMSDeliveryMode, "NMSDeliveryMode does not match");
+
+ }
+ }
+ }
+ }
+
+ protected void AssertMessageIsReadOnly(IMessage message)
+ {
+ Type writeableExceptionType = typeof(MessageNotWriteableException);
+ IBytesMessage theMessage = message as IBytesMessage;
+ Assert.IsNotNull(theMessage);
+ Assert.Throws(writeableExceptionType, delegate () { theMessage.WriteBoolean(true); });
+ Assert.Throws(writeableExceptionType, delegate () { theMessage.WriteByte((byte) 1); });
+ Assert.Throws(writeableExceptionType, delegate () { theMessage.WriteBytes(new byte[1]); });
+ Assert.Throws(writeableExceptionType, delegate () { theMessage.WriteBytes(new byte[3], 0, 2); });
+ Assert.Throws(writeableExceptionType, delegate () { theMessage.WriteChar('a'); });
+ Assert.Throws(writeableExceptionType, delegate () { theMessage.WriteDouble(1.5); });
+ Assert.Throws(writeableExceptionType, delegate () { theMessage.WriteSingle((float) 1.5); });
+ Assert.Throws(writeableExceptionType, delegate () { theMessage.WriteInt32(1); });
+ Assert.Throws(writeableExceptionType, delegate () { theMessage.WriteInt64(1); });
+ Assert.Throws(writeableExceptionType, delegate () { theMessage.WriteObject("stringobj"); });
+ Assert.Throws(writeableExceptionType, delegate () { theMessage.WriteInt16((short) 1); });
+ Assert.Throws(writeableExceptionType, delegate () { theMessage.WriteString("utfstring"); });
+ }
+
+ /// <summary>
+ /// Assert that two messages are IBytesMessages and their contents are equal.
+ /// </summary>
+ /// <param name="expected"></param>
+ /// <param name="actual"></param>
+ protected void AssertBytesMessageEqual(IMessage expected, IMessage actual)
+ {
+ IBytesMessage expectedBytesMsg = expected as IBytesMessage;
+ expectedBytesMsg.Reset();
+ Assert.IsNotNull(expectedBytesMsg, "'expected' message not a bytes message");
+ IBytesMessage actualBytesMsg = actual as IBytesMessage;
+ Assert.IsNotNull(actualBytesMsg, "'actual' message not a bytes message");
+ Assert.AreEqual(expectedBytesMsg.Content, actualBytesMsg.Content, "Bytes message contents do not match.");
+ }
+ }
+}
diff --git a/src/test/csharp/Commands/BytesMessage.cs b/src/test/csharp/Commands/BytesMessage.cs
new file mode 100644
index 0000000..e581942
--- /dev/null
+++ b/src/test/csharp/Commands/BytesMessage.cs
@@ -0,0 +1,511 @@
+/*
+ * 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.
+ */
+
+using Apache.NMS;
+using Apache.NMS.Util;
+using System;
+using System.Collections;
+using System.IO;
+
+namespace Apache.NMS.Commands
+{
+ public class BytesMessage : Message, IBytesMessage
+ {
+ private EndianBinaryReader dataIn = null;
+ private EndianBinaryWriter dataOut = null;
+ private MemoryStream outputBuffer = null;
+ private int length = 0;
+
+ public override Object Clone()
+ {
+ StoreContent();
+ return base.Clone();
+ }
+
+ public override void ClearBody()
+ {
+ base.ClearBody();
+ this.outputBuffer = null;
+ this.dataIn = null;
+ this.dataOut = null;
+ this.length = 0;
+ }
+
+ public long BodyLength
+ {
+ get
+ {
+ InitializeReading();
+ return this.length;
+ }
+ }
+
+ public byte ReadByte()
+ {
+ InitializeReading();
+ try
+ {
+ return dataIn.ReadByte();
+ }
+ catch(EndOfStreamException e)
+ {
+ throw NMSExceptionSupport.CreateMessageEOFException(e);
+ }
+ catch(IOException e)
+ {
+ throw NMSExceptionSupport.CreateMessageFormatException(e);
+ }
+ }
+
+ public void WriteByte( byte value )
+ {
+ InitializeWriting();
+ try
+ {
+ dataOut.Write( value );
+ }
+ catch(Exception e)
+ {
+ throw NMSExceptionSupport.Create(e);
+ }
+ }
+
+ public bool ReadBoolean()
+ {
+ InitializeReading();
+ try
+ {
+ return dataIn.ReadBoolean();
+ }
+ catch(EndOfStreamException e)
+ {
+ throw NMSExceptionSupport.CreateMessageEOFException(e);
+ }
+ catch(IOException e)
+ {
+ throw NMSExceptionSupport.CreateMessageFormatException(e);
+ }
+ }
+
+ public void WriteBoolean( bool value )
+ {
+ InitializeWriting();
+ try
+ {
+ dataOut.Write( value );
+ }
+ catch(Exception e)
+ {
+ throw NMSExceptionSupport.Create(e);
+ }
+ }
+
+ public char ReadChar()
+ {
+ InitializeReading();
+ try
+ {
+ return dataIn.ReadChar();
+ }
+ catch(EndOfStreamException e)
+ {
+ throw NMSExceptionSupport.CreateMessageEOFException(e);
+ }
+ catch(IOException e)
+ {
+ throw NMSExceptionSupport.CreateMessageFormatException(e);
+ }
+ }
+
+ public void WriteChar( char value )
+ {
+ InitializeWriting();
+ try
+ {
+ dataOut.Write( value );
+ }
+ catch(Exception e)
+ {
+ throw NMSExceptionSupport.Create(e);
+ }
+ }
+
+ public short ReadInt16()
+ {
+ InitializeReading();
+ try
+ {
+ return dataIn.ReadInt16();
+ }
+ catch(EndOfStreamException e)
+ {
+ throw NMSExceptionSupport.CreateMessageEOFException(e);
+ }
+ catch(IOException e)
+ {
+ throw NMSExceptionSupport.CreateMessageFormatException(e);
+ }
+ }
+
+ public void WriteInt16( short value )
+ {
+ InitializeWriting();
+ try
+ {
+ dataOut.Write( value );
+ }
+ catch(Exception e)
+ {
+ throw NMSExceptionSupport.Create(e);
+ }
+ }
+
+ public int ReadInt32()
+ {
+ InitializeReading();
+ try
+ {
+ return dataIn.ReadInt32();
+ }
+ catch(EndOfStreamException e)
+ {
+ throw NMSExceptionSupport.CreateMessageEOFException(e);
+ }
+ catch(IOException e)
+ {
+ throw NMSExceptionSupport.CreateMessageFormatException(e);
+ }
+ }
+
+ public void WriteInt32( int value )
+ {
+ InitializeWriting();
+ try
+ {
+ dataOut.Write( value );
+ }
+ catch(Exception e)
+ {
+ throw NMSExceptionSupport.Create(e);
+ }
+ }
+
+ public long ReadInt64()
+ {
+ InitializeReading();
+ try
+ {
+ return dataIn.ReadInt64();
+ }
+ catch(EndOfStreamException e)
+ {
+ throw NMSExceptionSupport.CreateMessageEOFException(e);
+ }
+ catch(IOException e)
+ {
+ throw NMSExceptionSupport.CreateMessageFormatException(e);
+ }
+ }
+
+ public void WriteInt64( long value )
+ {
+ InitializeWriting();
+ try
+ {
+ dataOut.Write( value );
+ }
+ catch(Exception e)
+ {
+ throw NMSExceptionSupport.Create(e);
+ }
+ }
+
+ public float ReadSingle()
+ {
+ InitializeReading();
+ try
+ {
+ return dataIn.ReadSingle();
+ }
+ catch(EndOfStreamException e)
+ {
+ throw NMSExceptionSupport.CreateMessageEOFException(e);
+ }
+ catch(IOException e)
+ {
+ throw NMSExceptionSupport.CreateMessageFormatException(e);
+ }
+ }
+
+ public void WriteSingle( float value )
+ {
+ InitializeWriting();
+ try
+ {
+ dataOut.Write( value );
+ }
+ catch(Exception e)
+ {
+ throw NMSExceptionSupport.Create(e);
+ }
+ }
+
+ public double ReadDouble()
+ {
+ InitializeReading();
+ try
+ {
+ return dataIn.ReadDouble();
+ }
+ catch(EndOfStreamException e)
+ {
+ throw NMSExceptionSupport.CreateMessageEOFException(e);
+ }
+ catch(IOException e)
+ {
+ throw NMSExceptionSupport.CreateMessageFormatException(e);
+ }
+ }
+
+ public void WriteDouble( double value )
+ {
+ InitializeWriting();
+ try
+ {
+ dataOut.Write( value );
+ }
+ catch(Exception e)
+ {
+ throw NMSExceptionSupport.Create(e);
+ }
+ }
+
+ public int ReadBytes( byte[] value )
+ {
+ InitializeReading();
+ try
+ {
+ return dataIn.Read( value, 0, value.Length );
+ }
+ catch(EndOfStreamException e)
+ {
+ throw NMSExceptionSupport.CreateMessageEOFException(e);
+ }
+ catch(IOException e)
+ {
+ throw NMSExceptionSupport.CreateMessageFormatException(e);
+ }
+ }
+
+ public int ReadBytes( byte[] value, int length )
+ {
+ InitializeReading();
+ try
+ {
+ return dataIn.Read( value, 0, length );
+ }
+ catch(EndOfStreamException e)
+ {
+ throw NMSExceptionSupport.CreateMessageEOFException(e);
+ }
+ catch(IOException e)
+ {
+ throw NMSExceptionSupport.CreateMessageFormatException(e);
+ }
+ }
+
+ public void WriteBytes( byte[] value )
+ {
+ InitializeWriting();
+ try
+ {
+ dataOut.Write( value, 0, value.Length );
+ }
+ catch(Exception e)
+ {
+ throw NMSExceptionSupport.Create(e);
+ }
+ }
+
+ public void WriteBytes( byte[] value, int offset, int length )
+ {
+ InitializeWriting();
+ try
+ {
+ dataOut.Write( value, offset, length );
+ }
+ catch(Exception e)
+ {
+ throw NMSExceptionSupport.Create(e);
+ }
+ }
+
+ public string ReadString()
+ {
+ InitializeReading();
+ try
+ {
+ // JMS, CMS and NMS all encode the String using a 16 bit size header.
+ return dataIn.ReadString16();
+ }
+ catch(EndOfStreamException e)
+ {
+ throw NMSExceptionSupport.CreateMessageEOFException(e);
+ }
+ catch(IOException e)
+ {
+ throw NMSExceptionSupport.CreateMessageFormatException(e);
+ }
+ }
+
+ public void WriteString( string value )
+ {
+ InitializeWriting();
+ try
+ {
+ // JMS, CMS and NMS all encode the String using a 16 bit size header.
+ dataOut.WriteString16(value);
+ }
+ catch(Exception e)
+ {
+ throw NMSExceptionSupport.Create(e);
+ }
+ }
+
+ public void WriteObject( System.Object value )
+ {
+ InitializeWriting();
+ if( value is System.Byte )
+ {
+ this.dataOut.Write( (byte) value );
+ }
+ else if( value is Char )
+ {
+ this.dataOut.Write( (char) value );
+ }
+ else if( value is Boolean )
+ {
+ this.dataOut.Write( (bool) value );
+ }
+ else if( value is Int16 )
+ {
+ this.dataOut.Write( (short) value );
+ }
+ else if( value is Int32 )
+ {
+ this.dataOut.Write( (int) value );
+ }
+ else if( value is Int64 )
+ {
+ this.dataOut.Write( (long) value );
+ }
+ else if( value is Single )
+ {
+ this.dataOut.Write( (float) value );
+ }
+ else if( value is Double )
+ {
+ this.dataOut.Write( (double) value );
+ }
+ else if( value is byte[] )
+ {
+ this.dataOut.Write( (byte[]) value );
+ }
+ else if( value is String )
+ {
+ this.dataOut.WriteString16( (string) value );
+ }
+ else
+ {
+ throw new MessageFormatException("Cannot write non-primitive type:" + value.GetType());
+ }
+ }
+
+ public new byte[] Content
+ {
+ get
+ {
+ byte[] buffer = null;
+ InitializeReading();
+ if(this.length != 0)
+ {
+ buffer = new byte[this.length];
+ this.dataIn.Read(buffer, 0, buffer.Length);
+ }
+ return buffer;
+ }
+
+ set
+ {
+ InitializeWriting();
+ this.dataOut.Write(value, 0, value.Length);
+ }
+ }
+
+ public void Reset()
+ {
+ StoreContent();
+ this.dataIn = null;
+ this.dataOut = null;
+ this.outputBuffer = null;
+ this.ReadOnlyBody = true;
+ }
+
+ private void InitializeReading()
+ {
+ FailIfWriteOnlyBody();
+ if(this.dataIn == null)
+ {
+ byte[] data = base.Content;
+
+ if(base.Content == null)
+ {
+ data = new byte[0];
+ }
+
+ Stream target = new MemoryStream(data, false);
+
+ this.length = data.Length;
+ this.dataIn = new EndianBinaryReader(target);
+ }
+ }
+
+ private void InitializeWriting()
+ {
+ FailIfReadOnlyBody();
+ if(this.dataOut == null)
+ {
+ this.outputBuffer = new MemoryStream();
+ this.dataOut = new EndianBinaryWriter(this.outputBuffer);
+ }
+ }
+
+ private void StoreContent()
+ {
+ if(this.dataOut != null)
+ {
+ this.dataOut.Close();
+ base.Content = outputBuffer.ToArray();
+
+ this.dataOut = null;
+ this.outputBuffer = null;
+ }
+ }
+
+ }
+}
+
diff --git a/src/test/csharp/Commands/Destination.cs b/src/test/csharp/Commands/Destination.cs
new file mode 100644
index 0000000..23c477d
--- /dev/null
+++ b/src/test/csharp/Commands/Destination.cs
@@ -0,0 +1,380 @@
+/*
+ * 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.
+ */
+
+using System;
+using System.Collections.Specialized;
+using Apache.NMS.Util;
+
+namespace Apache.NMS.Commands
+{
+ /// <summary>
+ /// Summary description for Destination.
+ /// </summary>
+ public abstract class Destination : IDestination, ICloneable
+ {
+ /// <summary>
+ /// Topic Destination object
+ /// </summary>
+ public const int TOPIC = 1;
+ /// <summary>
+ /// Temporary Topic Destination object
+ /// </summary>
+ public const int TEMPORARY_TOPIC = 2;
+ /// <summary>
+ /// Queue Destination object
+ /// </summary>
+ public const int QUEUE = 3;
+ /// <summary>
+ /// Temporary Queue Destination object
+ /// </summary>
+ public const int TEMPORARY_QUEUE = 4;
+
+ private const String TEMP_PREFIX = "{TD{";
+ private const String TEMP_POSTFIX = "}TD}";
+
+ private String physicalName = "";
+ private StringDictionary options = null;
+
+ private bool disposed = false;
+
+ /// <summary>
+ /// The Default Constructor
+ /// </summary>
+ protected Destination()
+ {
+ }
+
+ /// <summary>
+ /// Construct the Destination with a defined physical name;
+ /// </summary>
+ /// <param name="name"></param>
+ protected Destination(String name)
+ {
+ setPhysicalName(name);
+ }
+
+ ~Destination()
+ {
+ Dispose(false);
+ }
+
+ public void Dispose()
+ {
+ Dispose(true);
+ GC.SuppressFinalize(this);
+ }
+
+ private void Dispose(bool disposing)
+ {
+ if(disposed)
+ {
+ return;
+ }
+
+ if(disposing)
+ {
+ try
+ {
+ OnDispose();
+ }
+ catch(Exception ex)
+ {
+ Tracer.ErrorFormat("Exception disposing Destination {0}: {1}", this.physicalName, ex.Message);
+ }
+ }
+
+ disposed = true;
+ }
+
+ /// <summary>
+ /// Child classes can override this method to perform clean-up logic.
+ /// </summary>
+ protected virtual void OnDispose()
+ {
+ }
+
+ public bool IsTopic
+ {
+ get
+ {
+ int destinationType = GetDestinationType();
+ return TOPIC == destinationType
+ || TEMPORARY_TOPIC == destinationType;
+ }
+ }
+
+ public bool IsQueue
+ {
+ get
+ {
+ int destinationType = GetDestinationType();
+ return QUEUE == destinationType
+ || TEMPORARY_QUEUE == destinationType;
+ }
+ }
+
+ public bool IsTemporary
+ {
+ get
+ {
+ int destinationType = GetDestinationType();
+ return TEMPORARY_QUEUE == destinationType
+ || TEMPORARY_TOPIC == destinationType;
+ }
+ }
+
+ /// <summary>
+ /// Dictionary of name/value pairs representing option values specified
+ /// in the URI used to create this Destination. A null value is returned
+ /// if no options were specified.
+ /// </summary>
+ internal StringDictionary Options
+ {
+ get { return this.options; }
+ }
+
+ private void setPhysicalName(string name)
+ {
+ this.physicalName = name;
+
+ int p = name.IndexOf('?');
+ if(p >= 0)
+ {
+ String optstring = physicalName.Substring(p + 1);
+ this.physicalName = name.Substring(0, p);
+ options = URISupport.ParseQuery(optstring);
+ }
+ }
+
+ /// <summary>
+ /// </summary>
+ /// <param name="destination"></param>
+ /// <returns></returns>
+ public static Destination Transform(IDestination destination)
+ {
+ Destination result = null;
+ if(destination != null)
+ {
+ if(destination is Destination)
+ {
+ result = (Destination) destination;
+ }
+ else
+ {
+ if(destination is ITemporaryQueue)
+ {
+ result = new TempQueue(((IQueue) destination).QueueName);
+ }
+ else if(destination is ITemporaryTopic)
+ {
+ result = new TempTopic(((ITopic) destination).TopicName);
+ }
+ else if(destination is IQueue)
+ {
+ result = new Queue(((IQueue) destination).QueueName);
+ }
+ else if(destination is ITopic)
+ {
+ result = new Topic(((ITopic) destination).TopicName);
+ }
+ }
+ }
+ return result;
+ }
+
+ /// <summary>
+ /// Create a temporary name from the clientId
+ /// </summary>
+ /// <param name="clientId"></param>
+ /// <returns></returns>
+ public static String CreateTemporaryName(String clientId)
+ {
+ return TEMP_PREFIX + clientId + TEMP_POSTFIX;
+ }
+
+ /// <summary>
+ /// From a temporary destination find the clientId of the Connection that created it
+ /// </summary>
+ /// <param name="destination"></param>
+ /// <returns>the clientId or null if not a temporary destination</returns>
+ public static String GetClientId(Destination destination)
+ {
+ String answer = null;
+ if(destination != null && destination.IsTemporary)
+ {
+ String name = destination.PhysicalName;
+ int start = name.IndexOf(TEMP_PREFIX);
+ if(start >= 0)
+ {
+ start += TEMP_PREFIX.Length;
+ int stop = name.LastIndexOf(TEMP_POSTFIX);
+ if(stop > start && stop < name.Length)
+ {
+ answer = name.Substring(start, stop);
+ }
+ }
+ }
+ return answer;
+ }
+
+ /// <summary>
+ /// </summary>
+ /// <param name="o">object to compare</param>
+ /// <returns>1 if this is less than o else 0 if they are equal or -1 if this is less than o</returns>
+ public int CompareTo(Object o)
+ {
+ if(o is Destination)
+ {
+ return CompareTo((Destination) o);
+ }
+ return -1;
+ }
+
+ /// <summary>
+ /// Lets sort by name first then lets sort topics greater than queues
+ /// </summary>
+ /// <param name="that">another destination to compare against</param>
+ /// <returns>1 if this is less than o else 0 if they are equal or -1 if this is less than o</returns>
+ public int CompareTo(Destination that)
+ {
+ int answer = 0;
+ if(physicalName != that.physicalName)
+ {
+ if(physicalName == null)
+ {
+ return -1;
+ }
+ else if(that.physicalName == null)
+ {
+ return 1;
+ }
+ answer = physicalName.CompareTo(that.physicalName);
+ }
+
+ if(answer == 0)
+ {
+ if(IsTopic)
+ {
+ if(that.IsQueue)
+ {
+ return 1;
+ }
+ }
+ else
+ {
+ if(that.IsTopic)
+ {
+ return -1;
+ }
+ }
+ }
+ return answer;
+ }
+
+ /// <summary>
+ /// </summary>
+ /// <returns>Returns the Destination type</returns>
+ public abstract int GetDestinationType();
+
+ public String PhysicalName
+ {
+ get { return this.physicalName; }
+ set
+ {
+ this.physicalName = value;
+ }
+ }
+
+ /// <summary>
+ /// </summary>
+ /// <returns>string representation of this instance</returns>
+ public override String ToString()
+ {
+ switch(DestinationType)
+ {
+ case DestinationType.Topic:
+ return "topic://" + PhysicalName;
+
+ case DestinationType.TemporaryTopic:
+ return "temp-topic://" + PhysicalName;
+
+ case DestinationType.TemporaryQueue:
+ return "temp-queue://" + PhysicalName;
+
+ default:
+ return "queue://" + PhysicalName;
+ }
+ }
+
+ /// <summary>
+ /// </summary>
+ /// <returns>hashCode for this instance</returns>
+ public override int GetHashCode()
+ {
+ int answer = 37;
+
+ if(this.physicalName != null)
+ {
+ answer = physicalName.GetHashCode();
+ }
+ if(IsTopic)
+ {
+ answer ^= 0xfabfab;
+ }
+ return answer;
+ }
+
+ /// <summary>
+ /// if the object passed in is equivalent, return true
+ /// </summary>
+ /// <param name="obj">the object to compare</param>
+ /// <returns>true if this instance and obj are equivalent</returns>
+ public override bool Equals(Object obj)
+ {
+ bool result = this == obj;
+ if(!result && obj != null && obj is Destination)
+ {
+ Destination other = (Destination) obj;
+ result = this.GetDestinationType() == other.GetDestinationType()
+ && this.physicalName.Equals(other.physicalName);
+ }
+ return result;
+ }
+
+ /// <summary>
+ /// Factory method to create a child destination if this destination is a composite
+ /// </summary>
+ /// <param name="name"></param>
+ /// <returns>the created Destination</returns>
+ public abstract Destination CreateDestination(String name);
+
+ public abstract DestinationType DestinationType
+ {
+ get;
+ }
+
+ public virtual Object Clone()
+ {
+ // Since we are the lowest level base class, do a
+ // shallow copy which will include the derived classes.
+ // From here we would do deep cloning of other objects
+ // if we had any.
+ return this.MemberwiseClone();
+ }
+ }
+}
+
diff --git a/src/test/csharp/Commands/MapMessage.cs b/src/test/csharp/Commands/MapMessage.cs
new file mode 100644
index 0000000..4ba9751
--- /dev/null
+++ b/src/test/csharp/Commands/MapMessage.cs
@@ -0,0 +1,90 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.IO;
+using Apache.NMS;
+using Apache.NMS.Util;
+
+namespace Apache.NMS.Commands
+{
+ public class MapMessage : Message, IMapMessage
+ {
+ private PrimitiveMap body;
+ private PrimitiveMapInterceptor typeConverter;
+
+ public MapMessage() : base()
+ {
+ }
+
+ public MapMessage(PrimitiveMap body) : base()
+ {
+ this.body = body;
+ this.typeConverter = new PrimitiveMapInterceptor(this, this.body);
+ }
+
+ public override void ClearBody()
+ {
+ this.body = null;
+ this.typeConverter = null;
+ base.ClearBody();
+ }
+
+ public override bool ReadOnlyBody
+ {
+ get { return base.ReadOnlyBody; }
+
+ set
+ {
+ if(this.typeConverter != null)
+ {
+ this.typeConverter.ReadOnly = true;
+ }
+
+ base.ReadOnlyBody = value;
+ }
+ }
+
+
+ public IPrimitiveMap Body
+ {
+ get
+ {
+ if(this.body == null)
+ {
+ this.body = new PrimitiveMap();
+ this.typeConverter = new PrimitiveMapInterceptor(this, this.body);
+ }
+
+ return this.typeConverter;
+ }
+
+ set
+ {
+ this.body = value as PrimitiveMap;
+ if(value != null)
+ {
+ this.typeConverter = new PrimitiveMapInterceptor(this, value);
+ }
+ else
+ {
+ this.typeConverter = null;
+ }
+ }
+ }
+ }
+}
diff --git a/src/test/csharp/Commands/Message.cs b/src/test/csharp/Commands/Message.cs
new file mode 100644
index 0000000..5cadd5f
--- /dev/null
+++ b/src/test/csharp/Commands/Message.cs
@@ -0,0 +1,329 @@
+/*
+ * 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.
+ */
+
+using System;
+using System.Collections;
+
+using Apache.NMS.Util;
+
+namespace Apache.NMS.Commands
+{
+ public class Message : IMessage, ICloneable
+ {
+ private IDestination destination;
+ private string transactionId;
+ private string messageId;
+ private string groupID;
+ private int groupSequence;
+ private string correlationId;
+ private bool persistent;
+ private long expiration;
+ private byte priority;
+ private IDestination replyTo;
+ private long timestamp;
+ private string type;
+ private bool redelivered;
+ private byte[] content;
+ private bool readOnlyMsgProperties;
+ private bool readOnlyMsgBody;
+
+ private MessagePropertyIntercepter propertyHelper;
+ private PrimitiveMap properties;
+
+ ///
+ /// <summery>
+ /// Clone this object and return a new instance that the caller now owns.
+ /// </summery>
+ ///
+ public virtual Object Clone()
+ {
+ // Since we are the lowest level base class, do a
+ // shallow copy which will include the derived classes.
+ // From here we would do deep cloning of other objects
+ // if we had any.
+ Message o = (Message) this.MemberwiseClone();
+
+ if(this.messageId != null)
+ {
+ o.NMSMessageId = (string) this.messageId.Clone();
+ }
+
+ return o;
+ }
+
+ ///
+ /// <summery>
+ /// Returns a string containing the information for this DataStructure
+ /// such as its type and value of its elements.
+ /// </summery>
+ ///
+ public override string ToString()
+ {
+ return GetType().Name + "[" +
+ "Destination=" + destination + ", " +
+ "TransactionId=" + transactionId + ", " +
+ "MessageId=" + messageId + ", " +
+ "GroupID=" + groupID + ", " +
+ "GroupSequence=" + groupSequence + ", " +
+ "CorrelationId=" + correlationId + ", " +
+ "Expiration=" + expiration + ", " +
+ "Priority=" + priority + ", " +
+ "ReplyTo=" + replyTo + ", " +
+ "Timestamp=" + timestamp + ", " +
+ "Type=" + type + ", " +
+ "Redelivered=" + redelivered +
+ "]";
+ }
+
+ public void Acknowledge()
+ {
+ }
+
+ public virtual void ClearBody()
+ {
+ this.content = null;
+ }
+
+ public virtual void ClearProperties()
+ {
+ this.properties.Clear();
+ }
+
+ protected void FailIfReadOnlyBody()
+ {
+ if(ReadOnlyBody == true)
+ {
+ throw new MessageNotWriteableException("Message is in Read-Only mode.");
+ }
+ }
+
+ protected void FailIfWriteOnlyBody()
+ {
+ if(ReadOnlyBody == false)
+ {
+ throw new MessageNotReadableException("Message is in Write-Only mode.");
+ }
+ }
+
+ #region Properties
+
+ public string TransactionId
+ {
+ get { return this.transactionId; }
+ set { this.transactionId = value; }
+ }
+
+ public byte[] Content
+ {
+ get { return content; }
+ set { this.content = value; }
+ }
+
+ public virtual bool ReadOnlyProperties
+ {
+ get { return this.readOnlyMsgProperties; }
+ set { this.readOnlyMsgProperties = value; }
+ }
+
+ public virtual bool ReadOnlyBody
+ {
+ get { return this.readOnlyMsgBody; }
+ set { this.readOnlyMsgBody = value; }
+ }
+
+ public IPrimitiveMap Properties
+ {
+ get
+ {
+ if(null == properties)
+ {
+ properties = new PrimitiveMap();
+ propertyHelper = new MessagePropertyIntercepter(this, properties, this.ReadOnlyProperties);
+ propertyHelper.AllowByteArrays = false;
+ }
+
+ return propertyHelper;
+ }
+ }
+
+ /// <summary>
+ /// The correlation ID used to correlate messages with conversations or long running business processes
+ /// </summary>
+ public string NMSCorrelationID
+ {
+ get { return correlationId; }
+ set { correlationId = value; }
+ }
+
+ /// <summary>
+ /// The destination of the message
+ /// </summary>
+ public IDestination NMSDestination
+ {
+ get { return destination; }
+ set { this.destination = Destination.Transform(value); }
+ }
+
+ private TimeSpan timeToLive = TimeSpan.FromMilliseconds(0);
+ /// <summary>
+ /// The time in milliseconds that this message should expire in
+ /// </summary>
+ public TimeSpan NMSTimeToLive
+ {
+ get { return timeToLive; }
+
+ set
+ {
+ timeToLive = value;
+ if(timeToLive.TotalMilliseconds > 0)
+ {
+ long timeStamp = timestamp;
+
+ if(timeStamp == 0)
+ {
+ timeStamp = DateUtils.ToJavaTimeUtc(DateTime.UtcNow);
+ }
+
+ expiration = timeStamp + (long) timeToLive.TotalMilliseconds;
+ }
+ else
+ {
+ expiration = 0;
+ }
+ }
+ }
+
+ /// <summary>
+ /// The timestamp the broker added to the message
+ /// </summary>
+ public DateTime NMSTimestamp
+ {
+ get { return DateUtils.ToDateTime(timestamp); }
+ set
+ {
+ timestamp = DateUtils.ToJavaTimeUtc(value);
+ if(timeToLive.TotalMilliseconds > 0)
+ {
+ expiration = timestamp + (long) timeToLive.TotalMilliseconds;
+ }
+ }
+ }
+
+ /// <summary>
+ /// The message ID which is set by the provider
+ /// </summary>
+ public string NMSMessageId
+ {
+ get { return this.messageId; }
+ set { this.messageId = value; }
+ }
+
+ /// <summary>
+ /// Whether or not this message is persistent
+ /// </summary>
+ public MsgDeliveryMode NMSDeliveryMode
+ {
+ get { return (persistent ? MsgDeliveryMode.Persistent : MsgDeliveryMode.NonPersistent); }
+ set { persistent = (MsgDeliveryMode.Persistent == value); }
+ }
+
+ /// <summary>
+ /// The Priority on this message
+ /// </summary>
+ public MsgPriority NMSPriority
+ {
+ get { return (MsgPriority) priority; }
+ set { priority = (byte) value; }
+ }
+
+ /// <summary>
+ /// Returns true if this message has been redelivered to this or another consumer before being acknowledged successfully.
+ /// </summary>
+ public bool NMSRedelivered
+ {
+ get { return this.redelivered; }
+ set { this.redelivered = value; }
+ }
+
+ /// <summary>
+ /// The destination that the consumer of this message should send replies to
+ /// </summary>
+ public IDestination NMSReplyTo
+ {
+ get { return replyTo; }
+ set { replyTo = Destination.Transform(value); }
+ }
+
+ /// <summary>
+ /// The type name of this message
+ /// </summary>
+ public string NMSType
+ {
+ get { return type; }
+ set { type = value; }
+ }
+
+ #endregion
+
+ #region NMS Extension headers
+
+ /// <summary>
+ /// Returns the number of times this message has been redelivered to other consumers without being acknowledged successfully.
+ /// </summary>
+ public int NMSXDeliveryCount
+ {
+ get { return 0; }
+ }
+
+ /// <summary>
+ /// The Message Group ID used to group messages together to the same consumer for the same group ID value
+ /// </summary>
+ public string NMSXGroupID
+ {
+ get { return groupID; }
+ set { groupID = value; }
+ }
+ /// <summary>
+ /// The Message Group Sequence counter to indicate the position in a group
+ /// </summary>
+ public int NMSXGroupSeq
+ {
+ get { return groupSequence; }
+ set { groupSequence = value; }
+ }
+
+ /// <summary>
+ /// Returns the ID of the producers transaction
+ /// </summary>
+ public string NMSXProducerTXID
+ {
+ get
+ {
+ if(null != transactionId)
+ {
+ return transactionId;
+ }
+
+ return String.Empty;
+ }
+ }
+
+ #endregion
+
+ };
+}
+
diff --git a/src/test/csharp/Commands/ObjectMessage.cs b/src/test/csharp/Commands/ObjectMessage.cs
new file mode 100644
index 0000000..ba68ee0
--- /dev/null
+++ b/src/test/csharp/Commands/ObjectMessage.cs
@@ -0,0 +1,44 @@
+/*
+* 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.
+*/
+
+using System;
+using System.Collections;
+using System.IO;
+
+using Apache.NMS;
+
+namespace Apache.NMS.Commands
+{
+ public class ObjectMessage : Message, IObjectMessage
+ {
+ private object body;
+
+ public override string ToString() {
+ return GetType().Name + "["
+ + " ]";
+ }
+
+ // Properties
+
+ public object Body
+ {
+ get { return body; }
+ set { body = value; }
+ }
+
+ }
+}
diff --git a/src/test/csharp/Commands/Queue.cs b/src/test/csharp/Commands/Queue.cs
new file mode 100644
index 0000000..c0dd5f9
--- /dev/null
+++ b/src/test/csharp/Commands/Queue.cs
@@ -0,0 +1,75 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+using System;
+
+namespace Apache.NMS.Commands
+{
+ /// <summary>
+ /// Summary description for Queue.
+ /// </summary>
+ public class Queue : Destination, IQueue
+ {
+ public Queue()
+ : base()
+ {
+ }
+
+ public Queue(String name)
+ : base(name)
+ {
+ }
+
+ override public DestinationType DestinationType
+ {
+ get
+ {
+ return DestinationType.Queue;
+ }
+ }
+
+ public String QueueName
+ {
+ get { return PhysicalName; }
+ }
+
+ public override int GetDestinationType()
+ {
+ return QUEUE;
+ }
+
+ public override Destination CreateDestination(String name)
+ {
+ return new Queue(name);
+ }
+
+ public override Object Clone()
+ {
+ // Since we are a derived class use the base's Clone()
+ // to perform the shallow copy. Since it is shallow it
+ // will include our derived class. Since we are derived,
+ // this method is an override.
+ Queue o = (Queue) base.Clone();
+
+ // Now do the deep work required
+ // If any new variables are added then this routine will
+ // likely need updating
+
+ return o;
+ }
+ }
+}
+
diff --git a/src/test/csharp/Commands/StreamMessage.cs b/src/test/csharp/Commands/StreamMessage.cs
new file mode 100644
index 0000000..1195a12
--- /dev/null
+++ b/src/test/csharp/Commands/StreamMessage.cs
@@ -0,0 +1,901 @@
+/*
+ * 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.
+ */
+
+using System;
+using System.IO;
+using System.Collections;
+
+using Apache.NMS;
+using Apache.NMS.Util;
+
+namespace Apache.NMS.Commands
+{
+ public class StreamMessage : Message, IStreamMessage
+ {
+ private EndianBinaryReader dataIn = null;
+ private EndianBinaryWriter dataOut = null;
+ private MemoryStream byteBuffer = null;
+ private int bytesRemaining = -1;
+
+ public bool ReadBoolean()
+ {
+ InitializeReading();
+
+ try
+ {
+ long startingPos = this.byteBuffer.Position;
+ try
+ {
+ int type = this.dataIn.ReadByte();
+
+ if(type == PrimitiveMap.BOOLEAN_TYPE)
+ {
+ return this.dataIn.ReadBoolean();
+ }
+ else if(type == PrimitiveMap.STRING_TYPE)
+ {
+ return Boolean.Parse(this.dataIn.ReadString16());
+ }
+ else if(type == PrimitiveMap.NULL)
+ {
+ this.byteBuffer.Seek(startingPos, SeekOrigin.Begin);
+ throw new NMSException("Cannot convert Null type to a bool");
+ }
+ else
+ {
+ this.byteBuffer.Seek(startingPos, SeekOrigin.Begin);
+ throw new MessageFormatException("Value is not a Boolean type.");
+ }
+ }
+ catch(FormatException e)
+ {
+ this.byteBuffer.Seek(startingPos, SeekOrigin.Begin);
+ throw NMSExceptionSupport.CreateMessageFormatException(e);
+ }
+ }
+ catch(EndOfStreamException e)
+ {
+ throw NMSExceptionSupport.CreateMessageEOFException(e);
+ }
+ catch(IOException e)
+ {
+ throw NMSExceptionSupport.CreateMessageFormatException(e);
+ }
+ }
+
+ public byte ReadByte()
+ {
+ InitializeReading();
+
+ try
+ {
+ long startingPos = this.byteBuffer.Position;
+ try
+ {
+ int type = this.dataIn.ReadByte();
+
+ if(type == PrimitiveMap.BYTE_TYPE)
+ {
+ return this.dataIn.ReadByte();
+ }
+ else if(type == PrimitiveMap.STRING_TYPE)
+ {
+ return Byte.Parse(this.dataIn.ReadString16());
+ }
+ else if(type == PrimitiveMap.NULL)
+ {
+ this.byteBuffer.Seek(startingPos, SeekOrigin.Begin);
+ throw new NMSException("Cannot convert Null type to a byte");
+ }
+ else
+ {
+ this.byteBuffer.Seek(startingPos, SeekOrigin.Begin);
+ throw new MessageFormatException("Value is not a Byte type.");
+ }
+ }
+ catch(FormatException e)
+ {
+ this.byteBuffer.Seek(startingPos, SeekOrigin.Begin);
+ throw NMSExceptionSupport.CreateMessageFormatException(e);
+ }
+ }
+ catch(EndOfStreamException e)
+ {
+ throw NMSExceptionSupport.CreateMessageEOFException(e);
+ }
+ catch(IOException e)
+ {
+ throw NMSExceptionSupport.CreateMessageFormatException(e);
+ }
+ }
+
+ public char ReadChar()
+ {
+ InitializeReading();
+
+ try
+ {
+ long startingPos = this.byteBuffer.Position;
+ try
+ {
+ int type = this.dataIn.ReadByte();
+
+ if(type == PrimitiveMap.CHAR_TYPE)
+ {
+ return this.dataIn.ReadChar();
+ }
+ else if(type == PrimitiveMap.NULL)
+ {
+ this.byteBuffer.Seek(startingPos, SeekOrigin.Begin);
+ throw new NMSException("Cannot convert Null type to a char");
+ }
+ else
+ {
+ this.byteBuffer.Seek(startingPos, SeekOrigin.Begin);
+ throw new MessageFormatException("Value is not a Char type.");
+ }
+ }
+ catch(FormatException e)
+ {
+ this.byteBuffer.Seek(startingPos, SeekOrigin.Begin);
+ throw NMSExceptionSupport.CreateMessageFormatException(e);
+ }
+ }
+ catch(EndOfStreamException e)
+ {
+ throw NMSExceptionSupport.CreateMessageEOFException(e);
+ }
+ catch(IOException e)
+ {
+ throw NMSExceptionSupport.CreateMessageFormatException(e);
+ }
+ }
+
+ public short ReadInt16()
+ {
+ InitializeReading();
+
+ try
+ {
+ long startingPos = this.byteBuffer.Position;
+ try
+ {
+ int type = this.dataIn.ReadByte();
+
+ if(type == PrimitiveMap.SHORT_TYPE)
+ {
+ return this.dataIn.ReadInt16();
+ }
+ else if(type == PrimitiveMap.BYTE_TYPE)
+ {
+ return this.dataIn.ReadByte();
+ }
+ else if(type == PrimitiveMap.STRING_TYPE)
+ {
+ return Int16.Parse(this.dataIn.ReadString16());
+ }
+ else if(type == PrimitiveMap.NULL)
+ {
+ this.byteBuffer.Seek(startingPos, SeekOrigin.Begin);
+ throw new NMSException("Cannot convert Null type to a short");
+ }
+ else
+ {
+ this.byteBuffer.Seek(startingPos, SeekOrigin.Begin);
+ throw new MessageFormatException("Value is not a Int16 type.");
+ }
+ }
+ catch(FormatException e)
+ {
+ this.byteBuffer.Seek(startingPos, SeekOrigin.Begin);
+ throw NMSExceptionSupport.CreateMessageFormatException(e);
+ }
+ }
+ catch(EndOfStreamException e)
+ {
+ throw NMSExceptionSupport.CreateMessageEOFException(e);
+ }
+ catch(IOException e)
+ {
+ throw NMSExceptionSupport.CreateMessageFormatException(e);
+ }
+ }
+
+ public int ReadInt32()
+ {
+ InitializeReading();
+
+ try
+ {
+ long startingPos = this.byteBuffer.Position;
+ try
+ {
+ int type = this.dataIn.ReadByte();
+
+ if(type == PrimitiveMap.INTEGER_TYPE)
+ {
+ return this.dataIn.ReadInt32();
+ }
+ else if(type == PrimitiveMap.SHORT_TYPE)
+ {
+ return this.dataIn.ReadInt16();
+ }
+ else if(type == PrimitiveMap.BYTE_TYPE)
+ {
+ return this.dataIn.ReadByte();
+ }
+ else if(type == PrimitiveMap.STRING_TYPE)
+ {
+ return Int32.Parse(this.dataIn.ReadString16());
+ }
+ else if(type == PrimitiveMap.NULL)
+ {
+ this.byteBuffer.Seek(startingPos, SeekOrigin.Begin);
+ throw new NMSException("Cannot convert Null type to a int");
+ }
+ else
+ {
+ this.byteBuffer.Seek(startingPos, SeekOrigin.Begin);
+ throw new MessageFormatException("Value is not a Int32 type.");
+ }
+ }
+ catch(FormatException e)
+ {
+ this.byteBuffer.Seek(startingPos, SeekOrigin.Begin);
+ throw NMSExceptionSupport.CreateMessageFormatException(e);
+ }
+ }
+ catch(EndOfStreamException e)
+ {
+ throw NMSExceptionSupport.CreateMessageEOFException(e);
+ }
+ catch(IOException e)
+ {
+ throw NMSExceptionSupport.CreateMessageFormatException(e);
+ }
+ }
+
+ public long ReadInt64()
+ {
+ InitializeReading();
+
+ try
+ {
+ long startingPos = this.byteBuffer.Position;
+ try
+ {
+ int type = this.dataIn.ReadByte();
+
+ if(type == PrimitiveMap.LONG_TYPE)
+ {
+ return this.dataIn.ReadInt64();
+ }
+ else if(type == PrimitiveMap.INTEGER_TYPE)
+ {
+ return this.dataIn.ReadInt32();
+ }
+ else if(type == PrimitiveMap.SHORT_TYPE)
+ {
+ return this.dataIn.ReadInt16();
+ }
+ else if(type == PrimitiveMap.BYTE_TYPE)
+ {
+ return this.dataIn.ReadByte();
+ }
+ else if(type == PrimitiveMap.STRING_TYPE)
+ {
+ return Int64.Parse(this.dataIn.ReadString16());
+ }
+ else if(type == PrimitiveMap.NULL)
+ {
+ this.byteBuffer.Seek(startingPos, SeekOrigin.Begin);
+ throw new NMSException("Cannot convert Null type to a long");
+ }
+ else
+ {
+ this.byteBuffer.Seek(startingPos, SeekOrigin.Begin);
+ throw new MessageFormatException("Value is not a Int64 type.");
+ }
+ }
+ catch(FormatException e)
+ {
+ this.byteBuffer.Seek(startingPos, SeekOrigin.Begin);
+ throw NMSExceptionSupport.CreateMessageFormatException(e);
+ }
+ }
+ catch(EndOfStreamException e)
+ {
+ throw NMSExceptionSupport.CreateMessageEOFException(e);
+ }
+ catch(IOException e)
+ {
+ throw NMSExceptionSupport.CreateMessageFormatException(e);
+ }
+ }
+
+ public float ReadSingle()
+ {
+ InitializeReading();
+
+ try
+ {
+ long startingPos = this.byteBuffer.Position;
+ try
+ {
+ int type = this.dataIn.ReadByte();
+
+ if(type == PrimitiveMap.FLOAT_TYPE)
+ {
+ return this.dataIn.ReadSingle();
+ }
+ else if(type == PrimitiveMap.STRING_TYPE)
+ {
+ return Single.Parse(this.dataIn.ReadString16());
+ }
+ else if(type == PrimitiveMap.NULL)
+ {
+ this.byteBuffer.Seek(startingPos, SeekOrigin.Begin);
+ throw new NMSException("Cannot convert Null type to a float");
+ }
+ else
+ {
+ this.byteBuffer.Seek(startingPos, SeekOrigin.Begin);
+ throw new MessageFormatException("Value is not a Single type.");
+ }
+ }
+ catch(FormatException e)
+ {
+ this.byteBuffer.Seek(startingPos, SeekOrigin.Begin);
+ throw NMSExceptionSupport.CreateMessageFormatException(e);
+ }
+ }
+ catch(EndOfStreamException e)
+ {
+ throw NMSExceptionSupport.CreateMessageEOFException(e);
+ }
+ catch(IOException e)
+ {
+ throw NMSExceptionSupport.CreateMessageFormatException(e);
+ }
+ }
+
+ public double ReadDouble()
+ {
+ InitializeReading();
+
+ try
+ {
+ long startingPos = this.byteBuffer.Position;
+ try
+ {
+ int type = this.dataIn.ReadByte();
+
+ if(type == PrimitiveMap.DOUBLE_TYPE)
+ {
+ return this.dataIn.ReadDouble();
+ }
+ else if(type == PrimitiveMap.FLOAT_TYPE)
+ {
+ return this.dataIn.ReadSingle();
+ }
+ else if(type == PrimitiveMap.STRING_TYPE)
+ {
+ return Single.Parse(this.dataIn.ReadString16());
+ }
+ else if(type == PrimitiveMap.NULL)
+ {
+ this.byteBuffer.Seek(startingPos, SeekOrigin.Begin);
+ throw new NMSException("Cannot convert Null type to a double");
+ }
+ else
+ {
+ this.byteBuffer.Seek(startingPos, SeekOrigin.Begin);
+ throw new MessageFormatException("Value is not a Double type.");
+ }
+ }
+ catch(FormatException e)
+ {
+ this.byteBuffer.Seek(startingPos, SeekOrigin.Begin);
+ throw NMSExceptionSupport.CreateMessageFormatException(e);
+ }
+ }
+ catch(EndOfStreamException e)
+ {
+ throw NMSExceptionSupport.CreateMessageEOFException(e);
+ }
+ catch(IOException e)
+ {
+ throw NMSExceptionSupport.CreateMessageFormatException(e);
+ }
+ }
+
+ public string ReadString()
+ {
+ InitializeReading();
+
+ long startingPos = this.byteBuffer.Position;
+
+ try
+ {
+ int type = this.dataIn.ReadByte();
+
+ if(type == PrimitiveMap.BIG_STRING_TYPE)
+ {
+ return this.dataIn.ReadString32();
+ }
+ else if(type == PrimitiveMap.STRING_TYPE)
+ {
+ return this.dataIn.ReadString16();
+ }
+ else if(type == PrimitiveMap.LONG_TYPE)
+ {
+ return this.dataIn.ReadInt64().ToString();
+ }
+ else if(type == PrimitiveMap.INTEGER_TYPE)
+ {
+ return this.dataIn.ReadInt32().ToString();
+ }
+ else if(type == PrimitiveMap.SHORT_TYPE)
+ {
+ return this.dataIn.ReadInt16().ToString();
+ }
+ else if(type == PrimitiveMap.FLOAT_TYPE)
+ {
+ return this.dataIn.ReadSingle().ToString();
+ }
+ else if(type == PrimitiveMap.DOUBLE_TYPE)
+ {
+ return this.dataIn.ReadDouble().ToString();
+ }
+ else if(type == PrimitiveMap.CHAR_TYPE)
+ {
+ return this.dataIn.ReadChar().ToString();
+ }
+ else if(type == PrimitiveMap.BYTE_TYPE)
+ {
+ return this.dataIn.ReadByte().ToString();
+ }
+ else if(type == PrimitiveMap.BOOLEAN_TYPE)
+ {
+ return this.dataIn.ReadBoolean().ToString();
+ }
+ else if(type == PrimitiveMap.NULL)
+ {
+ return null;
+ }
+ else
+ {
+ this.byteBuffer.Seek(startingPos, SeekOrigin.Begin);
+ throw new MessageFormatException("Value is not a known type.");
+ }
+ }
+ catch(FormatException e)
+ {
+ this.byteBuffer.Seek(startingPos, SeekOrigin.Begin);
+ throw NMSExceptionSupport.CreateMessageFormatException(e);
+ }
+ catch(EndOfStreamException e)
+ {
+ throw NMSExceptionSupport.CreateMessageEOFException(e);
+ }
+ catch(IOException e)
+ {
+ throw NMSExceptionSupport.CreateMessageFormatException(e);
+ }
+ }
+
+ public int ReadBytes(byte[] value)
+ {
+ InitializeReading();
+
+ if(value == null)
+ {
+ throw new NullReferenceException("Passed Byte Array is null");
+ }
+
+ try
+ {
+ if(this.bytesRemaining == -1)
+ {
+ long startingPos = this.byteBuffer.Position;
+ byte type = this.dataIn.ReadByte();
+
+ if(type != PrimitiveMap.BYTE_ARRAY_TYPE)
+ {
+ this.byteBuffer.Seek(startingPos, SeekOrigin.Begin);
+ throw new MessageFormatException("Not a byte array");
+ }
+
+ this.bytesRemaining = this.dataIn.ReadInt32();
+ }
+ else if(this.bytesRemaining == 0)
+ {
+ this.bytesRemaining = -1;
+ return -1;
+ }
+
+ if(value.Length <= this.bytesRemaining)
+ {
+ // small buffer
+ this.bytesRemaining -= value.Length;
+ this.dataIn.Read(value, 0, value.Length);
+ return value.Length;
+ }
+ else
+ {
+ // big buffer
+ int rc = this.dataIn.Read(value, 0, this.bytesRemaining);
+ this.bytesRemaining = 0;
+ return rc;
+ }
+ }
+ catch(EndOfStreamException ex)
+ {
+ throw NMSExceptionSupport.CreateMessageEOFException(ex);
+ }
+ catch(IOException ex)
+ {
+ throw NMSExceptionSupport.CreateMessageFormatException(ex);
+ }
+ }
+
+ public Object ReadObject()
+ {
+ InitializeReading();
+
+ long startingPos = this.byteBuffer.Position;
+
+ try
+ {
+ int type = this.dataIn.ReadByte();
+
+ if(type == PrimitiveMap.BIG_STRING_TYPE)
+ {
+ return this.dataIn.ReadString32();
+ }
+ else if(type == PrimitiveMap.STRING_TYPE)
+ {
+ return this.dataIn.ReadString16();
+ }
+ else if(type == PrimitiveMap.LONG_TYPE)
+ {
+ return this.dataIn.ReadInt64();
+ }
+ else if(type == PrimitiveMap.INTEGER_TYPE)
+ {
+ return this.dataIn.ReadInt32();
+ }
+ else if(type == PrimitiveMap.SHORT_TYPE)
+ {
+ return this.dataIn.ReadInt16();
+ }
+ else if(type == PrimitiveMap.FLOAT_TYPE)
+ {
+ return this.dataIn.ReadSingle();
+ }
+ else if(type == PrimitiveMap.DOUBLE_TYPE)
+ {
+ return this.dataIn.ReadDouble();
+ }
+ else if(type == PrimitiveMap.CHAR_TYPE)
+ {
+ return this.dataIn.ReadChar();
+ }
+ else if(type == PrimitiveMap.BYTE_TYPE)
+ {
+ return this.dataIn.ReadByte();
+ }
+ else if(type == PrimitiveMap.BOOLEAN_TYPE)
+ {
+ return this.dataIn.ReadBoolean();
+ }
+ else if(type == PrimitiveMap.BYTE_ARRAY_TYPE)
+ {
+ int length = this.dataIn.ReadInt32();
+ byte[] data = new byte[length];
+ this.dataIn.Read(data, 0, length);
+ return data;
+ }
+ else if(type == PrimitiveMap.NULL)
+ {
+ return null;
+ }
+ else
+ {
+ this.byteBuffer.Seek(startingPos, SeekOrigin.Begin);
+ throw new MessageFormatException("Value is not a known type.");
+ }
+ }
+ catch(FormatException e)
+ {
+ this.byteBuffer.Seek(startingPos, SeekOrigin.Begin);
+ throw NMSExceptionSupport.CreateMessageFormatException(e);
+ }
+ catch(EndOfStreamException e)
+ {
+ throw NMSExceptionSupport.CreateMessageEOFException(e);
+ }
+ catch(IOException e)
+ {
+ throw NMSExceptionSupport.CreateMessageFormatException(e);
+ }
+ }
+
+ public void WriteBoolean(bool value)
+ {
+ InitializeWriting();
+ try
+ {
+ this.dataOut.Write(PrimitiveMap.BOOLEAN_TYPE);
+ this.dataOut.Write(value);
+ }
+ catch(IOException e)
+ {
+ NMSExceptionSupport.Create(e);
+ }
+ }
+
+ public void WriteByte(byte value)
+ {
+ InitializeWriting();
+ try
+ {
+ this.dataOut.Write(PrimitiveMap.BYTE_TYPE);
+ this.dataOut.Write(value);
+ }
+ catch(IOException e)
+ {
+ NMSExceptionSupport.Create(e);
+ }
+ }
+
+ public void WriteBytes(byte[] value)
+ {
+ InitializeWriting();
+ this.WriteBytes(value, 0, value.Length);
+ }
+
+ public void WriteBytes(byte[] value, int offset, int length)
+ {
+ InitializeWriting();
+ try
+ {
+ this.dataOut.Write(PrimitiveMap.BYTE_ARRAY_TYPE);
+ this.dataOut.Write((int) length);
+ this.dataOut.Write(value, offset, length);
+ }
+ catch(IOException e)
+ {
+ NMSExceptionSupport.Create(e);
+ }
+ }
+
+ public void WriteChar(char value)
+ {
+ InitializeWriting();
+ try
+ {
+ this.dataOut.Write(PrimitiveMap.CHAR_TYPE);
+ this.dataOut.Write(value);
+ }
+ catch(IOException e)
+ {
+ NMSExceptionSupport.Create(e);
+ }
+ }
+
+ public void WriteInt16(short value)
+ {
+ InitializeWriting();
+ try
+ {
+ this.dataOut.Write(PrimitiveMap.SHORT_TYPE);
+ this.dataOut.Write(value);
+ }
+ catch(IOException e)
+ {
+ NMSExceptionSupport.Create(e);
+ }
+ }
+
+ public void WriteInt32(int value)
+ {
+ InitializeWriting();
+ try
+ {
+ this.dataOut.Write(PrimitiveMap.INTEGER_TYPE);
+ this.dataOut.Write(value);
+ }
+ catch(IOException e)
+ {
+ NMSExceptionSupport.Create(e);
+ }
+ }
+
+ public void WriteInt64(long value)
+ {
+ InitializeWriting();
+ try
+ {
+ this.dataOut.Write(PrimitiveMap.LONG_TYPE);
+ this.dataOut.Write(value);
+ }
+ catch(IOException e)
+ {
+ NMSExceptionSupport.Create(e);
+ }
+ }
+
+ public void WriteSingle(float value)
+ {
+ InitializeWriting();
+ try
+ {
+ this.dataOut.Write(PrimitiveMap.FLOAT_TYPE);
+ this.dataOut.Write(value);
+ }
+ catch(IOException e)
+ {
+ NMSExceptionSupport.Create(e);
+ }
+ }
+
+ public void WriteDouble(double value)
+ {
+ InitializeWriting();
+ try
+ {
+ this.dataOut.Write(PrimitiveMap.DOUBLE_TYPE);
+ this.dataOut.Write(value);
+ }
+ catch(IOException e)
+ {
+ NMSExceptionSupport.Create(e);
+ }
+ }
+
+ public void WriteString(string value)
+ {
+ InitializeWriting();
+ try
+ {
+ if( value.Length > 8192 )
+ {
+ this.dataOut.Write(PrimitiveMap.BIG_STRING_TYPE);
+ this.dataOut.WriteString32(value);
+ }
+ else
+ {
+ this.dataOut.Write(PrimitiveMap.STRING_TYPE);
+ this.dataOut.WriteString16(value);
+ }
+ }
+ catch(IOException e)
+ {
+ NMSExceptionSupport.Create(e);
+ }
+ }
+
+ public void WriteObject(Object value)
+ {
+ InitializeWriting();
+ if( value is System.Byte )
+ {
+ this.WriteByte( (byte) value );
+ }
+ else if( value is Char )
+ {
+ this.WriteChar( (char) value );
+ }
+ else if( value is Boolean )
+ {
+ this.WriteBoolean( (bool) value );
+ }
+ else if( value is Int16 )
+ {
+ this.WriteInt16( (short) value );
+ }
+ else if( value is Int32 )
+ {
+ this.WriteInt32( (int) value );
+ }
+ else if( value is Int64 )
+ {
+ this.WriteInt64( (long) value );
+ }
+ else if( value is Single )
+ {
+ this.WriteSingle( (float) value );
+ }
+ else if( value is Double )
+ {
+ this.WriteDouble( (double) value );
+ }
+ else if( value is byte[] )
+ {
+ this.WriteBytes( (byte[]) value );
+ }
+ else if( value is String )
+ {
+ this.WriteString( (string) value );
+ }
+ else
+ {
+ throw new MessageFormatException("Cannot write non-primitive type:" + value.GetType());
+ }
+ }
+
+ public override Object Clone()
+ {
+ StoreContent();
+ return base.Clone();
+ }
+
+ public override void ClearBody()
+ {
+ base.ClearBody();
+ this.byteBuffer = null;
+ this.dataIn = null;
+ this.dataOut = null;
+ this.bytesRemaining = -1;
+ }
+
+ public void Reset()
+ {
+ StoreContent();
+ this.dataIn = null;
+ this.dataOut = null;
+ this.byteBuffer = null;
+ this.bytesRemaining = -1;
+ this.ReadOnlyBody = true;
+ }
+
+ private void InitializeReading()
+ {
+ FailIfWriteOnlyBody();
+ if(this.dataIn == null)
+ {
+ this.byteBuffer = new MemoryStream(this.Content, false);
+ this.dataIn = new EndianBinaryReader(this.byteBuffer);
+ }
+ }
+
+ private void InitializeWriting()
+ {
+ FailIfReadOnlyBody();
+ if(this.dataOut == null)
+ {
+ this.byteBuffer = new MemoryStream();
+ this.dataOut = new EndianBinaryWriter(this.byteBuffer);
+ }
+ }
+
+ private void StoreContent()
+ {
+ if( dataOut != null)
+ {
+ dataOut.Close();
+
+ this.Content = byteBuffer.ToArray();
+ this.dataOut = null;
+ this.byteBuffer = null;
+ }
+ }
+
+ }
+}
+
diff --git a/src/test/csharp/Commands/TempDestination.cs b/src/test/csharp/Commands/TempDestination.cs
new file mode 100644
index 0000000..6e2e63f
--- /dev/null
+++ b/src/test/csharp/Commands/TempDestination.cs
@@ -0,0 +1,70 @@
+/*
+ * 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.
+ */
+
+using System;
+
+namespace Apache.NMS.Commands
+{
+ public abstract class TempDestination : Destination
+ {
+ /// <summary>
+ /// Method CreateDestination
+ /// </summary>
+ /// <returns>An Destination</returns>
+ /// <param name="name">A String</param>
+ public override Destination CreateDestination(String name)
+ {
+ return null;
+ }
+
+ abstract override public DestinationType DestinationType
+ {
+ get;
+ }
+
+ public TempDestination()
+ : base()
+ {
+ }
+
+ public TempDestination(String name)
+ : base(name)
+ {
+ }
+
+ public override Object Clone()
+ {
+ // Since we are a derived class use the base's Clone()
+ // to perform the shallow copy. Since it is shallow it
+ // will include our derived class. Since we are derived,
+ // this method is an override.
+ TempDestination o = (TempDestination) base.Clone();
+
+ // Now do the deep work required
+ // If any new variables are added then this routine will
+ // likely need updating
+
+ return o;
+ }
+
+ public void Delete()
+ {
+ throw new NotSupportedException("Stomp Cannot Delete Temporary Destinations");
+ }
+ }
+}
+
diff --git a/src/test/csharp/Commands/TempQueue.cs b/src/test/csharp/Commands/TempQueue.cs
new file mode 100644
index 0000000..0f39e5e
--- /dev/null
+++ b/src/test/csharp/Commands/TempQueue.cs
@@ -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.
+ */
+using System;
+
+namespace Apache.NMS.Commands
+{
+ /// <summary>
+ /// A Temporary Queue
+ /// </summary>
+ public class TempQueue : TempDestination, ITemporaryQueue
+ {
+ public TempQueue()
+ : base()
+ {
+ }
+
+ public TempQueue(String name)
+ : base(name)
+ {
+ }
+
+ override public DestinationType DestinationType
+ {
+ get
+ {
+ return DestinationType.TemporaryQueue;
+ }
+ }
+
+ public String QueueName
+ {
+ get { return PhysicalName; }
+ }
+
+ public String GetQueueName()
+ {
+ return PhysicalName;
+ }
+
+ public override int GetDestinationType()
+ {
+ return TEMPORARY_QUEUE;
+ }
+
+ public override Destination CreateDestination(String name)
+ {
+ return new TempQueue(name);
+ }
+
+ public override Object Clone()
+ {
+ // Since we are a derived class use the base's Clone()
+ // to perform the shallow copy. Since it is shallow it
+ // will include our derived class. Since we are derived,
+ // this method is an override.
+ TempQueue o = (TempQueue) base.Clone();
+
+ // Now do the deep work required
+ // If any new variables are added then this routine will
+ // likely need updating
+
+ return o;
+ }
+
+ }
+}
+
diff --git a/src/test/csharp/Commands/TempTopic.cs b/src/test/csharp/Commands/TempTopic.cs
new file mode 100644
index 0000000..3a42a55
--- /dev/null
+++ b/src/test/csharp/Commands/TempTopic.cs
@@ -0,0 +1,77 @@
+/*
+ * 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.
+ */
+using System;
+
+namespace Apache.NMS.Commands
+{
+
+ /// <summary>
+ /// A Temporary Topic
+ /// </summary>
+ public class TempTopic : TempDestination, ITemporaryTopic
+ {
+ public TempTopic() : base()
+ {
+ }
+
+ public TempTopic(String name) : base(name)
+ {
+ }
+
+ override public DestinationType DestinationType
+ {
+ get { return DestinationType.TemporaryTopic; }
+ }
+
+ public String TopicName
+ {
+ get { return PhysicalName; }
+ }
+
+ public String GetTopicName()
+ {
+ return PhysicalName;
+ }
+
+ public override int GetDestinationType()
+ {
+ return TEMPORARY_TOPIC;
+ }
+
+ public override Destination CreateDestination(String name)
+ {
+ return new TempTopic(name);
+ }
+
+ public override Object Clone()
+ {
+ // Since we are a derived class use the base's Clone()
+ // to perform the shallow copy. Since it is shallow it
+ // will include our derived class. Since we are derived,
+ // this method is an override.
+ TempTopic o = (TempTopic) base.Clone();
+
+ // Now do the deep work required
+ // If any new variables are added then this routine will
+ // likely need updating
+
+ return o;
+ }
+
+ }
+}
+
diff --git a/src/test/csharp/Commands/TextMessage.cs b/src/test/csharp/Commands/TextMessage.cs
new file mode 100644
index 0000000..40eac3b
--- /dev/null
+++ b/src/test/csharp/Commands/TextMessage.cs
@@ -0,0 +1,70 @@
+/*
+ * 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.
+ */
+
+using System;
+using System.IO;
+
+using Apache.NMS;
+using Apache.NMS.Util;
+
+namespace Apache.NMS.Commands
+{
+ public class TextMessage : Message, ITextMessage
+ {
+ private String text = null;
+
+ public TextMessage()
+ {
+ }
+
+ public TextMessage(String text)
+ {
+ this.Text = text;
+ }
+
+ public override string ToString()
+ {
+ string text = this.Text;
+
+ if(text != null && text.Length > 63)
+ {
+ text = text.Substring(0, 45) + "..." + text.Substring(text.Length - 12);
+ }
+ return base.ToString() + " Text = " + (text ?? "null");
+ }
+
+ public override void ClearBody()
+ {
+ base.ClearBody();
+ this.text = null;
+ }
+
+ // Properties
+
+ public string Text
+ {
+ get { return this.text; }
+ set
+ {
+ FailIfReadOnlyBody();
+ this.text = value;
+ this.Content = null;
+ }
+ }
+ }
+}
+
diff --git a/src/test/csharp/Commands/Topic.cs b/src/test/csharp/Commands/Topic.cs
new file mode 100644
index 0000000..adb7c11
--- /dev/null
+++ b/src/test/csharp/Commands/Topic.cs
@@ -0,0 +1,74 @@
+/*
+ * 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.
+ */
+using System;
+
+namespace Apache.NMS.Commands
+{
+
+ /// <summary>
+ /// Summary description for Topic.
+ /// </summary>
+ public class Topic : Destination, ITopic
+ {
+ public Topic() : base()
+ {
+ }
+
+ public Topic(String name) : base(name)
+ {
+ }
+
+ override public DestinationType DestinationType
+ {
+ get
+ {
+ return DestinationType.Topic;
+ }
+ }
+
+ public String TopicName
+ {
+ get { return PhysicalName; }
+ }
+
+ public override int GetDestinationType()
+ {
+ return TOPIC;
+ }
+
+ public override Destination CreateDestination(String name)
+ {
+ return new Topic(name);
+ }
+
+ public override Object Clone()
+ {
+ // Since we are a derived class use the base's Clone()
+ // to perform the shallow copy. Since it is shallow it
+ // will include our derived class. Since we are derived,
+ // this method is an override.
+ Topic o = (Topic) base.Clone();
+
+ // Now do the deep work required
+ // If any new variables are added then this routine will
+ // likely need updating
+
+ return o;
+ }
+ }
+}
+
diff --git a/src/test/csharp/ConnectionTest.cs b/src/test/csharp/ConnectionTest.cs
new file mode 100644
index 0000000..22cdf08
--- /dev/null
+++ b/src/test/csharp/ConnectionTest.cs
@@ -0,0 +1,191 @@
+/*
+ * 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.
+ */
+using System;
+using NUnit.Framework;
+
+namespace Apache.NMS.Test
+{
+ //[TestFixture]
+ public class ConnectionTest : NMSTest
+ {
+ IConnection startedConnection = null;
+ IConnection stoppedConnection = null;
+
+ protected ConnectionTest(NMSTestSupport testSupport)
+ : base(testSupport)
+ {
+ }
+
+ //[SetUp]
+ public override void SetUp()
+ {
+ base.SetUp();
+
+ startedConnection = CreateConnection(null);
+ startedConnection.Start();
+ stoppedConnection = CreateConnection(null);
+ }
+
+ //[TearDown]
+ public override void TearDown()
+ {
+ startedConnection.Close();
+ stoppedConnection.Close();
+
+ base.TearDown();
+ }
+
+ /// <summary>
+ /// Verify that it is possible to create multiple connections to the broker.
+ /// There was a bug in the connection factory which set the clientId member which made
+ /// it impossible to create an additional connection.
+ /// </summary>
+ //[Test]
+ public virtual void TestTwoConnections()
+ {
+ using(IConnection connection1 = CreateConnection(null))
+ {
+ connection1.Start();
+ using(IConnection connection2 = CreateConnection(null))
+ {
+ // with the bug present we'll get an exception in connection2.start()
+ connection2.Start();
+ }
+ }
+ }
+
+ //[Test]
+ public virtual void TestCreateAndDisposeWithConsumer(
+ //[Values(true, false)]
+ bool disposeConsumer, string testQueueRef)
+ {
+ using(IConnection connection = CreateConnection("DisposalTestConnection"))
+ {
+ connection.Start();
+
+ using(ISession session = connection.CreateSession())
+ {
+ IDestination destination = GetClearDestination(session, DestinationType.Queue, testQueueRef);
+ IMessageConsumer consumer = session.CreateConsumer(destination);
+
+ connection.Stop();
+ if(disposeConsumer)
+ {
+ consumer.Dispose();
+ }
+ }
+ }
+ }
+
+ //[Test]
+ public virtual void TestCreateAndDisposeWithProducer(
+ //[Values(true, false)]
+ bool disposeProducer, string testQueueRef)
+ {
+ using(IConnection connection = CreateConnection("DisposalTestConnection"))
+ {
+ connection.Start();
+
+ using(ISession session = connection.CreateSession())
+ {
+ IDestination destination = GetClearDestination(session, DestinationType.Queue, testQueueRef);
+ IMessageProducer producer = session.CreateProducer(destination);
+
+ connection.Stop();
+ if(disposeProducer)
+ {
+ producer.Dispose();
+ }
+ }
+ }
+ }
+
+ //[Test]
+ public virtual void TestStartAfterSend(
+ //[Values(MsgDeliveryMode.Persistent, MsgDeliveryMode.NonPersistent)]
+ MsgDeliveryMode deliveryMode,
+ //[Values(DestinationType.Queue, DestinationType.Topic)]
+ DestinationType destinationType, string testDestinationRef)
+ {
+ using(IConnection connection = CreateConnection(GetTestClientId()))
+ {
+ ISession session = connection.CreateSession(AcknowledgementMode.AutoAcknowledge);
+ IDestination destination = GetClearDestination(session, destinationType, testDestinationRef);
+ IMessageConsumer consumer = session.CreateConsumer(destination);
+
+ // Send the messages
+ SendMessages(session, destination, deliveryMode, 1);
+
+ // Start the conncection after the message was sent.
+ connection.Start();
+
+ // Make sure only 1 message was delivered.
+ Assert.IsNotNull(consumer.Receive(TimeSpan.FromMilliseconds(1000)));
+ Assert.IsNull(consumer.ReceiveNoWait());
+ }
+ }
+
+ /// <summary>
+ /// Tests if the consumer receives the messages that were sent before the
+ /// connection was started.
+ /// </summary>
+ //[Test]
+ public virtual void TestStoppedConsumerHoldsMessagesTillStarted(string testTopicRef)
+ {
+ ISession startedSession = startedConnection.CreateSession(AcknowledgementMode.AutoAcknowledge);
+ ISession stoppedSession = stoppedConnection.CreateSession(AcknowledgementMode.AutoAcknowledge);
+
+ // Setup the consumers.
+ IDestination topic = GetClearDestination(startedSession, DestinationType.Topic, testTopicRef);
+ IMessageConsumer startedConsumer = startedSession.CreateConsumer(topic);
+ IMessageConsumer stoppedConsumer = stoppedSession.CreateConsumer(topic);
+
+ // Send the message.
+ IMessageProducer producer = startedSession.CreateProducer(topic);
+ ITextMessage message = startedSession.CreateTextMessage("Hello");
+ producer.Send(message);
+
+ // Test the assertions.
+ IMessage m = startedConsumer.Receive(TimeSpan.FromMilliseconds(1000));
+ Assert.IsNotNull(m);
+
+ m = stoppedConsumer.Receive(TimeSpan.FromMilliseconds(1000));
+ Assert.IsNull(m);
+
+ stoppedConnection.Start();
+ m = stoppedConsumer.Receive(TimeSpan.FromMilliseconds(5000));
+ Assert.IsNotNull(m);
+
+ startedSession.Close();
+ stoppedSession.Close();
+ }
+
+ /// <summary>
+ /// Tests if the consumer is able to receive messages eveb when the
+ /// connecction restarts multiple times.
+ /// </summary>
+ //[Test]
+ public virtual void TestMultipleConnectionStops(string testTopicRef)
+ {
+ TestStoppedConsumerHoldsMessagesTillStarted(testTopicRef);
+ stoppedConnection.Stop();
+ TestStoppedConsumerHoldsMessagesTillStarted(testTopicRef);
+ stoppedConnection.Stop();
+ TestStoppedConsumerHoldsMessagesTillStarted(testTopicRef);
+ }
+ }
+}
diff --git a/src/test/csharp/ConsumerTest.cs b/src/test/csharp/ConsumerTest.cs
new file mode 100644
index 0000000..a3aec2e
--- /dev/null
+++ b/src/test/csharp/ConsumerTest.cs
@@ -0,0 +1,573 @@
+/*
+ * 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.
+ */
+using System;
+using System.Threading;
+using NUnit.Framework;
+
+namespace Apache.NMS.Test
+{
+ //[TestFixture]
+ public class ConsumerTest : NMSTest
+ {
+ protected const int COUNT = 25;
+ protected const string VALUE_NAME = "value";
+
+ private bool dontAck;
+
+ protected ConsumerTest(NMSTestSupport testSupport)
+ : base(testSupport)
+ {
+ }
+
+// The .NET CF does not have the ability to interrupt threads, so this test is impossible.
+#if !NETCF
+ //[Test]
+ public virtual void TestNoTimeoutConsumer(
+ //[Values(AcknowledgementMode.AutoAcknowledge, AcknowledgementMode.ClientAcknowledge,
+ // AcknowledgementMode.DupsOkAcknowledge, AcknowledgementMode.Transactional)]
+ AcknowledgementMode ackMode)
+ {
+ // Launch a thread to perform IMessageConsumer.Receive().
+ // If it doesn't fail in less than three seconds, no exception was thrown.
+ Thread receiveThread = new Thread(new ThreadStart(TimeoutConsumerThreadProc));
+ using(IConnection connection = CreateConnection())
+ {
+ connection.Start();
+ using(ISession session = connection.CreateSession(ackMode))
+ {
+ ITemporaryQueue queue = session.CreateTemporaryQueue();
+ using(this.timeoutConsumer = session.CreateConsumer(queue))
+ {
+ receiveThread.Start();
+ if(receiveThread.Join(3000))
+ {
+ Assert.Fail("IMessageConsumer.Receive() returned without blocking. Test failed.");
+ }
+ else
+ {
+ // Kill the thread - otherwise it'll sit in Receive() until a message arrives.
+ receiveThread.Interrupt();
+ }
+ }
+ }
+ }
+ }
+
+ protected IMessageConsumer timeoutConsumer;
+
+ protected void TimeoutConsumerThreadProc()
+ {
+ try
+ {
+ timeoutConsumer.Receive();
+ }
+ catch(ArgumentOutOfRangeException e)
+ {
+ // The test failed. We will know because the timeout will expire inside TestNoTimeoutConsumer().
+ Assert.Fail("Test failed with exception: " + e.Message);
+ }
+ catch(ThreadInterruptedException)
+ {
+ // The test succeeded! We were still blocked when we were interrupted.
+ }
+ catch(Exception e)
+ {
+ // Some other exception occurred.
+ Assert.Fail("Test failed with exception: " + e.Message);
+ }
+ }
+
+ //[Test]
+ public virtual void TestSyncReceiveConsumerClose(
+ //[Values(AcknowledgementMode.AutoAcknowledge, AcknowledgementMode.ClientAcknowledge,
+ // AcknowledgementMode.DupsOkAcknowledge, AcknowledgementMode.Transactional)]
+ AcknowledgementMode ackMode)
+ {
+ // Launch a thread to perform IMessageConsumer.Receive().
+ // If it doesn't fail in less than three seconds, no exception was thrown.
+ Thread receiveThread = new Thread(new ThreadStart(TimeoutConsumerThreadProc));
+ using (IConnection connection = CreateConnection())
+ {
+ connection.Start();
+ using (ISession session = connection.CreateSession(ackMode))
+ {
+ ITemporaryQueue queue = session.CreateTemporaryQueue();
+ using (this.timeoutConsumer = session.CreateConsumer(queue))
+ {
+ receiveThread.Start();
+ if (receiveThread.Join(3000))
+ {
+ Assert.Fail("IMessageConsumer.Receive() returned without blocking. Test failed.");
+ }
+ else
+ {
+ // Kill the thread - otherwise it'll sit in Receive() until a message arrives.
+ this.timeoutConsumer.Close();
+ receiveThread.Join(10000);
+ if (receiveThread.IsAlive)
+ {
+ // Kill the thread - otherwise it'll sit in Receive() until a message arrives.
+ receiveThread.Interrupt();
+ Assert.Fail("IMessageConsumer.Receive() thread is still alive, Close should have killed it.");
+ }
+ }
+ }
+ }
+ }
+ }
+
+ internal class ThreadArg
+ {
+ internal IConnection connection = null;
+ internal ISession session = null;
+ internal IDestination destination = null;
+ }
+
+ protected void DelayedProducerThreadProc(Object arg)
+ {
+ try
+ {
+ ThreadArg args = arg as ThreadArg;
+
+ using(ISession session = args.connection.CreateSession())
+ {
+ using(IMessageProducer producer = session.CreateProducer(args.destination))
+ {
+ // Give the consumer time to enter the receive.
+ Thread.Sleep(5000);
+
+ producer.Send(args.session.CreateTextMessage("Hello World"));
+ }
+ }
+ }
+ catch(Exception e)
+ {
+ // Some other exception occurred.
+ Assert.Fail("Test failed with exception: " + e.Message);
+ }
+ }
+
+ //[Test]
+ public virtual void TestDoChangeSentMessage(
+ //[Values(AcknowledgementMode.AutoAcknowledge, AcknowledgementMode.ClientAcknowledge,
+ // AcknowledgementMode.DupsOkAcknowledge, AcknowledgementMode.Transactional)]
+ AcknowledgementMode ackMode,
+ //[Values(true, false)]
+ bool doClear)
+ {
+ using(IConnection connection = CreateConnection())
+ {
+ connection.Start();
+ using(ISession session = connection.CreateSession(ackMode))
+ {
+ ITemporaryQueue queue = session.CreateTemporaryQueue();
+ using(IMessageConsumer consumer = session.CreateConsumer(queue))
+ {
+ IMessageProducer producer = session.CreateProducer(queue);
+ ITextMessage message = session.CreateTextMessage();
+
+ string prefix = "ConsumerTest - TestDoChangeSentMessage: ";
+
+ for(int i = 0; i < COUNT; i++)
+ {
+ message.Properties[VALUE_NAME] = i;
+ message.Text = prefix + Convert.ToString(i);
+
+ producer.Send(message);
+
+ if(doClear)
+ {
+ message.ClearBody();
+ message.ClearProperties();
+ }
+ }
+
+ if(ackMode == AcknowledgementMode.Transactional)
+ {
+ session.Commit();
+ }
+
+ for(int i = 0; i < COUNT; i++)
+ {
+ ITextMessage msg = consumer.Receive(TimeSpan.FromMilliseconds(2000)) as ITextMessage;
+ Assert.AreEqual(msg.Text, prefix + Convert.ToString(i));
+ Assert.AreEqual(msg.Properties.GetInt(VALUE_NAME), i);
+ }
+
+ if(ackMode == AcknowledgementMode.Transactional)
+ {
+ session.Commit();
+ }
+
+ }
+ }
+ }
+ }
+
+ //[Test]
+ public virtual void TestConsumerReceiveBeforeMessageDispatched(
+ //[Values(AcknowledgementMode.AutoAcknowledge, AcknowledgementMode.ClientAcknowledge,
+ // AcknowledgementMode.DupsOkAcknowledge, AcknowledgementMode.Transactional)]
+ AcknowledgementMode ackMode)
+ {
+ // Launch a thread to perform a delayed send.
+ Thread sendThread = new Thread(DelayedProducerThreadProc);
+ using(IConnection connection = CreateConnection())
+ {
+ connection.Start();
+ using(ISession session = connection.CreateSession(ackMode))
+ {
+ ITemporaryQueue queue = session.CreateTemporaryQueue();
+ using(IMessageConsumer consumer = session.CreateConsumer(queue))
+ {
+ ThreadArg arg = new ThreadArg();
+
+ arg.connection = connection;
+ arg.session = session;
+ arg.destination = queue;
+
+ sendThread.Start(arg);
+ IMessage message = consumer.Receive(TimeSpan.FromMinutes(1));
+ Assert.IsNotNull(message);
+ }
+ }
+ }
+ }
+
+ //[Test]
+ public virtual void TestDontStart(
+ //[Values(MsgDeliveryMode.NonPersistent)]
+ MsgDeliveryMode deliveryMode,
+ //[Values(DestinationType.Queue, DestinationType.Topic)]
+ DestinationType destinationType, string testDestinationRef)
+ {
+ using(IConnection connection = CreateConnection())
+ {
+ ISession session = connection.CreateSession();
+ IDestination destination = GetClearDestination(session, destinationType, testDestinationRef);
+ IMessageConsumer consumer = session.CreateConsumer(destination);
+
+ // Send the messages
+ SendMessages(session, destination, deliveryMode, 1);
+
+ // Make sure no messages were delivered.
+ Assert.IsNull(consumer.Receive(TimeSpan.FromMilliseconds(1000)));
+ }
+ }
+
+ //[Test]
+ public void TestSendReceiveTransacted(
+ //[Values(MsgDeliveryMode.NonPersistent, MsgDeliveryMode.Persistent)]
+ MsgDeliveryMode deliveryMode,
+ //[Values(DestinationType.Queue, DestinationType.Topic, DestinationType.TemporaryQueue, DestinationType.TemporaryTopic)]
+ DestinationType destinationType, string testDestinationRef)
+ {
+ using(IConnection connection = CreateConnection())
+ {
+ // Send a message to the broker.
+ connection.Start();
+ ISession session = connection.CreateSession(AcknowledgementMode.Transactional);
+ IDestination destination = GetClearDestination(session, destinationType, testDestinationRef);
+ IMessageConsumer consumer = session.CreateConsumer(destination);
+ IMessageProducer producer = session.CreateProducer(destination);
+
+ producer.DeliveryMode = deliveryMode;
+ producer.Send(session.CreateTextMessage("Test"));
+
+ // Message should not be delivered until commit.
+ Thread.Sleep(1000);
+ Assert.IsNull(consumer.ReceiveNoWait());
+ session.Commit();
+
+ // Make sure only 1 message was delivered.
+ IMessage message = consumer.Receive(TimeSpan.FromMilliseconds(1000));
+ Assert.IsNotNull(message);
+ Assert.IsFalse(message.NMSRedelivered);
+ Assert.IsNull(consumer.ReceiveNoWait());
+
+ // Message should be redelivered is rollback is used.
+ session.Rollback();
+
+ // Make sure only 1 message was delivered.
+ message = consumer.Receive(TimeSpan.FromMilliseconds(2000));
+ Assert.IsNotNull(message);
+ Assert.IsTrue(message.NMSRedelivered);
+ Assert.IsNull(consumer.ReceiveNoWait());
+
+ // If we commit now, the message should not be redelivered.
+ session.Commit();
+ Thread.Sleep(1000);
+ Assert.IsNull(consumer.ReceiveNoWait());
+ }
+ }
+
+ //[Test]
+ public virtual void TestAckedMessageAreConsumed(string testQueueRef)
+ {
+ using(IConnection connection = CreateConnection())
+ {
+ connection.Start();
+ ISession session = connection.CreateSession(AcknowledgementMode.ClientAcknowledge);
+ IDestination destination = GetClearDestination(session, DestinationType.Queue, testQueueRef);
+ IMessageProducer producer = session.CreateProducer(destination);
+ producer.Send(session.CreateTextMessage("Hello"));
+
+ // Consume the message...
+ IMessageConsumer consumer = session.CreateConsumer(destination);
+ IMessage msg = consumer.Receive(TimeSpan.FromMilliseconds(1000));
+ Assert.IsNotNull(msg);
+ msg.Acknowledge();
+
+ // Reset the session.
+ session.Close();
+ session = connection.CreateSession(AcknowledgementMode.ClientAcknowledge);
+
+ // Attempt to Consume the message...
+ consumer = session.CreateConsumer(destination);
+ msg = consumer.Receive(TimeSpan.FromMilliseconds(1000));
+ Assert.IsNull(msg);
+
+ session.Close();
+ }
+ }
+
+ //[Test]
+ public virtual void TestLastMessageAcked(string testQueueRef)
+ {
+ using(IConnection connection = CreateConnection())
+ {
+ connection.Start();
+ ISession session = connection.CreateSession(AcknowledgementMode.ClientAcknowledge);
+ IDestination destination = GetClearDestination(session, DestinationType.Queue, testQueueRef);
+ IMessageProducer producer = session.CreateProducer(destination);
+ producer.Send(session.CreateTextMessage("Hello"));
+ producer.Send(session.CreateTextMessage("Hello2"));
+ producer.Send(session.CreateTextMessage("Hello3"));
+
+ // Consume the message...
+ IMessageConsumer consumer = session.CreateConsumer(destination);
+ IMessage msg = consumer.Receive(TimeSpan.FromMilliseconds(1000));
+ Assert.IsNotNull(msg);
+ msg = consumer.Receive(TimeSpan.FromMilliseconds(1000));
+ Assert.IsNotNull(msg);
+ msg = consumer.Receive(TimeSpan.FromMilliseconds(1000));
+ Assert.IsNotNull(msg);
+ msg.Acknowledge();
+
+ // Reset the session.
+ session.Close();
+ session = connection.CreateSession(AcknowledgementMode.ClientAcknowledge);
+
+ // Attempt to Consume the message...
+ consumer = session.CreateConsumer(destination);
+ msg = consumer.Receive(TimeSpan.FromMilliseconds(1000));
+ Assert.IsNull(msg);
+
+ session.Close();
+ }
+ }
+
+ //[Test]
+ public virtual void TestUnAckedMessageAreNotConsumedOnSessionClose(string testQueueRef)
+ {
+ using(IConnection connection = CreateConnection())
+ {
+ connection.Start();
+ ISession session = connection.CreateSession(AcknowledgementMode.ClientAcknowledge);
+ IDestination destination = GetClearDestination(session, DestinationType.Queue, testQueueRef);
+ IMessageProducer producer = session.CreateProducer(destination);
+ producer.Send(session.CreateTextMessage("Hello"));
+
+ // Consume the message...
+ IMessageConsumer consumer = session.CreateConsumer(destination);
+ IMessage msg = consumer.Receive(TimeSpan.FromMilliseconds(1000));
+ Assert.IsNotNull(msg);
+ // Don't ack the message.
+
+ // Reset the session. This should cause the unacknowledged message to be re-delivered.
+ session.Close();
+ session = connection.CreateSession(AcknowledgementMode.ClientAcknowledge);
+
+ // Attempt to Consume the message...
+ consumer = session.CreateConsumer(destination);
+ msg = consumer.Receive(TimeSpan.FromMilliseconds(2000));
+ Assert.IsNotNull(msg);
+ msg.Acknowledge();
+
+ session.Close();
+ }
+ }
+
+ //[Test]
+ public virtual void TestAsyncAckedMessageAreConsumed(string testQueueRef)
+ {
+ using(IConnection connection = CreateConnection())
+ {
+ connection.Start();
+ ISession session = connection.CreateSession(AcknowledgementMode.ClientAcknowledge);
+ IDestination destination = GetClearDestination(session, DestinationType.Queue, testQueueRef);
+ IMessageProducer producer = session.CreateProducer(destination);
+ producer.Send(session.CreateTextMessage("Hello"));
+
+ // Consume the message...
+ IMessageConsumer consumer = session.CreateConsumer(destination);
+ consumer.Listener += new MessageListener(OnMessage);
+
+ Thread.Sleep(5000);
+
+ // Reset the session.
+ session.Close();
+
+ session = connection.CreateSession(AcknowledgementMode.ClientAcknowledge);
+
+ // Attempt to Consume the message...
+ consumer = session.CreateConsumer(destination);
+ IMessage msg = consumer.Receive(TimeSpan.FromMilliseconds(1000));
+ Assert.IsNull(msg);
+
+ session.Close();
+ }
+ }
+
+ //[Test]
+ public virtual void TestAsyncUnAckedMessageAreNotConsumedOnSessionClose(string testQueueRef)
+ {
+ using(IConnection connection = CreateConnection())
+ {
+ connection.Start();
+ // don't aknowledge message on onMessage() call
+ dontAck = true;
+ ISession session = connection.CreateSession(AcknowledgementMode.ClientAcknowledge);
+ IDestination destination = GetClearDestination(session, DestinationType.Queue, testQueueRef);
+ IMessageProducer producer = session.CreateProducer(destination);
+ producer.Send(session.CreateTextMessage("Hello"));
+
+ // Consume the message...
+ using(IMessageConsumer consumer = session.CreateConsumer(destination))
+ {
+ consumer.Listener += new MessageListener(OnMessage);
+ // Don't ack the message.
+ }
+
+ // Reset the session. This should cause the Unacked message to be
+ // redelivered.
+ session.Close();
+
+ Thread.Sleep(5000);
+ session = connection.CreateSession(AcknowledgementMode.ClientAcknowledge);
+ // Attempt to Consume the message...
+ using(IMessageConsumer consumer = session.CreateConsumer(destination))
+ {
+ IMessage msg = consumer.Receive(TimeSpan.FromMilliseconds(2000));
+ Assert.IsNotNull(msg);
+ msg.Acknowledge();
+ }
+
+ session.Close();
+ }
+ }
+
+ //[Test]
+ public virtual void TestAddRemoveAsnycMessageListener()
+ {
+ using(IConnection connection = CreateConnection())
+ {
+ connection.Start();
+
+ ISession session = connection.CreateSession(AcknowledgementMode.ClientAcknowledge);
+ ITemporaryTopic topic = session.CreateTemporaryTopic();
+ IMessageConsumer consumer = session.CreateConsumer(topic);
+
+ consumer.Listener += OnMessage;
+ consumer.Listener -= OnMessage;
+ consumer.Listener += OnMessage;
+
+ consumer.Close();
+ }
+ }
+
+ public void OnMessage(IMessage message)
+ {
+ Assert.IsNotNull(message);
+
+ if(!dontAck)
+ {
+ try
+ {
+ message.Acknowledge();
+ }
+ catch(Exception)
+ {
+ }
+ }
+ }
+
+ //[Test]
+ public virtual void TestReceiveNoWait(
+ //[Values(AcknowledgementMode.AutoAcknowledge, AcknowledgementMode.ClientAcknowledge,
+ // AcknowledgementMode.DupsOkAcknowledge, AcknowledgementMode.Transactional)]
+ AcknowledgementMode ackMode,
+ //[Values(MsgDeliveryMode.NonPersistent, MsgDeliveryMode.Persistent)]
+ MsgDeliveryMode deliveryMode)
+ {
+ const int RETRIES = 20;
+
+ using(IConnection connection = CreateConnection())
+ {
+ connection.Start();
+ using(ISession session = connection.CreateSession(ackMode))
+ {
+ IDestination destination = session.CreateTemporaryQueue();
+
+ using(IMessageProducer producer = session.CreateProducer(destination))
+ {
+ producer.DeliveryMode = deliveryMode;
+ ITextMessage message = session.CreateTextMessage("TEST");
+ producer.Send(message);
+
+ if(AcknowledgementMode.Transactional == ackMode)
+ {
+ session.Commit();
+ }
+ }
+
+ using(IMessageConsumer consumer = session.CreateConsumer(destination))
+ {
+ IMessage message = null;
+
+ for(int i = 0; i < RETRIES && message == null; ++i)
+ {
+ message = consumer.ReceiveNoWait();
+ Thread.Sleep(100);
+ }
+
+ Assert.IsNotNull(message);
+ message.Acknowledge();
+
+ if(AcknowledgementMode.Transactional == ackMode)
+ {
+ session.Commit();
+ }
+ }
+ }
+ }
+ }
+
+#endif
+
+ }
+}
diff --git a/src/test/csharp/DurableTest.cs b/src/test/csharp/DurableTest.cs
new file mode 100644
index 0000000..819f10c
--- /dev/null
+++ b/src/test/csharp/DurableTest.cs
@@ -0,0 +1,267 @@
+/*
+ * 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.
+ */
+using System;
+using System.Threading;
+using Apache.NMS.Util;
+using NUnit.Framework;
+
+namespace Apache.NMS.Test
+{
+ //[TestFixture]
+ public class DurableTest : NMSTest
+ {
+ protected static string DURABLE_SELECTOR = "2 > 1";
+
+ protected string TEST_CLIENT_AND_CONSUMER_ID;
+ protected string SEND_CLIENT_ID;
+
+ protected DurableTest(NMSTestSupport testSupport)
+ : base(testSupport)
+ {
+ }
+
+ //[SetUp]
+ public override void SetUp()
+ {
+ base.SetUp();
+
+ TEST_CLIENT_AND_CONSUMER_ID = GetTestClientId();
+ SEND_CLIENT_ID = GetTestClientId();
+ }
+
+ //[Test]
+ public virtual void TestSendWhileClosed(
+ //[Values(AcknowledgementMode.AutoAcknowledge, AcknowledgementMode.ClientAcknowledge,
+ // AcknowledgementMode.DupsOkAcknowledge, AcknowledgementMode.Transactional)]
+ AcknowledgementMode ackMode, string testTopicRef)
+ {
+ try
+ {
+ using(IConnection connection = CreateConnection(TEST_CLIENT_AND_CONSUMER_ID))
+ {
+ connection.Start();
+
+ using(ISession session = connection.CreateSession(ackMode))
+ {
+ ITopic topic = (ITopic)GetClearDestination(session, DestinationType.Topic, testTopicRef);
+ IMessageProducer producer = session.CreateProducer(topic);
+
+ producer.DeliveryMode = MsgDeliveryMode.Persistent;
+
+ ISession consumeSession = connection.CreateSession(ackMode);
+ IMessageConsumer consumer = consumeSession.CreateDurableConsumer(topic, TEST_CLIENT_AND_CONSUMER_ID, null, false);
+ Thread.Sleep(1000);
+ consumer.Dispose();
+ consumer = null;
+
+ ITextMessage message = session.CreateTextMessage("DurableTest-TestSendWhileClosed");
+ message.Properties.SetString("test", "test");
+ message.NMSType = "test";
+ producer.Send(message);
+ if(AcknowledgementMode.Transactional == ackMode)
+ {
+ session.Commit();
+ }
+
+ Thread.Sleep(1000);
+ consumer = consumeSession.CreateDurableConsumer(topic, TEST_CLIENT_AND_CONSUMER_ID, null, false);
+ ITextMessage msg = consumer.Receive(TimeSpan.FromMilliseconds(1000)) as ITextMessage;
+ msg.Acknowledge();
+ if(AcknowledgementMode.Transactional == ackMode)
+ {
+ consumeSession.Commit();
+ }
+
+ Assert.IsNotNull(msg);
+ Assert.AreEqual(msg.Text, "DurableTest-TestSendWhileClosed");
+ Assert.AreEqual(msg.NMSType, "test");
+ Assert.AreEqual(msg.Properties.GetString("test"), "test");
+ }
+ }
+ }
+ catch(Exception ex)
+ {
+ Assert.Fail(ex.Message);
+ }
+ finally
+ {
+ // Pause to allow Stomp to unregister at the broker.
+ Thread.Sleep(500);
+
+ UnregisterDurableConsumer(TEST_CLIENT_AND_CONSUMER_ID, TEST_CLIENT_AND_CONSUMER_ID);
+ }
+ }
+
+ //[Test]
+ public void TestDurableConsumerSelectorChange(
+ //[Values(AcknowledgementMode.AutoAcknowledge, AcknowledgementMode.ClientAcknowledge,
+ // AcknowledgementMode.DupsOkAcknowledge, AcknowledgementMode.Transactional)]
+ AcknowledgementMode ackMode, string testTopicRef)
+ {
+ try
+ {
+ using(IConnection connection = CreateConnection(TEST_CLIENT_AND_CONSUMER_ID))
+ {
+ connection.Start();
+ using(ISession session = connection.CreateSession(ackMode))
+ {
+ ITopic topic = (ITopic)GetClearDestination(session, DestinationType.Topic, testTopicRef);
+ IMessageProducer producer = session.CreateProducer(topic);
+ IMessageConsumer consumer = session.CreateDurableConsumer(topic, TEST_CLIENT_AND_CONSUMER_ID, "color='red'", false);
+
+ producer.DeliveryMode = MsgDeliveryMode.Persistent;
+
+ // Send the messages
+ ITextMessage sendMessage = session.CreateTextMessage("1st");
+ sendMessage.Properties["color"] = "red";
+ producer.Send(sendMessage);
+ if(AcknowledgementMode.Transactional == ackMode)
+ {
+ session.Commit();
+ }
+
+ ITextMessage receiveMsg = consumer.Receive(receiveTimeout) as ITextMessage;
+ Assert.IsNotNull(receiveMsg, "Failed to retrieve 1st durable message.");
+ Assert.AreEqual("1st", receiveMsg.Text);
+ Assert.AreEqual(MsgDeliveryMode.Persistent, receiveMsg.NMSDeliveryMode, "NMSDeliveryMode does not match");
+ receiveMsg.Acknowledge();
+ if(AcknowledgementMode.Transactional == ackMode)
+ {
+ session.Commit();
+ }
+
+ // Change the subscription, allowing some time for the Broker to purge the
+ // consumers resources.
+ consumer.Dispose();
+ Thread.Sleep(1000);
+
+ consumer = session.CreateDurableConsumer(topic, TEST_CLIENT_AND_CONSUMER_ID, "color='blue'", false);
+
+ sendMessage = session.CreateTextMessage("2nd");
+ sendMessage.Properties["color"] = "red";
+ producer.Send(sendMessage);
+ sendMessage = session.CreateTextMessage("3rd");
+ sendMessage.Properties["color"] = "blue";
+ producer.Send(sendMessage);
+ if(AcknowledgementMode.Transactional == ackMode)
+ {
+ session.Commit();
+ }
+
+ // Selector should skip the 2nd message.
+ receiveMsg = consumer.Receive(receiveTimeout) as ITextMessage;
+ Assert.IsNotNull(receiveMsg, "Failed to retrieve durable message.");
+ Assert.AreEqual("3rd", receiveMsg.Text, "Retrieved the wrong durable message.");
+ Assert.AreEqual(MsgDeliveryMode.Persistent, receiveMsg.NMSDeliveryMode, "NMSDeliveryMode does not match");
+ receiveMsg.Acknowledge();
+ if(AcknowledgementMode.Transactional == ackMode)
+ {
+ session.Commit();
+ }
+
+ // Make sure there are no pending messages.
+ Assert.IsNull(consumer.ReceiveNoWait(), "Wrong number of messages in durable subscription.");
+ }
+ }
+ }
+ catch(Exception ex)
+ {
+ Assert.Fail(ex.Message);
+ }
+ finally
+ {
+ // Pause to allow Stomp to unregister at the broker.
+ Thread.Sleep(500);
+
+ UnregisterDurableConsumer(TEST_CLIENT_AND_CONSUMER_ID, TEST_CLIENT_AND_CONSUMER_ID);
+ }
+ }
+
+ //[Test]
+ public void TestDurableConsumer(
+ //[Values(AcknowledgementMode.AutoAcknowledge, AcknowledgementMode.ClientAcknowledge,
+ // AcknowledgementMode.DupsOkAcknowledge, AcknowledgementMode.Transactional)]
+ AcknowledgementMode ackMode, string testDurableTopicName)
+ {
+ try
+ {
+ RegisterDurableConsumer(TEST_CLIENT_AND_CONSUMER_ID, testDurableTopicName, TEST_CLIENT_AND_CONSUMER_ID, null, false);
+ RunTestDurableConsumer(testDurableTopicName, ackMode);
+ if(AcknowledgementMode.Transactional == ackMode)
+ {
+ RunTestDurableConsumer(testDurableTopicName, ackMode);
+ }
+ }
+ finally
+ {
+ // Pause to allow Stomp to unregister at the broker.
+ Thread.Sleep(500);
+
+ UnregisterDurableConsumer(TEST_CLIENT_AND_CONSUMER_ID, TEST_CLIENT_AND_CONSUMER_ID);
+ }
+ }
+
+ protected void RunTestDurableConsumer(string topicName, AcknowledgementMode ackMode)
+ {
+ SendDurableMessage(topicName);
+ SendDurableMessage(topicName);
+
+ using(IConnection connection = CreateConnection(TEST_CLIENT_AND_CONSUMER_ID))
+ {
+ connection.Start();
+ using(ISession session = connection.CreateSession(ackMode))
+ {
+ ITopic topic = SessionUtil.GetTopic(session, topicName);
+ using(IMessageConsumer consumer = session.CreateDurableConsumer(topic, TEST_CLIENT_AND_CONSUMER_ID, null, false))
+ {
+ IMessage msg = consumer.Receive(receiveTimeout);
+ Assert.IsNotNull(msg, "Did not receive first durable message.");
+ msg.Acknowledge();
+
+ msg = consumer.Receive(receiveTimeout);
+ Assert.IsNotNull(msg, "Did not receive second durable message.");
+ msg.Acknowledge();
+
+ if(AcknowledgementMode.Transactional == ackMode)
+ {
+ session.Commit();
+ }
+ }
+ }
+ }
+ }
+
+ protected void SendDurableMessage(string topicName)
+ {
+ using(IConnection connection = CreateConnection(SEND_CLIENT_ID))
+ {
+ connection.Start();
+ using(ISession session = connection.CreateSession())
+ {
+ ITopic topic = SessionUtil.GetTopic(session, topicName);
+ using(IMessageProducer producer = session.CreateProducer(topic))
+ {
+ ITextMessage message = session.CreateTextMessage("Durable Hello");
+
+ producer.DeliveryMode = MsgDeliveryMode.Persistent;
+ producer.Send(message);
+ }
+ }
+ }
+ }
+ }
+}
diff --git a/src/test/csharp/EndianBinaryReaderTest.cs b/src/test/csharp/EndianBinaryReaderTest.cs
new file mode 100644
index 0000000..dca24d0
--- /dev/null
+++ b/src/test/csharp/EndianBinaryReaderTest.cs
@@ -0,0 +1,162 @@
+/*
+ * 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.
+ */
+using System.IO;
+using Apache.NMS.Util;
+using NUnit.Framework;
+
+namespace Apache.NMS.Test
+{
+ [TestFixture]
+ public class EndianBinaryReaderTest
+ {
+ public void readString16Helper(byte[] input, char[] expect)
+ {
+ MemoryStream stream = new MemoryStream(input);
+ EndianBinaryReader reader = new EndianBinaryReader(stream);
+
+ char[] result = reader.ReadString16().ToCharArray();
+
+ for(int i = 0; i < expect.Length; ++i)
+ {
+ Assert.AreEqual(expect[i], result[i]);
+ }
+ }
+
+ [Test]
+ public void testReadString16_1byteUTF8encoding()
+ {
+ // Test data with 1-byte UTF8 encoding.
+ char[] expect = { '\u0000', '\u000B', '\u0048', '\u0065', '\u006C', '\u006C', '\u006F', '\u0020', '\u0057', '\u006F', '\u0072', '\u006C', '\u0064' };
+ byte[] input = { 0x00, 0x0E, 0xC0, 0x80, 0x0B, 0x48, 0x65, 0x6C, 0x6C, 0x6F, 0x20, 0x57, 0x6F, 0x72, 0x6C, 0x64 };
+
+ readString16Helper(input, expect);
+ }
+
+ [Test]
+ public void testReadString16_2byteUTF8encoding()
+ {
+ // Test data with 2-byte UT8 encoding.
+ char[] expect = { '\u0000', '\u00C2', '\u00A9', '\u00C3', '\u00A6' };
+ byte[] input = { 0x00, 0x0A, 0xC0, 0x80, 0xC3, 0x82, 0xC2, 0xA9, 0xC3, 0x83, 0xC2, 0xA6 };
+ readString16Helper(input, expect);
+ }
+
+ [Test]
+ public void testReadString16_1byteAnd2byteEmbeddedNULLs()
+ {
+ // Test data with 1-byte and 2-byte encoding with embedded NULL's.
+ char[] expect = { '\u0000', '\u0004', '\u00C2', '\u00A9', '\u00C3', '\u0000', '\u00A6' };
+ byte[] input = { 0x00, 0x0D, 0xC0, 0x80, 0x04, 0xC3, 0x82, 0xC2, 0xA9, 0xC3, 0x83, 0xC0, 0x80, 0xC2, 0xA6 };
+
+ readString16Helper(input, expect);
+ }
+
+ [Test]
+ [ExpectedException(typeof(IOException))]
+ public void testReadString16_UTF8Missing2ndByte()
+ {
+ // Test with bad UTF-8 encoding, missing 2nd byte of two byte value
+ byte[] input = { 0x00, 0x0D, 0xC0, 0x80, 0x04, 0xC3, 0x82, 0xC2, 0xC2, 0xC3, 0x83, 0xC0, 0x80, 0xC2, 0xA6 };
+
+ MemoryStream stream = new MemoryStream(input);
+ EndianBinaryReader reader = new EndianBinaryReader(stream);
+
+ reader.ReadString16();
+ }
+
+ [Test]
+ [ExpectedException(typeof(IOException))]
+ public void testReadString16_3byteEncodingMissingLastByte()
+ {
+ // Test with three byte encode that's missing a last byte.
+ byte[] input = { 0x00, 0x02, 0xE8, 0xA8 };
+
+ MemoryStream stream = new MemoryStream(input);
+ EndianBinaryReader reader = new EndianBinaryReader(stream);
+
+ reader.ReadString16();
+ }
+
+ public void readString32Helper(byte[] input, char[] expect)
+ {
+ MemoryStream stream = new MemoryStream(input);
+ EndianBinaryReader reader = new EndianBinaryReader(stream);
+
+ char[] result = reader.ReadString32().ToCharArray();
+
+ for(int i = 0; i < expect.Length; ++i)
+ {
+ Assert.AreEqual(expect[i], result[i]);
+ }
+ }
+
+ [Test]
+ public void testReadString32_1byteUTF8encoding()
+ {
+ // Test data with 1-byte UTF8 encoding.
+ char[] expect = { '\u0000', '\u000B', '\u0048', '\u0065', '\u006C', '\u006C', '\u006F', '\u0020', '\u0057', '\u006F', '\u0072', '\u006C', '\u0064' };
+ byte[] input = { 0x00, 0x00, 0x00, 0x0E, 0xC0, 0x80, 0x0B, 0x48, 0x65, 0x6C, 0x6C, 0x6F, 0x20, 0x57, 0x6F, 0x72, 0x6C, 0x64 };
+
+ readString32Helper(input, expect);
+ }
+
+ [Test]
+ public void testReadString32_2byteUTF8encoding()
+ {
+ // Test data with 2-byte UT8 encoding.
+ char[] expect = { '\u0000', '\u00C2', '\u00A9', '\u00C3', '\u00A6' };
+ byte[] input = { 0x00, 0x00, 0x00, 0x0A, 0xC0, 0x80, 0xC3, 0x82, 0xC2, 0xA9, 0xC3, 0x83, 0xC2, 0xA6 };
+ readString32Helper(input, expect);
+ }
+
+ [Test]
+ public void testReadString32_1byteAnd2byteEmbeddedNULLs()
+ {
+ // Test data with 1-byte and 2-byte encoding with embedded NULL's.
+ char[] expect = { '\u0000', '\u0004', '\u00C2', '\u00A9', '\u00C3', '\u0000', '\u00A6' };
+ byte[] input = { 0x00, 0x00, 0x00, 0x0D, 0xC0, 0x80, 0x04, 0xC3, 0x82, 0xC2, 0xA9, 0xC3, 0x83, 0xC0, 0x80, 0xC2, 0xA6 };
+
+ readString32Helper(input, expect);
+ }
+
+ [Test]
+ [ExpectedException(typeof(IOException))]
+ public void testReadString32_UTF8Missing2ndByte()
+ {
+ // Test with bad UTF-8 encoding, missing 2nd byte of two byte value
+ byte[] input = { 0x00, 0x00, 0x00, 0x0D, 0xC0, 0x80, 0x04, 0xC3, 0x82, 0xC2, 0xC2, 0xC3, 0x83, 0xC0, 0x80, 0xC2, 0xA6 };
+
+ MemoryStream stream = new MemoryStream(input);
+ EndianBinaryReader reader = new EndianBinaryReader(stream);
+
+ reader.ReadString32();
+ }
+
+ [Test]
+ [ExpectedException(typeof(IOException))]
+ public void testReadString32_3byteEncodingMissingLastByte()
+ {
+ // Test with three byte encode that's missing a last byte.
+ byte[] input = { 0x00, 0x00, 0x00, 0x02, 0xE8, 0xA8 };
+
+ MemoryStream stream = new MemoryStream(input);
+ EndianBinaryReader reader = new EndianBinaryReader(stream);
+
+ reader.ReadString32();
+ }
+ }
+}
diff --git a/src/test/csharp/EndianBinaryWriterTest.cs b/src/test/csharp/EndianBinaryWriterTest.cs
new file mode 100644
index 0000000..635b449
--- /dev/null
+++ b/src/test/csharp/EndianBinaryWriterTest.cs
@@ -0,0 +1,202 @@
+/*
+ * 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.
+ */
+
+using System;
+using System.IO;
+using Apache.NMS.Util;
+using NUnit.Framework;
+
+namespace Apache.NMS.Test
+{
+ [TestFixture]
+ public class EndianBinaryWriterTest
+ {
+ void writeString16TestHelper(char[] input, byte[] expect)
+ {
+ MemoryStream stream = new MemoryStream();
+ EndianBinaryWriter writer = new EndianBinaryWriter(stream);
+
+ String str = new String(input);
+
+ writer.WriteString16(str);
+
+ byte[] result = stream.GetBuffer();
+
+ Assert.AreEqual(result[0], 0x00);
+ Assert.AreEqual(result[1], expect.Length);
+
+ for(int i = 4; i < expect.Length; ++i)
+ {
+ Assert.AreEqual(result[i], expect[i - 2]);
+ }
+ }
+
+ [Test]
+ public void testWriteString16_1byteUTF8encoding()
+ {
+ // Test data with 1-byte UTF8 encoding.
+ char[] input = { '\u0000', '\u000B', '\u0048', '\u0065', '\u006C', '\u006C', '\u006F', '\u0020', '\u0057', '\u006F', '\u0072', '\u006C', '\u0064' };
+ byte[] expect = { 0xC0, 0x80, 0x0B, 0x48, 0x65, 0x6C, 0x6C, 0x6F, 0x20, 0x57, 0x6F, 0x72, 0x6C, 0x64 };
+
+ writeString16TestHelper(input, expect);
+ }
+
+ [Test]
+ public void testWriteString16_2byteUTF8encoding()
+ {
+ // Test data with 2-byte UT8 encoding.
+ char[] input = { '\u0000', '\u00C2', '\u00A9', '\u00C3', '\u00A6' };
+ byte[] expect = { 0xC0, 0x80, 0xC3, 0x82, 0xC2, 0xA9, 0xC3, 0x83, 0xC2, 0xA6 };
+
+ writeString16TestHelper(input, expect);
+ }
+
+ [Test]
+ public void testWriteString16_1byteAnd2byteEmbeddedNULLs()
+ {
+ // Test data with 1-byte and 2-byte encoding with embedded NULL's.
+ char[] input = { '\u0000', '\u0004', '\u00C2', '\u00A9', '\u00C3', '\u0000', '\u00A6' };
+ byte[] expect = { 0xC0, 0x80, 0x04, 0xC3, 0x82, 0xC2, 0xA9, 0xC3, 0x83, 0xC0, 0x80, 0xC2, 0xA6 };
+
+ writeString16TestHelper(input, expect);
+ }
+
+ [Test]
+ public void testWriteString16_nullstring()
+ {
+ // test that a null string writes no output.
+ MemoryStream stream = new MemoryStream();
+ EndianBinaryWriter writer = new EndianBinaryWriter(stream);
+ writer.WriteString16(null);
+ Assert.AreEqual(0, stream.Length);
+ }
+
+ [Test]
+ public void testWriteString16_emptystring()
+ {
+ // test that a null string writes no output.
+ MemoryStream stream = new MemoryStream();
+ EndianBinaryWriter writer = new EndianBinaryWriter(stream);
+ writer.WriteString16("");
+
+ stream.Seek(0, SeekOrigin.Begin);
+ EndianBinaryReader reader = new EndianBinaryReader(stream);
+ Assert.AreEqual(0, reader.ReadInt16());
+ }
+
+ [Test]
+ [ExpectedException(typeof(IOException))]
+ public void testWriteString16_stringTooLong()
+ {
+ // String of length 65536 of Null Characters.
+ MemoryStream stream = new MemoryStream();
+ EndianBinaryWriter writer = new EndianBinaryWriter(stream);
+ String testStr = new String('a', 65536);
+ writer.Write(testStr);
+ }
+
+ [Test]
+ public void testWriteString16_maxStringLength()
+ {
+ // String of length 65535 of non Null Characters since Null encodes as UTF-8.
+ MemoryStream stream = new MemoryStream();
+ EndianBinaryWriter writer = new EndianBinaryWriter(stream);
+ String testStr = new String('a', 65535);
+ writer.Write(testStr);
+ }
+
+ [Test]
+ [ExpectedException(typeof(IOException))]
+ public void testWriteString16_invalidEncodingHeader()
+ {
+ // Set one of the 65535 bytes to a value that will result in a 2 byte UTF8 encoded sequence.
+ // This will cause the string of length 65535 to have a utf length of 65536.
+ MemoryStream stream = new MemoryStream();
+ EndianBinaryWriter writer = new EndianBinaryWriter(stream);
+ String testStr = new String('a', 65535);
+ char[] array = testStr.ToCharArray();
+ array[0] = '\u0000';
+ testStr = new String(array);
+ writer.Write(testStr);
+ }
+
+ void writeString32TestHelper(char[] input, byte[] expect)
+ {
+ MemoryStream stream = new MemoryStream();
+ EndianBinaryWriter writer = new EndianBinaryWriter(stream);
+
+ String str = new String(input);
+
+ writer.WriteString32(str);
+
+ byte[] result = stream.GetBuffer();
+
+ Assert.AreEqual(result[0], 0x00);
+ Assert.AreEqual(result[1], 0x00);
+ Assert.AreEqual(result[2], 0x00);
+ Assert.AreEqual(result[3], expect.Length);
+
+ for(int i = 4; i < expect.Length; ++i)
+ {
+ Assert.AreEqual(result[i], expect[i - 4]);
+ }
+ }
+
+ [Test]
+ public void testWriteString32_1byteUTF8encoding()
+ {
+ // Test data with 1-byte UTF8 encoding.
+ char[] input = { '\u0000', '\u000B', '\u0048', '\u0065', '\u006C', '\u006C', '\u006F', '\u0020', '\u0057', '\u006F', '\u0072', '\u006C', '\u0064' };
+ byte[] expect = { 0xC0, 0x80, 0x0B, 0x48, 0x65, 0x6C, 0x6C, 0x6F, 0x20, 0x57, 0x6F, 0x72, 0x6C, 0x64 };
+
+ writeString32TestHelper(input, expect);
+ }
+
+ [Test]
+ public void testWriteString32_2byteUTF8encoding()
+ {
+ // Test data with 2-byte UT8 encoding.
+ char[] input = { '\u0000', '\u00C2', '\u00A9', '\u00C3', '\u00A6' };
+ byte[] expect = { 0xC0, 0x80, 0xC3, 0x82, 0xC2, 0xA9, 0xC3, 0x83, 0xC2, 0xA6 };
+
+ writeString32TestHelper(input, expect);
+ }
+
+ [Test]
+ public void testWriteString32_1byteAnd2byteEmbeddedNULLs()
+ {
+ // Test data with 1-byte and 2-byte encoding with embedded NULL's.
+ char[] input = { '\u0000', '\u0004', '\u00C2', '\u00A9', '\u00C3', '\u0000', '\u00A6' };
+ byte[] expect = { 0xC0, 0x80, 0x04, 0xC3, 0x82, 0xC2, 0xA9, 0xC3, 0x83, 0xC0, 0x80, 0xC2, 0xA6 };
+
+ writeString32TestHelper(input, expect);
+ }
+
+ [Test]
+ public void testWriteString32_nullstring()
+ {
+ // test that a null strings writes a -1
+ MemoryStream stream = new MemoryStream();
+ EndianBinaryWriter writer = new EndianBinaryWriter(stream);
+ writer.WriteString32(null);
+
+ stream.Seek(0, SeekOrigin.Begin);
+ EndianBinaryReader reader = new EndianBinaryReader(stream);
+ Assert.AreEqual(-1, reader.ReadInt32());
+ }
+ }
+}
diff --git a/src/test/csharp/EndianTest.cs b/src/test/csharp/EndianTest.cs
new file mode 100644
index 0000000..773eaf1
--- /dev/null
+++ b/src/test/csharp/EndianTest.cs
@@ -0,0 +1,131 @@
+/*
+ * 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.
+ */
+
+using System.IO;
+using Apache.NMS.Util;
+using NUnit.Framework;
+
+namespace Apache.NMS.Test
+{
+ [TestFixture]
+ public class EndianTest
+ {
+ [Test]
+ public void TestLongEndian()
+ {
+ long value = 0x0102030405060708L;
+ long newValue = EndianSupport.SwitchEndian(value);
+ Assert.AreEqual(0x0807060504030201L, newValue);
+ long actual = EndianSupport.SwitchEndian(newValue);
+ Assert.AreEqual(value, actual);
+ }
+
+ [Test]
+ public void TestIntEndian()
+ {
+ int value = 0x12345678;
+ int newValue = EndianSupport.SwitchEndian(value);
+ Assert.AreEqual(0x78563412, newValue);
+ int actual = EndianSupport.SwitchEndian(newValue);
+ Assert.AreEqual(value, actual);
+ }
+
+ [Test]
+ public void TestCharEndian()
+ {
+ char value = 'J';
+ char newValue = EndianSupport.SwitchEndian(value);
+ char actual = EndianSupport.SwitchEndian(newValue);
+ Assert.AreEqual(value, actual);
+ }
+
+ [Test]
+ public void TestShortEndian()
+ {
+ short value = 0x1234;
+ short newValue = EndianSupport.SwitchEndian(value);
+ Assert.AreEqual(0x3412, newValue);
+ short actual = EndianSupport.SwitchEndian(newValue);
+ Assert.AreEqual(value, actual);
+ }
+
+ [Test]
+ public void TestNegativeLongEndian()
+ {
+ long value = -0x0102030405060708L;
+ long newValue = EndianSupport.SwitchEndian(value);
+ long actual = EndianSupport.SwitchEndian(newValue);
+ Assert.AreEqual(value, actual);
+ }
+
+ [Test]
+ public void TestNegativeIntEndian()
+ {
+ int value = -0x12345678;
+ int newValue = EndianSupport.SwitchEndian(value);
+ int actual = EndianSupport.SwitchEndian(newValue);
+ Assert.AreEqual(value, actual);
+ }
+
+ [Test]
+ public void TestNegativeShortEndian()
+ {
+ short value = -0x1234;
+ short newValue = EndianSupport.SwitchEndian(value);
+ short actual = EndianSupport.SwitchEndian(newValue);
+ Assert.AreEqual(value, actual);
+ }
+
+ [Test]
+ public void TestFloatDontNeedEndianSwitch()
+ {
+ float value = -1.223F;
+
+ // Convert to int so we can compare to Java version.
+ MemoryStream ms = new MemoryStream(4);
+ BinaryWriter bw = new BinaryWriter(ms);
+ bw.Write(value);
+ bw.Close();
+ ms = new MemoryStream(ms.ToArray());
+ BinaryReader br = new BinaryReader(ms);
+
+ // System.out.println(Integer.toString(Float.floatToIntBits(-1.223F), 16));
+ Assert.AreEqual(-0x406374bc, br.ReadInt32());
+ }
+
+ [Test]
+ public void TestDoublDontNeedEndianSwitch()
+ {
+ double value = -1.223D;
+
+ // Convert to int so we can compare to Java version.
+ MemoryStream ms = new MemoryStream(4);
+ BinaryWriter bw = new BinaryWriter(ms);
+ bw.Write(value);
+ bw.Close();
+ ms = new MemoryStream(ms.ToArray());
+ BinaryReader br = new BinaryReader(ms);
+ long longVersion = br.ReadInt64();
+
+ // System.out.println(Long.toString(Double.doubleToLongBits(-1.223D), 16));
+ Assert.AreEqual(-0x400c6e978d4fdf3b, longVersion);
+ }
+ }
+}
+
+
+
diff --git a/src/test/csharp/ForeignMessageTransformationTest.cs b/src/test/csharp/ForeignMessageTransformationTest.cs
new file mode 100644
index 0000000..e5870b8
--- /dev/null
+++ b/src/test/csharp/ForeignMessageTransformationTest.cs
@@ -0,0 +1,305 @@
+/*
+ * 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.
+ */
+using System;
+using Apache.NMS.Util;
+using Apache.NMS.Commands;
+using NUnit.Framework;
+
+namespace Apache.NMS.Test
+{
+ //[TestFixture]
+ public class ForeignMessageTransformationTest : NMSTest
+ {
+ private string propertyName = "Test-Property";
+ private string propertyValue = "Test-Property-Value";
+ private string mapElementName = "Test-Map-Property";
+ private string mapElementValue = "Test-Map-Property-Value";
+ private string textBody = "This is a TextMessage from a Foreign Provider";
+ private byte[] bytesContent = {1, 2, 3, 4, 5, 6, 7, 8};
+
+ private bool a = true;
+ private byte b = 123;
+ private char c = 'c';
+ private short d = 0x1234;
+ private int e = 0x12345678;
+ private long f = 0x1234567812345678;
+ private string g = "Hello World!";
+ private bool h = false;
+ private byte i = 0xFF;
+ private short j = -0x1234;
+ private int k = -0x12345678;
+ private long l = -0x1234567812345678;
+ private float m = 2.1F;
+ private double n = 2.3;
+
+ protected ForeignMessageTransformationTest(NMSTestSupport testSupport)
+ : base(testSupport)
+ {
+ }
+
+ //[Test]
+ public virtual void TestSendReceiveForeignMessage(
+ //[Values(MsgDeliveryMode.Persistent, MsgDeliveryMode.NonPersistent)]
+ MsgDeliveryMode deliveryMode, string testTopicRef)
+ {
+ using(IConnection connection = CreateConnection())
+ {
+ connection.Start();
+ using(ISession session = connection.CreateSession(AcknowledgementMode.AutoAcknowledge))
+ {
+ IDestination destination = GetClearDestination(session, DestinationType.Topic, testTopicRef);
+ using(IMessageConsumer consumer = session.CreateConsumer(destination))
+ using(IMessageProducer producer = session.CreateProducer(destination))
+ {
+ try
+ {
+ producer.DeliveryMode = deliveryMode;
+ Message request = new Message();
+ request.Properties[propertyName] = propertyValue;
+
+ producer.Send(request);
+
+ IMessage message = consumer.Receive(receiveTimeout);
+ Assert.IsNotNull(message, "No message returned!");
+ Assert.AreEqual(request.Properties.Count, message.Properties.Count, "Invalid number of properties.");
+ Assert.AreEqual(deliveryMode, message.NMSDeliveryMode, "NMSDeliveryMode does not match");
+
+ // use generic API to access entries
+ Assert.AreEqual(propertyValue, message.Properties[propertyName], "generic map entry: " + propertyName);
+
+ // use type safe APIs
+ Assert.AreEqual(propertyValue, message.Properties.GetString(propertyName), "map entry: " + propertyName);
+ }
+ catch(NotSupportedException)
+ {
+ }
+ }
+ }
+ }
+ }
+
+ //[Test]
+ public virtual void TestSendReceiveForeignTextMessage(
+ //[Values(MsgDeliveryMode.Persistent, MsgDeliveryMode.NonPersistent)]
+ MsgDeliveryMode deliveryMode, string testTopicRef)
+ {
+ using(IConnection connection = CreateConnection())
+ {
+ connection.Start();
+ using(ISession session = connection.CreateSession(AcknowledgementMode.AutoAcknowledge))
+ {
+ IDestination destination = GetClearDestination(session, DestinationType.Topic, testTopicRef);
+ using(IMessageConsumer consumer = session.CreateConsumer(destination))
+ using(IMessageProducer producer = session.CreateProducer(destination))
+ {
+ try
+ {
+ producer.DeliveryMode = deliveryMode;
+ TextMessage request = new TextMessage();
+ request.Properties[propertyName] = propertyValue;
+ request.Text = textBody;
+
+ producer.Send(request);
+
+ ITextMessage message = consumer.Receive(receiveTimeout) as ITextMessage;
+ Assert.IsNotNull(message, "No message returned!");
+ Assert.AreEqual(request.Properties.Count, message.Properties.Count, "Invalid number of properties.");
+ Assert.AreEqual(deliveryMode, message.NMSDeliveryMode, "NMSDeliveryMode does not match");
+
+ // Check the body
+ Assert.AreEqual(textBody, message.Text, "TextMessage body was wrong.");
+
+ // use generic API to access entries
+ Assert.AreEqual(propertyValue, message.Properties[propertyName], "generic map entry: " + propertyName);
+
+ // use type safe APIs
+ Assert.AreEqual(propertyValue, message.Properties.GetString(propertyName), "map entry: " + propertyName);
+ }
+ catch(NotSupportedException)
+ {
+ }
+ }
+ }
+ }
+ }
+
+ //[Test]
+ public virtual void TestSendReceiveForeignBytesMessage(
+ //[Values(MsgDeliveryMode.Persistent, MsgDeliveryMode.NonPersistent)]
+ MsgDeliveryMode deliveryMode, string testTopicRef)
+ {
+ using(IConnection connection = CreateConnection())
+ {
+ connection.Start();
+ using(ISession session = connection.CreateSession(AcknowledgementMode.AutoAcknowledge))
+ {
+ IDestination destination = GetClearDestination(session, DestinationType.Topic, testTopicRef);
+ using(IMessageConsumer consumer = session.CreateConsumer(destination))
+ using(IMessageProducer producer = session.CreateProducer(destination))
+ {
+ try
+ {
+ producer.DeliveryMode = deliveryMode;
+ BytesMessage request = new BytesMessage();
+ request.Properties[propertyName] = propertyValue;
+ request.WriteBytes(bytesContent);
+
+ producer.Send(request);
+
+ IBytesMessage message = consumer.Receive(receiveTimeout) as IBytesMessage;
+ Assert.IsNotNull(message, "No message returned!");
+ Assert.AreEqual(request.Properties.Count, message.Properties.Count, "Invalid number of properties.");
+ Assert.AreEqual(deliveryMode, message.NMSDeliveryMode, "NMSDeliveryMode does not match");
+
+ // Check the body
+ byte[] content = new byte[bytesContent.Length];
+ Assert.AreEqual(bytesContent.Length, message.ReadBytes(content));
+ Assert.AreEqual(bytesContent, content, "BytesMessage body was wrong.");
+
+ // use generic API to access entries
+ Assert.AreEqual(propertyValue, message.Properties[propertyName], "generic map entry: " + propertyName);
+
+ // use type safe APIs
+ Assert.AreEqual(propertyValue, message.Properties.GetString(propertyName), "map entry: " + propertyName);
+ }
+ catch(NotSupportedException)
+ {
+ }
+ }
+ }
+ }
+ }
+
+ //[Test]
+ public virtual void TestSendReceiveForeignMapMessage(
+ //[Values(MsgDeliveryMode.Persistent, MsgDeliveryMode.NonPersistent)]
+ MsgDeliveryMode deliveryMode, string testTopicRef)
+ {
+ using(IConnection connection = CreateConnection())
+ {
+ connection.Start();
+ using(ISession session = connection.CreateSession(AcknowledgementMode.AutoAcknowledge))
+ {
+ IDestination destination = GetClearDestination(session, DestinationType.Topic, testTopicRef);
+ using(IMessageConsumer consumer = session.CreateConsumer(destination))
+ using(IMessageProducer producer = session.CreateProducer(destination))
+ {
+ try
+ {
+ producer.DeliveryMode = deliveryMode;
+ MapMessage request = new MapMessage();
+ request.Properties[propertyName] = propertyValue;
+ request.Body[mapElementName] = mapElementValue;
+
+ producer.Send(request);
+
+ IMapMessage message = consumer.Receive(receiveTimeout) as IMapMessage;
+ Assert.IsNotNull(message, "No message returned!");
+ Assert.AreEqual(request.Properties.Count, message.Properties.Count, "Invalid number of properties.");
+ Assert.AreEqual(deliveryMode, message.NMSDeliveryMode, "NMSDeliveryMode does not match");
+
+ // Check the body
+ Assert.AreEqual(request.Body.Count, message.Body.Count);
+ Assert.AreEqual(mapElementValue, message.Body[mapElementName], "MapMessage body was wrong.");
+
+ // use generic API to access entries
+ Assert.AreEqual(propertyValue, message.Properties[propertyName], "generic map entry: " + propertyName);
+
+ // use type safe APIs
+ Assert.AreEqual(propertyValue, message.Properties.GetString(propertyName), "map entry: " + propertyName);
+ }
+ catch(NotSupportedException)
+ {
+ }
+ }
+ }
+ }
+ }
+
+ //[Test]
+ public virtual void TestSendReceiveForeignStreamMessage(
+ //[Values(MsgDeliveryMode.Persistent, MsgDeliveryMode.NonPersistent)]
+ MsgDeliveryMode deliveryMode, string testTopicRef)
+ {
+ using(IConnection connection = CreateConnection())
+ {
+ connection.Start();
+ using(ISession session = connection.CreateSession(AcknowledgementMode.AutoAcknowledge))
+ {
+ IDestination destination = GetClearDestination(session, DestinationType.Topic, testTopicRef);
+ using(IMessageConsumer consumer = session.CreateConsumer(destination))
+ using(IMessageProducer producer = session.CreateProducer(destination))
+ {
+ try
+ {
+ producer.DeliveryMode = deliveryMode;
+ StreamMessage request = new StreamMessage();
+ request.Properties[propertyName] = propertyValue;
+
+ request.WriteBoolean(a);
+ request.WriteByte(b);
+ request.WriteChar(c);
+ request.WriteInt16(d);
+ request.WriteInt32(e);
+ request.WriteInt64(f);
+ request.WriteString(g);
+ request.WriteBoolean(h);
+ request.WriteByte(i);
+ request.WriteInt16(j);
+ request.WriteInt32(k);
+ request.WriteInt64(l);
+ request.WriteSingle(m);
+ request.WriteDouble(n);
+
+ producer.Send(request);
+
+ IStreamMessage message = consumer.Receive(receiveTimeout) as IStreamMessage;
+ Assert.IsNotNull(message, "No message returned!");
+ Assert.AreEqual(request.Properties.Count, message.Properties.Count, "Invalid number of properties.");
+ Assert.AreEqual(deliveryMode, message.NMSDeliveryMode, "NMSDeliveryMode does not match");
+
+ // Check the body
+ Assert.AreEqual(a, message.ReadBoolean(), "Stream Boolean Value: a");
+ Assert.AreEqual(b, message.ReadByte(), "Stream Byte Value: b");
+ Assert.AreEqual(c, message.ReadChar(), "Stream Char Value: c");
+ Assert.AreEqual(d, message.ReadInt16(), "Stream Int16 Value: d");
+ Assert.AreEqual(e, message.ReadInt32(), "Stream Int32 Value: e");
+ Assert.AreEqual(f, message.ReadInt64(), "Stream Int64 Value: f");
+ Assert.AreEqual(g, message.ReadString(), "Stream String Value: g");
+ Assert.AreEqual(h, message.ReadBoolean(), "Stream Boolean Value: h");
+ Assert.AreEqual(i, message.ReadByte(), "Stream Byte Value: i");
+ Assert.AreEqual(j, message.ReadInt16(), "Stream Int16 Value: j");
+ Assert.AreEqual(k, message.ReadInt32(), "Stream Int32 Value: k");
+ Assert.AreEqual(l, message.ReadInt64(), "Stream Int64 Value: l");
+ Assert.AreEqual(m, message.ReadSingle(), "Stream Single Value: m");
+ Assert.AreEqual(n, message.ReadDouble(), "Stream Double Value: n");
+
+ // use generic API to access entries
+ Assert.AreEqual(propertyValue, message.Properties[propertyName], "generic map entry: " + propertyName);
+
+ // use type safe APIs
+ Assert.AreEqual(propertyValue, message.Properties.GetString(propertyName), "map entry: " + propertyName);
+ }
+ catch(NotSupportedException)
+ {
+ }
+ }
+ }
+ }
+ }
+ }
+}
diff --git a/src/test/csharp/MapMessageTest.cs b/src/test/csharp/MapMessageTest.cs
new file mode 100644
index 0000000..6b7385d
--- /dev/null
+++ b/src/test/csharp/MapMessageTest.cs
@@ -0,0 +1,208 @@
+/*
+ * 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.
+ */
+using System;
+using System.Collections;
+using Apache.NMS.Util;
+using NUnit.Framework;
+
+namespace Apache.NMS.Test
+{
+ //[TestFixture]
+ public class MapMessageTest : NMSTest
+ {
+ protected bool a = true;
+ protected byte b = 123;
+ protected char c = 'c';
+ protected short d = 0x1234;
+ protected int e = 0x12345678;
+ protected long f = 0x1234567812345678;
+ protected string g = "Hello World!";
+ protected bool h = false;
+ protected byte i = 0xFF;
+ protected short j = -0x1234;
+ protected int k = -0x12345678;
+ protected long l = -0x1234567812345678;
+ protected float m = 2.1F;
+ protected double n = 2.3;
+ protected byte[] o = {1, 2, 3, 4, 5};
+
+ protected MapMessageTest(NMSTestSupport testSupport)
+ : base(testSupport)
+ {
+ }
+
+ //[Test]
+ public virtual void TestSendReceiveMapMessage(
+ //[Values(MsgDeliveryMode.Persistent, MsgDeliveryMode.NonPersistent)]
+ MsgDeliveryMode deliveryMode, string testQueueRef)
+ {
+ using(IConnection connection = CreateConnection(GetTestClientId()))
+ {
+ connection.Start();
+ using(ISession session = connection.CreateSession(AcknowledgementMode.AutoAcknowledge))
+ {
+ IDestination destination = GetClearDestination(session, DestinationType.Queue, testQueueRef);
+ using(IMessageConsumer consumer = session.CreateConsumer(destination))
+ using(IMessageProducer producer = session.CreateProducer(destination))
+ {
+ producer.DeliveryMode = deliveryMode;
+ IMapMessage request = session.CreateMapMessage();
+ request.Body["a"] = a;
+ request.Body["b"] = b;
+ request.Body["c"] = c;
+ request.Body["d"] = d;
+ request.Body["e"] = e;
+ request.Body["f"] = f;
+ request.Body["g"] = g;
+ request.Body["h"] = h;
+ request.Body["i"] = i;
+ request.Body["j"] = j;
+ request.Body["k"] = k;
+ request.Body["l"] = l;
+ request.Body["m"] = m;
+ request.Body["n"] = n;
+ request.Body["o"] = o;
+ producer.Send(request);
+
+ IMapMessage message = consumer.Receive(receiveTimeout) as IMapMessage;
+ Assert.IsNotNull(message, "No message returned!");
+ Assert.AreEqual(request.Body.Count, message.Body.Count, "Invalid number of message maps.");
+ Assert.AreEqual(deliveryMode, message.NMSDeliveryMode, "NMSDeliveryMode does not match");
+ Assert.AreEqual(ToHex(f), ToHex(message.Body.GetLong("f")), "map entry: f as hex");
+
+ // use generic API to access entries
+ Assert.AreEqual(a, message.Body["a"], "generic map entry: a");
+ Assert.AreEqual(b, message.Body["b"], "generic map entry: b");
+ Assert.AreEqual(c, message.Body["c"], "generic map entry: c");
+ Assert.AreEqual(d, message.Body["d"], "generic map entry: d");
+ Assert.AreEqual(e, message.Body["e"], "generic map entry: e");
+ Assert.AreEqual(f, message.Body["f"], "generic map entry: f");
+ Assert.AreEqual(g, message.Body["g"], "generic map entry: g");
+ Assert.AreEqual(h, message.Body["h"], "generic map entry: h");
+ Assert.AreEqual(i, message.Body["i"], "generic map entry: i");
+ Assert.AreEqual(j, message.Body["j"], "generic map entry: j");
+ Assert.AreEqual(k, message.Body["k"], "generic map entry: k");
+ Assert.AreEqual(l, message.Body["l"], "generic map entry: l");
+ Assert.AreEqual(m, message.Body["m"], "generic map entry: m");
+ Assert.AreEqual(n, message.Body["n"], "generic map entry: n");
+ Assert.AreEqual(o, message.Body["o"], "generic map entry: o");
+
+ // use type safe APIs
+ Assert.AreEqual(a, message.Body.GetBool("a"), "map entry: a");
+ Assert.AreEqual(b, message.Body.GetByte("b"), "map entry: b");
+ Assert.AreEqual(c, message.Body.GetChar("c"), "map entry: c");
+ Assert.AreEqual(d, message.Body.GetShort("d"), "map entry: d");
+ Assert.AreEqual(e, message.Body.GetInt("e"), "map entry: e");
+ Assert.AreEqual(f, message.Body.GetLong("f"), "map entry: f");
+ Assert.AreEqual(g, message.Body.GetString("g"), "map entry: g");
+ Assert.AreEqual(h, message.Body.GetBool("h"), "map entry: h");
+ Assert.AreEqual(i, message.Body.GetByte("i"), "map entry: i");
+ Assert.AreEqual(j, message.Body.GetShort("j"), "map entry: j");
+ Assert.AreEqual(k, message.Body.GetInt("k"), "map entry: k");
+ Assert.AreEqual(l, message.Body.GetLong("l"), "map entry: l");
+ Assert.AreEqual(m, message.Body.GetFloat("m"), "map entry: m");
+ Assert.AreEqual(n, message.Body.GetDouble("n"), "map entry: n");
+ Assert.AreEqual(o, message.Body.GetBytes("o"), "map entry: o");
+ }
+ }
+ }
+ }
+
+ //[Test]
+ public virtual void TestSendReceiveNestedMapMessage(
+ //[Values(MsgDeliveryMode.Persistent, MsgDeliveryMode.NonPersistent)]
+ MsgDeliveryMode deliveryMode, string testQueueRef)
+ {
+ using(IConnection connection = CreateConnection(GetTestClientId()))
+ {
+ connection.Start();
+ using(ISession session = connection.CreateSession(AcknowledgementMode.AutoAcknowledge))
+ {
+ IDestination destination = GetClearDestination(session, DestinationType.Queue, testQueueRef);
+ using(IMessageConsumer consumer = session.CreateConsumer(destination))
+ using(IMessageProducer producer = session.CreateProducer(destination))
+ {
+ try
+ {
+ producer.DeliveryMode = deliveryMode;
+ IMapMessage request = session.CreateMapMessage();
+ const string textFieldValue = "Nested Map Messages Rule!";
+
+ request.Body.SetString("textField", textFieldValue);
+
+ IDictionary grandChildMap = new Hashtable();
+ grandChildMap["x"] = "abc";
+ grandChildMap["y"] = new ArrayList(new object[] { "a", "b", "c" });
+
+ IDictionary nestedMap = new Hashtable();
+ nestedMap["a"] = "foo";
+ nestedMap["b"] = (int) 23;
+ nestedMap["c"] = (long) 45;
+ nestedMap["d"] = grandChildMap;
+
+ request.Body.SetDictionary("mapField", nestedMap);
+ request.Body.SetList("listField", new ArrayList(new Object[] { "a", "b", "c" }));
+
+ producer.Send(request);
+
+ IMapMessage message = consumer.Receive(receiveTimeout) as IMapMessage;
+ Assert.IsNotNull(message, "No message returned!");
+ Assert.AreEqual(request.Body.Count, message.Body.Count, "Invalid number of message maps.");
+ Assert.AreEqual(deliveryMode, message.NMSDeliveryMode, "NMSDeliveryMode does not match");
+
+ string textFieldResponse = message.Body.GetString("textField");
+ Assert.AreEqual(textFieldValue, textFieldResponse, "textField does not match.");
+
+ IDictionary nestedMapResponse = message.Body.GetDictionary("mapField");
+ Assert.IsNotNull(nestedMapResponse, "Nested map not returned.");
+ Assert.AreEqual(nestedMap.Count, nestedMapResponse.Count, "nestedMap: Wrong number of elements");
+ Assert.AreEqual("foo", nestedMapResponse["a"], "nestedMap: a");
+ Assert.AreEqual(23, nestedMapResponse["b"], "nestedMap: b");
+ Assert.AreEqual(45, nestedMapResponse["c"], "nestedMap: c");
+
+ IDictionary grandChildMapResponse = nestedMapResponse["d"] as IDictionary;
+ Assert.IsNotNull(grandChildMapResponse, "Grand child map not returned.");
+ Assert.AreEqual(grandChildMap.Count, grandChildMapResponse.Count, "grandChildMap: Wrong number of elements");
+ Assert.AreEqual(grandChildMapResponse["x"], "abc", "grandChildMap: x");
+
+ IList grandChildList = grandChildMapResponse["y"] as IList;
+ Assert.IsNotNull(grandChildList, "Grand child list not returned.");
+ Assert.AreEqual(3, grandChildList.Count, "grandChildList: Wrong number of list elements.");
+ Assert.AreEqual("a", grandChildList[0], "grandChildList: a");
+ Assert.AreEqual("b", grandChildList[1], "grandChildList: b");
+ Assert.AreEqual("c", grandChildList[2], "grandChildList: c");
+
+ IList listFieldResponse = message.Body.GetList("listField");
+ Assert.IsNotNull(listFieldResponse, "Nested list not returned.");
+ Assert.AreEqual(3, listFieldResponse.Count, "listFieldResponse: Wrong number of list elements.");
+ Assert.AreEqual("a", listFieldResponse[0], "listFieldResponse: a");
+ Assert.AreEqual("b", listFieldResponse[1], "listFieldResponse: b");
+ Assert.AreEqual("c", listFieldResponse[2], "listFieldResponse: c");
+ }
+ catch(NotSupportedException)
+ {
+ }
+ catch(NMSException e)
+ {
+ Assert.IsTrue(e.InnerException.GetType() == typeof(NotSupportedException));
+ }
+ }
+ }
+ }
+ }
+ }
+}
diff --git a/src/test/csharp/MessageSelectorTest.cs b/src/test/csharp/MessageSelectorTest.cs
new file mode 100644
index 0000000..03f0a4e
--- /dev/null
+++ b/src/test/csharp/MessageSelectorTest.cs
@@ -0,0 +1,184 @@
+/*
+ * 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.
+ */
+using System;
+using System.Threading;
+using Apache.NMS.Util;
+using NUnit.Framework;
+
+namespace Apache.NMS.Test
+{
+ //[TestFixture]
+ //[Category("LongRunning")]
+ public class MessageSelectorTest : NMSTest
+ {
+ private int receivedNonIgnoredMsgCount = 0;
+ private int receivedIgnoredMsgCount = 0;
+ private bool simulateSlowConsumer = false;
+
+ protected MessageSelectorTest(NMSTestSupport testSupport)
+ : base(testSupport)
+ {
+ }
+
+ //[Test]
+ public virtual void TestFilterIgnoredMessages(
+ //[Values(SELECTOR_TEST_QUEUE_URI, SELECTOR_TEST_TOPIC_URI)]
+ string testDestinationURI)
+ {
+ simulateSlowConsumer = false;
+ RunFilterIgnoredMessagesTest(testDestinationURI);
+ }
+
+ /// <summary>
+ /// A slow consumer will trigger the producer flow control on the broker when the destination is
+ /// a queue. It will also trigger the consumer flow control by slowing down the feed to all of the
+ /// consumers on the queue to only send messages as fast as the slowest consumer can run.
+ /// When sending to a topic, the producer will not be slowed down, and consumers will be allowed
+ /// to run as fast as they can go.
+ /// Since this test can take a long time to run, it is marked as explicit.
+ /// </summary>
+ /// <param name="testDestinationURI"></param>
+ //[Test]
+ public virtual void TestFilterIgnoredMessagesSlowConsumer(
+ //[Values(SELECTOR_TEST_QUEUE_URI, SELECTOR_TEST_TOPIC_URI)]
+ string testDestinationURI)
+ {
+ simulateSlowConsumer = true;
+ RunFilterIgnoredMessagesTest(testDestinationURI);
+ }
+
+ public void RunFilterIgnoredMessagesTest(string testDestinationURI)
+ {
+ TimeSpan ttl = TimeSpan.FromMinutes(30);
+ const int MaxNumRequests = 100000;
+
+ using(IConnection connection1 = CreateConnection(GetTestClientId()))
+ using(IConnection connection2 = CreateConnection(GetTestClientId()))
+ using(IConnection connection3 = CreateConnection(GetTestClientId()))
+ {
+ connection1.Start();
+ connection2.Start();
+ connection3.Start();
+ using(ISession session1 = connection1.CreateSession(AcknowledgementMode.AutoAcknowledge))
+ using(ISession session2 = connection2.CreateSession(AcknowledgementMode.AutoAcknowledge))
+ using(ISession session3 = connection3.CreateSession(AcknowledgementMode.AutoAcknowledge))
+ {
+ IDestination destination1 = GetClearDestination(session1, testDestinationURI);
+ IDestination destination2 = GetClearDestination(session2, testDestinationURI);
+ IDestination destination3 = GetClearDestination(session3, testDestinationURI);
+
+ using(IMessageProducer producer = session1.CreateProducer(destination1))
+ using(IMessageConsumer consumer1 = session2.CreateConsumer(destination2, "JMSType NOT LIKE '%IGNORE'"))
+ {
+ int numNonIgnoredMsgsSent = 0;
+ int numIgnoredMsgsSent = 0;
+
+ producer.DeliveryMode = MsgDeliveryMode.NonPersistent;
+
+ receivedNonIgnoredMsgCount = 0;
+ receivedIgnoredMsgCount = 0;
+ consumer1.Listener += new MessageListener(OnNonIgnoredMessage);
+ IMessageConsumer consumer2 = null;
+
+ for(int index = 1; index <= MaxNumRequests; index++)
+ {
+ IMessage request = session1.CreateTextMessage(String.Format("Hello World! [{0} of {1}]", index, MaxNumRequests));
+
+ request.NMSTimeToLive = ttl;
+ if(0 == (index % 2))
+ {
+ request.NMSType = "ACTIVE";
+ numNonIgnoredMsgsSent++;
+ }
+ else
+ {
+ request.NMSType = "ACTIVE.IGNORE";
+ numIgnoredMsgsSent++;
+ }
+
+ producer.Send(request);
+
+ if(2000 == index)
+ {
+ // Start the second consumer
+ if(destination3.IsTopic)
+ {
+ // Reset the ignored message sent count, since all previous messages
+ // will not have been consumed on a topic.
+ numIgnoredMsgsSent = 0;
+ }
+
+ consumer2 = session3.CreateConsumer(destination3, "JMSType LIKE '%IGNORE'");
+ consumer2.Listener += new MessageListener(OnIgnoredMessage);
+ }
+ }
+
+ // Create a waiting loop that will coordinate the end of the test. It checks
+ // to see that all intended messages were received. It will continue to wait as
+ // long as new messages are being received. If it stops receiving messages before
+ // it receives everything it expects, it will eventually timeout and the test will fail.
+ int waitCount = 0;
+ int lastReceivedINongnoredMsgCount = receivedNonIgnoredMsgCount;
+ int lastReceivedIgnoredMsgCount = receivedIgnoredMsgCount;
+
+ while(receivedNonIgnoredMsgCount < numNonIgnoredMsgsSent
+ || receivedIgnoredMsgCount < numIgnoredMsgsSent)
+ {
+ if(lastReceivedINongnoredMsgCount != receivedNonIgnoredMsgCount
+ || lastReceivedIgnoredMsgCount != receivedIgnoredMsgCount)
+ {
+ // Reset the wait count.
+ waitCount = 0;
+ }
+ else
+ {
+ waitCount++;
+ }
+
+ lastReceivedINongnoredMsgCount = receivedNonIgnoredMsgCount;
+ lastReceivedIgnoredMsgCount = receivedIgnoredMsgCount;
+
+ Assert.IsTrue(waitCount <= 30, String.Format("Timeout waiting for all messages to be delivered. Only {0} of {1} non-ignored messages delivered. Only {2} of {3} ignored messages delivered.",
+ receivedNonIgnoredMsgCount, numNonIgnoredMsgsSent, receivedIgnoredMsgCount, numIgnoredMsgsSent));
+ Thread.Sleep(1000);
+ }
+
+ consumer2.Dispose();
+ }
+ }
+ }
+ }
+
+ protected void OnNonIgnoredMessage(IMessage message)
+ {
+ receivedNonIgnoredMsgCount++;
+ Assert.AreEqual(message.NMSType, "ACTIVE");
+ }
+
+ protected void OnIgnoredMessage(IMessage message)
+ {
+ receivedIgnoredMsgCount++;
+ Assert.AreEqual(message.NMSType, "ACTIVE.IGNORE");
+ if(simulateSlowConsumer)
+ {
+ // Simulate a slow consumer It doesn't have to be too slow in a high speed environment
+ // in order to trigger producer flow control.
+ Thread.Sleep(10);
+ }
+ }
+ }
+}
diff --git a/src/test/csharp/MessageTest.cs b/src/test/csharp/MessageTest.cs
new file mode 100644
index 0000000..228ed98
--- /dev/null
+++ b/src/test/csharp/MessageTest.cs
@@ -0,0 +1,147 @@
+/*
+ * 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.
+ */
+using System;
+using Apache.NMS.Util;
+using NUnit.Framework;
+
+namespace Apache.NMS.Test
+{
+ //[TestFixture]
+ public class MessageTest : NMSTest
+ {
+ protected bool a = true;
+ protected byte b = 123;
+ protected char c = 'c';
+ protected short d = 0x1234;
+ protected int e = 0x12345678;
+ protected long f = 0x1234567812345678;
+ protected string g = "Hello World!";
+ protected bool h = false;
+ protected byte i = 0xFF;
+ protected short j = -0x1234;
+ protected int k = -0x12345678;
+ protected long l = -0x1234567812345678;
+ protected float m = 2.1F;
+ protected double n = 2.3;
+ protected byte[] o = {1, 2, 3, 4, 5};
+
+ protected MessageTest(NMSTestSupport testSupport)
+ : base(testSupport)
+ {
+ }
+
+ //[Test]
+ public virtual void TestSendReceiveMessageProperties(
+ //[Values(MsgDeliveryMode.Persistent, MsgDeliveryMode.NonPersistent)]
+ MsgDeliveryMode deliveryMode, string testQueueRef)
+ {
+ using(IConnection connection = CreateConnection(GetTestClientId()))
+ {
+ connection.Start();
+ using(ISession session = connection.CreateSession(AcknowledgementMode.AutoAcknowledge))
+ {
+ IDestination destination = GetClearDestination(session, DestinationType.Queue, testQueueRef);
+ using(IMessageConsumer consumer = session.CreateConsumer(destination))
+ using(IMessageProducer producer = session.CreateProducer(destination))
+ {
+ producer.DeliveryMode = deliveryMode;
+ IMessage request = session.CreateMessage();
+ request.Properties["a"] = a;
+ request.Properties["b"] = b;
+ request.Properties["c"] = c;
+ request.Properties["d"] = d;
+ request.Properties["e"] = e;
+ request.Properties["f"] = f;
+ request.Properties["g"] = g;
+ request.Properties["h"] = h;
+ request.Properties["i"] = i;
+ request.Properties["j"] = j;
+ request.Properties["k"] = k;
+ request.Properties["l"] = l;
+ request.Properties["m"] = m;
+ request.Properties["n"] = n;
+
+ try
+ {
+ request.Properties["o"] = o;
+ Assert.Fail("Should not be able to add a Byte[] to the Properties of a Message.");
+ }
+ catch
+ {
+ // Expected
+ }
+
+ try
+ {
+ request.Properties.SetBytes("o", o);
+ Assert.Fail("Should not be able to add a Byte[] to the Properties of a Message.");
+ }
+ catch
+ {
+ // Expected
+ }
+
+ producer.Send(request);
+
+ IMessage message = consumer.Receive(receiveTimeout);
+ Assert.IsNotNull(message, "No message returned!");
+ Assert.AreEqual(request.Properties.Count, message.Properties.Count, "Invalid number of properties.");
+ Assert.AreEqual(deliveryMode, message.NMSDeliveryMode, "NMSDeliveryMode does not match");
+ Assert.AreEqual(ToHex(f), ToHex(message.Properties.GetLong("f")), "map entry: f as hex");
+
+ // use generic API to access entries
+ // Perform a string only comparison here since some NMS providers are type limited and
+ // may return only a string instance from the generic [] accessor. Each provider should
+ // further test this functionality to determine that the correct type is returned if
+ // it is capable of doing so.
+ Assert.AreEqual(a.ToString(), message.Properties["a"].ToString(), "generic map entry: a");
+ Assert.AreEqual(b.ToString(), message.Properties["b"].ToString(), "generic map entry: b");
+ Assert.AreEqual(c.ToString(), message.Properties["c"].ToString(), "generic map entry: c");
+ Assert.AreEqual(d.ToString(), message.Properties["d"].ToString(), "generic map entry: d");
+ Assert.AreEqual(e.ToString(), message.Properties["e"].ToString(), "generic map entry: e");
+ Assert.AreEqual(f.ToString(), message.Properties["f"].ToString(), "generic map entry: f");
+ Assert.AreEqual(g.ToString(), message.Properties["g"].ToString(), "generic map entry: g");
+ Assert.AreEqual(h.ToString(), message.Properties["h"].ToString(), "generic map entry: h");
+ Assert.AreEqual(i.ToString(), message.Properties["i"].ToString(), "generic map entry: i");
+ Assert.AreEqual(j.ToString(), message.Properties["j"].ToString(), "generic map entry: j");
+ Assert.AreEqual(k.ToString(), message.Properties["k"].ToString(), "generic map entry: k");
+ Assert.AreEqual(l.ToString(), message.Properties["l"].ToString(), "generic map entry: l");
+ Assert.AreEqual(m.ToString(), message.Properties["m"].ToString(), "generic map entry: m");
+ Assert.AreEqual(n.ToString(), message.Properties["n"].ToString(), "generic map entry: n");
+
+ // use type safe APIs
+ Assert.AreEqual(a, message.Properties.GetBool("a"), "map entry: a");
+ Assert.AreEqual(b, message.Properties.GetByte("b"), "map entry: b");
+ Assert.AreEqual(c, message.Properties.GetChar("c"), "map entry: c");
+ Assert.AreEqual(d, message.Properties.GetShort("d"), "map entry: d");
+ Assert.AreEqual(e, message.Properties.GetInt("e"), "map entry: e");
+ Assert.AreEqual(f, message.Properties.GetLong("f"), "map entry: f");
+ Assert.AreEqual(g, message.Properties.GetString("g"), "map entry: g");
+ Assert.AreEqual(h, message.Properties.GetBool("h"), "map entry: h");
+ Assert.AreEqual(i, message.Properties.GetByte("i"), "map entry: i");
+ Assert.AreEqual(j, message.Properties.GetShort("j"), "map entry: j");
+ Assert.AreEqual(k, message.Properties.GetInt("k"), "map entry: k");
+ Assert.AreEqual(l, message.Properties.GetLong("l"), "map entry: l");
+ Assert.AreEqual(m, message.Properties.GetFloat("m"), "map entry: m");
+ Assert.AreEqual(n, message.Properties.GetDouble("n"), "map entry: n");
+ }
+ }
+ }
+ }
+ }
+}
+
diff --git a/src/test/csharp/MessageTransformerTest.cs b/src/test/csharp/MessageTransformerTest.cs
new file mode 100644
index 0000000..f2d5b12
--- /dev/null
+++ b/src/test/csharp/MessageTransformerTest.cs
@@ -0,0 +1,124 @@
+/*
+ * 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.
+ */
+using System;
+using Apache.NMS.Util;
+using NUnit.Framework;
+
+namespace Apache.NMS.Test
+{
+ //[TestFixture]
+ public class MessageTransformerTest : NMSTest
+ {
+ private string propertyName = "ADDITIONAL-PROPERTY";
+ private string propertyValue = "ADDITIONAL-PROPERTY-VALUE";
+
+ protected MessageTransformerTest(NMSTestSupport testSupport)
+ : base(testSupport)
+ {
+ }
+
+ //[Test]
+ public virtual void TestProducerTransformer(
+ //[Values(MsgDeliveryMode.Persistent, MsgDeliveryMode.NonPersistent)]
+ MsgDeliveryMode deliveryMode)
+ {
+ using(IConnection connection = CreateConnection())
+ {
+ connection.Start();
+ using(ISession session = connection.CreateSession(AcknowledgementMode.AutoAcknowledge))
+ {
+ IDestination destination = session.CreateTemporaryTopic();
+ using(IMessageConsumer consumer = session.CreateConsumer(destination))
+ using(IMessageProducer producer = session.CreateProducer(destination))
+ {
+ producer.DeliveryMode = deliveryMode;
+ producer.ProducerTransformer = DoProducerTransform;
+
+ IMessage message = session.CreateMessage();
+
+ message.Properties["Test"] = "Value";
+
+ producer.Send(message);
+
+ message = consumer.Receive(TimeSpan.FromMilliseconds(5000));
+
+ Assert.IsNotNull(message);
+ Assert.IsTrue(message.Properties.Count == 2);
+
+ Assert.AreEqual("Value", message.Properties["Test"]);
+ Assert.AreEqual(propertyValue, message.Properties[propertyName]);
+ }
+ }
+ }
+ }
+
+ //[Test]
+ public virtual void TestConsumerTransformer(
+ //[Values(MsgDeliveryMode.Persistent, MsgDeliveryMode.NonPersistent)]
+ MsgDeliveryMode deliveryMode)
+ {
+ using(IConnection connection = CreateConnection())
+ {
+ connection.Start();
+ using(ISession session = connection.CreateSession(AcknowledgementMode.AutoAcknowledge))
+ {
+ IDestination destination = session.CreateTemporaryTopic();
+ using(IMessageConsumer consumer = session.CreateConsumer(destination))
+ using(IMessageProducer producer = session.CreateProducer(destination))
+ {
+ producer.DeliveryMode = deliveryMode;
+
+ consumer.ConsumerTransformer = DoConsumerTransform;
+
+ IMessage message = session.CreateMessage();
+
+ message.Properties["Test"] = "Value";
+
+ producer.Send(message);
+
+ message = consumer.Receive(TimeSpan.FromMilliseconds(5000));
+
+ Assert.IsNotNull(message);
+ Assert.IsTrue(message.Properties.Count == 2, "Property Count should be 2");
+
+ Assert.AreEqual("Value", message.Properties["Test"], "Property 'Value' was incorrect");
+ Assert.AreEqual(propertyValue, message.Properties[propertyName], "Property not inserted");
+ }
+ }
+ }
+ }
+
+ private IMessage DoProducerTransform(ISession session, IMessageProducer producer, IMessage message)
+ {
+ message.Properties[propertyName] = propertyValue;
+
+ return message;
+ }
+
+ private IMessage DoConsumerTransform(ISession session, IMessageConsumer consumer, IMessage message)
+ {
+ IMessage newMessage = session.CreateMessage();
+
+ MessageTransformation.CopyNMSMessageProperties(message, newMessage);
+
+ newMessage.Properties[propertyName] = propertyValue;
+
+ return newMessage;
+ }
+ }
+}
+
diff --git a/src/test/csharp/NMSPropertyTest.cs b/src/test/csharp/NMSPropertyTest.cs
new file mode 100644
index 0000000..82b1021
--- /dev/null
+++ b/src/test/csharp/NMSPropertyTest.cs
@@ -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.
+ */
+using System;
+using Apache.NMS.Util;
+using NUnit.Framework;
+
+namespace Apache.NMS.Test
+{
+ //[TestFixture]
+ public class NMSPropertyTest : NMSTest
+ {
+ // standard NMS properties
+ protected string expectedText = "Hey this works!";
+ protected string correlationID = "FooBar";
+ protected MsgPriority priority = MsgPriority.Normal;
+ protected String type = "FooType";
+ protected String groupID = "BarGroup";
+ protected int groupSeq = 1;
+
+ protected NMSPropertyTest(NMSTestSupport testSupport)
+ : base (testSupport)
+ {
+ }
+
+ //[Test]
+ public void TestSendReceiveNMSProperties(
+ //[Values(MsgDeliveryMode.Persistent, MsgDeliveryMode.NonPersistent)]
+ MsgDeliveryMode deliveryMode, string testQueueRef)
+ {
+ using(IConnection connection = CreateConnection(GetTestClientId()))
+ {
+ connection.Start();
+ using(ISession session = connection.CreateSession(AcknowledgementMode.AutoAcknowledge))
+ {
+ IDestination destination = GetClearDestination(session, DestinationType.Queue, testQueueRef);
+ using(IMessageConsumer consumer = session.CreateConsumer(destination))
+ using(IMessageProducer producer = session.CreateProducer(destination))
+ {
+ producer.Priority = priority;
+ producer.DeliveryMode = deliveryMode;
+ ITextMessage request = session.CreateTextMessage(expectedText);
+
+ // Set the headers
+ request.NMSCorrelationID = correlationID;
+ request.NMSType = type;
+ request.Properties["NMSXGroupID"] = groupID;
+ request.Properties["NMSXGroupSeq"] = groupSeq;
+
+ producer.Send(request);
+
+ ITextMessage message = consumer.Receive(receiveTimeout) as ITextMessage;
+
+ Assert.IsNotNull(message, "Did not receive an ITextMessage!");
+ Assert.AreEqual(expectedText, message.Text, "Message text does not match.");
+
+ // compare standard NMS headers
+ Assert.AreEqual(correlationID, message.NMSCorrelationID, "NMSCorrelationID does not match");
+ Assert.AreEqual(deliveryMode, message.NMSDeliveryMode, "NMSDeliveryMode does not match");
+ Assert.AreEqual(priority, message.NMSPriority, "NMSPriority does not match");
+ Assert.AreEqual(type, message.NMSType, "NMSType does not match");
+ Assert.AreEqual(groupID, message.Properties["NMSXGroupID"], "NMSXGroupID does not match");
+ Assert.AreEqual(groupSeq, message.Properties["NMSXGroupSeq"], "NMSXGroupSeq does not match");
+ }
+ }
+ }
+ }
+ }
+}
diff --git a/src/test/csharp/NMSTest.cs b/src/test/csharp/NMSTest.cs
new file mode 100644
index 0000000..1069586
--- /dev/null
+++ b/src/test/csharp/NMSTest.cs
@@ -0,0 +1,508 @@
+/*
+ * 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.
+ */
+using System;
+using System.Xml;
+using Apache.NMS.Util;
+using NUnit.Framework;
+
+namespace Apache.NMS.Test
+{
+ /// <summary>
+ /// Base class for test cases
+ /// </summary>
+ public abstract class NMSTest
+ {
+ protected TimeSpan receiveTimeout = TimeSpan.FromMilliseconds(15000);
+
+ public static string ToHex(long value)
+ {
+ return String.Format("{0:x}", value);
+ }
+
+ #region Constructors and test support
+
+ private NMSTestSupport testSupport;
+
+ static NMSTest()
+ {
+ Apache.NMS.Tracer.Trace = new NMSTracer();
+ }
+
+ protected NMSTest(NMSTestSupport testSupport)
+ {
+ this.testSupport = testSupport;
+ this.testSupport.TestClassType = this.GetType();
+ }
+
+ #endregion
+
+ #region Set up and tear down
+
+ [SetUp]
+ public virtual void SetUp()
+ {
+ this.testSupport.SetUp();
+ }
+
+ [TearDown]
+ public virtual void TearDown()
+ {
+ this.testSupport.TearDown();
+ }
+
+ #endregion
+
+ #region Configuration file
+
+ /// <summary>
+ /// The configuration document.
+ /// </summary>
+ public XmlDocument ConfigurationDocument
+ {
+ get { return this.testSupport.ConfigurationDocument; }
+ }
+
+ /// <summary>
+ /// Loads the configuration file.
+ /// </summary>
+ /// <returns>XmlDocument of the configuration file</returns>
+ protected virtual XmlDocument LoadConfigFile()
+ {
+ return this.testSupport.LoadConfigFile();
+ }
+
+ /// <summary>
+ /// Loads the configuration file.
+ /// </summary>
+ /// <param name="configFilePath">Configuration file path</param>
+ /// <returns>XmlDocument of the configuration file</returns>
+ protected virtual XmlDocument LoadConfigFile(string configFilePath)
+ {
+ return this.testSupport.LoadConfigFile(configFilePath);
+ }
+
+ /// <summary>
+ /// Gets the path of the configuration filename.
+ /// </summary>
+ /// <returns>Path of the configuration filename</returns>
+ protected virtual string GetConfigFilePath()
+ {
+ return this.testSupport.GetConfigFilePath();
+ }
+
+ /// <summary>
+ /// Gets the environment variable name for the configuration file path.
+ /// </summary>
+ /// <returns>Environment variable name</returns>
+ protected virtual string GetConfigEnvVarName()
+ {
+ return this.testSupport.GetConfigEnvVarName();
+ }
+
+ /// <summary>
+ /// Gets the default name for the configuration filename.
+ /// </summary>
+ /// <returns>Default name of the configuration filename</returns>
+ protected virtual string GetDefaultConfigFileName()
+ {
+ return this.testSupport.GetDefaultConfigFileName();
+ }
+
+ /// <summary>
+ /// Gets the value of the "value" attribute of the specified node.
+ /// </summary>
+ /// <param name="parentNode">Parent node</param>
+ /// <param name="nodeName">Node name</param>
+ /// <param name="defaultVaue">Default value</param>
+ /// <returns></returns>
+ protected virtual string GetNodeValueAttribute(XmlElement parentNode,
+ string nodeName, string defaultVaue)
+ {
+ return this.testSupport.GetNodeValueAttribute(parentNode,
+ nodeName, defaultVaue);
+ }
+
+ #endregion
+
+ #region URI node
+
+ /// <summary>
+ /// Gets the URI node for the default configuration.
+ /// </summary>
+ /// <returns>URI node for the default configuration name</returns>
+ public virtual XmlElement GetURINode()
+ {
+ return this.testSupport.GetURINode();
+ }
+
+ /// <summary>
+ /// Gets the URI node for the default configuration.
+ /// </summary>
+ /// <param name="nameTestURI">Name of the default configuration node
+ /// </param>
+ /// <returns>URI node for the default configuration name</returns>
+ public virtual XmlElement GetURINode(string nameTestURI)
+ {
+ return this.testSupport.GetURINode(nameTestURI);
+ }
+
+ /// <summary>
+ /// Gets the name of the default connection configuration to be loaded.
+ /// </summary>
+ /// <returns>Default configuration name</returns>
+ protected virtual string GetNameTestURI()
+ {
+ return this.testSupport.GetNameTestURI();
+ }
+
+ #endregion
+
+ #region Factory
+
+ private NMSConnectionFactory nmsFactory;
+ /// <summary>
+ /// The connection factory interface property.
+ /// </summary>
+ public IConnectionFactory Factory
+ {
+ get { return this.testSupport.Factory; }
+ }
+
+ /// <summary>
+ /// Create the NMS Factory that can create NMS Connections.
+ /// </summary>
+ /// <returns>Connection factory</returns>
+ protected NMSConnectionFactory CreateNMSFactory()
+ {
+ return this.testSupport.CreateNMSFactory();
+ }
+
+ /// <summary>
+ /// Create the NMS Factory that can create NMS Connections. This
+ /// function loads the connection settings from the configuration file.
+ /// </summary>
+ /// <param name="nameTestURI">The named connection configuration.
+ /// </param>
+ /// <returns>Connection factory</returns>
+ protected NMSConnectionFactory CreateNMSFactory(string nameTestURI)
+ {
+ return this.testSupport.CreateNMSFactory(nameTestURI);
+ }
+
+ /// <summary>
+ /// Get the parameters for the ConnectionFactory from the configuration
+ /// file.
+ /// </summary>
+ /// <param name="uriNode">Parent node of the factoryParams node.</param>
+ /// <returns>Object array of parameter objects to be passsed to provider
+ /// factory object. Null if no parameters are specified in
+ /// configuration file.</returns>
+ protected object[] GetFactoryParams(XmlElement uriNode)
+ {
+ return this.testSupport.GetFactoryParams(uriNode);
+ }
+
+ #endregion
+
+ #region Client id and connection
+
+ /// <summary>
+ /// Client id.
+ /// </summary>
+ public string ClientId
+ {
+ get { return this.testSupport.ClientId; }
+ }
+
+ /// <summary>
+ /// Gets a new client id.
+ /// </summary>
+ /// <returns>Client id</returns>
+ public virtual string GetTestClientId()
+ {
+ return this.testSupport.GetTestClientId();
+ }
+
+ /// <summary>
+ /// Create a new connection to the broker.
+ /// </summary>
+ /// <returns>New connection</returns>
+ public virtual IConnection CreateConnection()
+ {
+ return this.testSupport.CreateConnection();
+ }
+
+ /// <summary>
+ /// Create a new connection to the broker.
+ /// </summary>
+ /// <param name="newClientId">Client ID of the new connection.</param>
+ /// <returns>New connection</returns>
+ public virtual IConnection CreateConnection(string newClientId)
+ {
+ return this.testSupport.CreateConnection(newClientId);
+ }
+
+ /// <summary>
+ /// Create a new connection to the broker, and start it.
+ /// </summary>
+ /// <returns>Started connection</returns>
+ public virtual IConnection CreateConnectionAndStart()
+ {
+ return this.testSupport.CreateConnectionAndStart();
+ }
+
+ /// <summary>
+ /// Create a new connection to the broker, and start it.
+ /// </summary>
+ /// <param name="newClientId">Client ID of the new connection.</param>
+ /// <returns>Started connection</returns>
+ public virtual IConnection CreateConnectionAndStart(string newClientId)
+ {
+ return this.testSupport.CreateConnectionAndStart(newClientId);
+ }
+
+ #endregion
+
+ #region Destination
+
+ /// <summary>
+ /// Gets a clear destination.
+ /// </summary>
+ /// <param name="session">Session</param>
+ /// <param name="type">Destination type</param>
+ /// <param name="destinationRef">Configuration node name for the
+ /// destination URI</param>
+ /// <returns>Destination</returns>
+ public virtual IDestination GetClearDestination(ISession session,
+ DestinationType type, string destinationRef)
+ {
+ return this.testSupport.GetClearDestination(session, type, destinationRef);
+ }
+
+ /// <summary>
+ /// Gets a clear destination. This will try to delete an existing
+ /// destination and re-create it.
+ /// </summary>
+ /// <param name="session">Session</param>
+ /// <param name="destinationURI">Destination URI</param>
+ /// <returns>Clear destination</returns>
+ public virtual IDestination GetClearDestination(ISession session,
+ string destinationURI)
+ {
+ return this.testSupport.GetClearDestination(session, destinationURI);
+ }
+
+ /// <summary>
+ /// Gets an existing destination. Don't clear its contents.
+ /// </summary>
+ /// <param name="session">Session</param>
+ /// <param name="type">Destination type</param>
+ /// <param name="destinationRef">Configuration node name for the
+ /// destination URI</param>
+ /// <returns>Destination</returns>
+ public virtual IDestination GetDestination(ISession session,
+ DestinationType type, string destinationRef)
+ {
+ return this.testSupport.GetDestination(session, type, destinationRef);
+ }
+
+ /// <summary>
+ /// Gets a destination URI.
+ /// </summary>
+ /// <param name="type">Destination type</param>
+ /// <param name="destinationRef">Configuration node name for the
+ /// destination URI</param>
+ /// <returns>Destination URI</returns>
+ public virtual string GetDestinationURI(DestinationType type, string destinationRef)
+ {
+ return this.testSupport.GetDestinationURI(type, destinationRef);
+ }
+
+ #endregion
+
+ #region Durable consumer
+
+ /// <summary>
+ /// Register a durable consumer
+ /// </summary>
+ /// <param name="connectionID">Connection ID of the consumer.</param>
+ /// <param name="destination">Destination name to register. Supports
+ /// embedded prefix names.</param>
+ /// <param name="consumerID">Name of the durable consumer.</param>
+ /// <param name="selector">Selector parameters for consumer.</param>
+ /// <param name="noLocal"></param>
+ protected void RegisterDurableConsumer(string connectionID,
+ string destination, string consumerID, string selector, bool noLocal)
+ {
+ using(IConnection connection = CreateConnection(connectionID))
+ {
+ connection.Start();
+ using(ISession session = connection.CreateSession(
+ AcknowledgementMode.DupsOkAcknowledge))
+ {
+ ITopic destinationTopic = (ITopic)SessionUtil.GetDestination(session, destination);
+ Assert.IsNotNull(destinationTopic, "Could not get destination topic.");
+
+ using(IMessageConsumer consumer = session.CreateDurableConsumer(destinationTopic, consumerID, selector, noLocal))
+ {
+ Assert.IsNotNull(consumer, "Could not create durable consumer.");
+ }
+ }
+ }
+ }
+
+ /// <summary>
+ /// Unregister a durable consumer for the given connection ID.
+ /// </summary>
+ /// <param name="connectionID">Connection ID of the consumer.</param>
+ /// <param name="consumerID">Name of the durable consumer.</param>
+ protected void UnregisterDurableConsumer(string connectionID, string consumerID)
+ {
+ using(IConnection connection = CreateConnection(connectionID))
+ {
+ connection.Start();
+ using(ISession session = connection.CreateSession(AcknowledgementMode.DupsOkAcknowledge))
+ {
+ session.DeleteDurableConsumer(consumerID);
+ }
+ }
+ }
+
+ #endregion
+
+ #region Send messages
+
+ /// <summary>
+ /// Sends a specified number of text messages to the designated
+ /// destination.
+ /// </summary>
+ /// <param name="destination">Destination.</param>
+ /// <param name="deliveryMode">Delivery mode.</param>
+ /// <param name="count">Number of messages to be sent.</param>
+ public void SendMessages(IDestination destination,
+ MsgDeliveryMode deliveryMode, int count)
+ {
+ IConnection connection = CreateConnection();
+ connection.Start();
+ SendMessages(connection, destination, deliveryMode, count);
+ connection.Close();
+ }
+
+ /// <summary>
+ /// Sends a specified number of text messages to the designated
+ /// destination.
+ /// </summary>
+ /// <param name="connection">Connection.</param>
+ /// <param name="destination">Destination.</param>
+ /// <param name="deliveryMode">Delivery mode.</param>
+ /// <param name="count">Number of messages to be sent.</param>
+ public void SendMessages(IConnection connection,
+ IDestination destination, MsgDeliveryMode deliveryMode, int count)
+ {
+ ISession session = connection.CreateSession(AcknowledgementMode.AutoAcknowledge);
+ SendMessages(session, destination, deliveryMode, count);
+ session.Close();
+ }
+
+ /// <summary>
+ /// Sends a specified number of text messages to the designated
+ /// destination.
+ /// </summary>
+ /// <param name="session">Session.</param>
+ /// <param name="destination">Destination.</param>
+ /// <param name="deliveryMode">Delivery mode.</param>
+ /// <param name="count">Number of messages to be sent.</param>
+ public void SendMessages(ISession session, IDestination destination,
+ MsgDeliveryMode deliveryMode, int count)
+ {
+ IMessageProducer producer = session.CreateProducer(destination);
+ producer.DeliveryMode = deliveryMode;
+ for(int i = 0; i < count; i++)
+ {
+ producer.Send(session.CreateTextMessage("" + i));
+ }
+ producer.Close();
+ }
+
+ #endregion
+
+ #region Check messages
+
+ protected void AssertTextMessagesEqual(IMessage[] firstSet, IMessage[] secondSet)
+ {
+ AssertTextMessagesEqual(firstSet, secondSet, "");
+ }
+
+ protected void AssertTextMessagesEqual(IMessage[] firstSet, IMessage[] secondSet, string messsage)
+ {
+ Assert.AreEqual(firstSet.Length, secondSet.Length, "Message count does not match: " + messsage);
+
+ for(int i = 0; i < secondSet.Length; i++)
+ {
+ ITextMessage m1 = firstSet[i] as ITextMessage;
+ ITextMessage m2 = secondSet[i] as ITextMessage;
+
+ AssertTextMessageEqual(m1, m2, "Message " + (i + 1) + " did not match : ");
+ }
+ }
+
+ protected void AssertEquals(ITextMessage m1, ITextMessage m2)
+ {
+ AssertEquals(m1, m2, "");
+ }
+
+ protected void AssertTextMessageEqual(ITextMessage m1, ITextMessage m2, string message)
+ {
+ Assert.IsFalse(m1 == null ^ m2 == null, message + ": expected {" + m1 + "}, but was {" + m2 + "}");
+
+ if(m1 == null)
+ {
+ return;
+ }
+
+ Assert.AreEqual(m1.Text, m2.Text, message);
+ }
+
+ protected void AssertEquals(IMessage m1, IMessage m2)
+ {
+ AssertEquals(m1, m2, "");
+ }
+
+ protected void AssertEquals(IMessage m1, IMessage m2, string message)
+ {
+ Assert.IsFalse(m1 == null ^ m2 == null, message + ": expected {" + m1 + "}, but was {" + m2 + "}");
+
+ if(m1 == null)
+ {
+ return;
+ }
+
+ Assert.IsTrue(m1.GetType() == m2.GetType(), message + ": expected {" + m1 + "}, but was {" + m2 + "}");
+
+ if(m1 is ITextMessage)
+ {
+ AssertTextMessageEqual((ITextMessage) m1, (ITextMessage) m2, message);
+ }
+ else
+ {
+ Assert.AreEqual(m1, m2, message);
+ }
+ }
+
+ #endregion
+ }
+}
diff --git a/src/test/csharp/NMSTestSupport.cs b/src/test/csharp/NMSTestSupport.cs
new file mode 100644
index 0000000..39da8bb
--- /dev/null
+++ b/src/test/csharp/NMSTestSupport.cs
@@ -0,0 +1,651 @@
+/*
+ * 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.
+ */
+using System;
+using System.Collections;
+using System.IO;
+using System.Reflection;
+using System.Text.RegularExpressions;
+using System.Xml;
+using Apache.NMS.Util;
+using NUnit.Framework;
+
+namespace Apache.NMS.Test
+{
+ /// <summary>
+ /// Useful class for test cases support.
+ /// </summary>
+ public class NMSTestSupport
+ {
+ protected TimeSpan receiveTimeout = TimeSpan.FromMilliseconds(15000);
+ protected int testRun;
+ protected int idCounter;
+
+ protected Type testClassType;
+ public Type TestClassType
+ {
+ get { return this.testClassType; }
+ set { this.testClassType = value; }
+ }
+
+ #region Constructors
+
+ public NMSTestSupport()
+ {
+ }
+
+ #endregion
+
+ #region Set up and tear down
+
+ public virtual void SetUp()
+ {
+ this.testRun++;
+ }
+
+ public virtual void TearDown()
+ {
+ }
+
+ #endregion
+
+ #region Configuration file
+
+ private XmlDocument configurationDocument = null;
+ /// <summary>
+ /// The configuration document.
+ /// </summary>
+ public XmlDocument ConfigurationDocument
+ {
+ get
+ {
+ if(this.configurationDocument == null)
+ {
+ this.configurationDocument = LoadConfigFile();
+ Assert.IsTrue(this.configurationDocument != null,
+ "Error loading configuration.");
+ }
+
+ return this.configurationDocument;
+ }
+ }
+
+ /// <summary>
+ /// Loads the configuration file.
+ /// </summary>
+ /// <returns>XmlDocument of the configuration file</returns>
+ public virtual XmlDocument LoadConfigFile()
+ {
+ return LoadConfigFile(GetConfigFilePath());
+ }
+
+ /// <summary>
+ /// Loads the configuration file.
+ /// </summary>
+ /// <param name="configFilePath">Configuration file path</param>
+ /// <returns>XmlDocument of the configuration file</returns>
+ public virtual XmlDocument LoadConfigFile(string configFilePath)
+ {
+ XmlDocument configDoc = new XmlDocument();
+
+ configDoc.Load(configFilePath);
+
+ return configDoc;
+ }
+
+ /// <summary>
+ /// Gets the path of the configuration filename.
+ /// </summary>
+ /// <returns>Path of the configuration filename</returns>
+ public virtual string GetConfigFilePath()
+ {
+ // The full path may be specified by an environment variable
+ string configFilePath = GetEnvVar(GetConfigEnvVarName(), "");
+ bool configFound = (!string.IsNullOrEmpty(configFilePath)
+ && File.Exists(configFilePath));
+
+ // Else it may be found in well known locations
+ if(!configFound)
+ {
+ string[] paths = GetConfigSearchPaths();
+ string configFileName = GetDefaultConfigFileName();
+
+ foreach(string path in paths)
+ {
+ string fullpath = Path.Combine(path, configFileName);
+ Tracer.Debug("\tScanning folder: " + path);
+
+ if(File.Exists(fullpath))
+ {
+ Tracer.Debug("\tAssembly found!");
+ configFilePath = fullpath;
+ configFound = true;
+ break;
+ }
+ }
+ }
+
+ Tracer.Debug("\tConfig file: " + configFilePath);
+ Assert.IsTrue(configFound, "Connection configuration file does not exist.");
+ return configFilePath;
+ }
+
+ /// <summary>
+ /// Gets the environment variable name for the configuration file path.
+ /// </summary>
+ /// <returns>Environment variable name</returns>
+ public virtual string GetConfigEnvVarName()
+ {
+ return "NMSTESTCONFIGPATH";
+ }
+
+ /// <summary>
+ /// Gets the default name for the configuration filename.
+ /// </summary>
+ /// <returns>Default name of the configuration filename</returns>
+ public virtual string GetDefaultConfigFileName()
+ {
+ return "nmsprovider-test.config";
+ }
+
+ /// <summary>
+ /// Gets an array of paths where the configuration file sould be found.
+ /// </summary>
+ /// <returns>Array of paths</returns>
+ private static string[] GetConfigSearchPaths()
+ {
+ ArrayList pathList = new ArrayList();
+
+ // Check the current folder first.
+ pathList.Add("");
+#if !NETCF
+ AppDomain currentDomain = AppDomain.CurrentDomain;
+
+ // Check the folder the assembly is located in.
+ pathList.Add(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location));
+ if(null != currentDomain.BaseDirectory)
+ {
+ pathList.Add(currentDomain.BaseDirectory);
+ }
+
+ if(null != currentDomain.RelativeSearchPath)
+ {
+ pathList.Add(currentDomain.RelativeSearchPath);
+ }
+#endif
+
+ return (string[]) pathList.ToArray(typeof(string));
+ }
+
+ /// <summary>
+ /// Gets the value of the "value" attribute of the specified node.
+ /// </summary>
+ /// <param name="parentNode">Parent node</param>
+ /// <param name="nodeName">Node name</param>
+ /// <param name="defaultVaue">Default value</param>
+ /// <returns></returns>
+ public string GetNodeValueAttribute(XmlElement parentNode,
+ string nodeName, string defaultVaue)
+ {
+ XmlElement node = (XmlElement)parentNode.SelectSingleNode(nodeName);
+
+ return (node == null ? defaultVaue : node.GetAttribute("value"));
+ }
+
+ #endregion
+
+ #region URI node
+
+ /// <summary>
+ /// Gets the URI node for the default configuration.
+ /// </summary>
+ /// <returns>URI node for the default configuration name</returns>
+ public virtual XmlElement GetURINode()
+ {
+ return GetURINode(GetNameTestURI());
+ }
+
+ /// <summary>
+ /// Gets the URI node for the default configuration.
+ /// </summary>
+ /// <param name="nameTestURI">Name of the default configuration node
+ /// </param>
+ /// <returns>URI node for the default configuration name</returns>
+ public virtual XmlElement GetURINode(string nameTestURI)
+ {
+ return (XmlElement)ConfigurationDocument.SelectSingleNode(
+ String.Format("/configuration/{0}", nameTestURI));
+ }
+
+ /// <summary>
+ /// Gets the name of the default connection configuration to be loaded.
+ /// </summary>
+ /// <returns>Default configuration name</returns>
+ public virtual string GetNameTestURI()
+ {
+ return "testURI";
+ }
+
+ #endregion
+
+ #region Factory
+
+ private NMSConnectionFactory nmsFactory;
+ /// <summary>
+ /// The connection factory interface property.
+ /// </summary>
+ public IConnectionFactory Factory
+ {
+ get
+ {
+ if(this.nmsFactory == null)
+ {
+ this.nmsFactory = CreateNMSFactory();
+
+ Assert.IsNotNull(this.nmsFactory, "Error creating factory.");
+ }
+
+ return this.nmsFactory.ConnectionFactory;
+ }
+ }
+
+ /// <summary>
+ /// Create the NMS Factory that can create NMS Connections.
+ /// </summary>
+ /// <returns>Connection factory</returns>
+ public NMSConnectionFactory CreateNMSFactory()
+ {
+ return CreateNMSFactory(GetNameTestURI());
+ }
+
+ /// <summary>
+ /// Create the NMS Factory that can create NMS Connections. This
+ /// function loads the connection settings from the configuration file.
+ /// </summary>
+ /// <param name="nameTestURI">The named connection configuration.
+ /// </param>
+ /// <returns>Connection factory</returns>
+ public NMSConnectionFactory CreateNMSFactory(string nameTestURI)
+ {
+ XmlElement uriNode = GetURINode(nameTestURI);
+
+ Uri brokerUri = null;
+ object[] factoryParams = null;
+ if(uriNode != null)
+ {
+ // Replace any environment variables embedded inside the string.
+ brokerUri = new Uri(uriNode.GetAttribute("value"));
+ factoryParams = GetFactoryParams(uriNode);
+ clientId = GetNodeValueAttribute(uriNode, "clientId", "NMSTestClientId");
+ userName = GetNodeValueAttribute(uriNode, "userName", null);
+ passWord = GetNodeValueAttribute(uriNode, "passWord", null);
+ }
+
+ if(factoryParams == null)
+ {
+ this.nmsFactory = new Apache.NMS.NMSConnectionFactory(brokerUri);
+ }
+ else
+ {
+ this.nmsFactory = new Apache.NMS.NMSConnectionFactory(brokerUri, factoryParams);
+ }
+
+ return this.nmsFactory;
+ }
+
+ /// <summary>
+ /// Get the parameters for the ConnectionFactory from the configuration
+ /// file.
+ /// </summary>
+ /// <param name="uriNode">Parent node of the factoryParams node.</param>
+ /// <returns>Object array of parameter objects to be passsed to provider
+ /// factory object. Null if no parameters are specified in
+ /// configuration file.</returns>
+ public object[] GetFactoryParams(XmlElement uriNode)
+ {
+ ArrayList factoryParams = new ArrayList();
+ XmlElement factoryParamsNode = (XmlElement)uriNode.SelectSingleNode("factoryParams");
+
+ if(factoryParamsNode != null)
+ {
+ XmlNodeList nodeList = factoryParamsNode.SelectNodes("param");
+
+ if(nodeList != null)
+ {
+ foreach(XmlElement paramNode in nodeList)
+ {
+ string paramType = paramNode.GetAttribute("type");
+ string paramValue = paramNode.GetAttribute("value");
+
+ switch(paramType)
+ {
+ case "string":
+ factoryParams.Add(paramValue);
+ break;
+
+ case "int":
+ factoryParams.Add(int.Parse(paramValue));
+ break;
+
+ // TODO: Add more parameter types
+ }
+ }
+ }
+ }
+
+ if(factoryParams.Count > 0)
+ {
+ return factoryParams.ToArray();
+ }
+
+ return null;
+ }
+
+ #endregion
+
+ #region Environment variables
+
+ /// <summary>
+ /// Get environment variable value.
+ /// </summary>
+ /// <param name="varName"></param>
+ /// <param name="defaultValue"></param>
+ /// <returns></returns>
+ public static string GetEnvVar(string varName, string defaultValue)
+ {
+#if (PocketPC||NETCF||NETCF_2_0)
+ string varValue = null;
+#else
+ string varValue = Environment.GetEnvironmentVariable(varName);
+#endif
+ if(null == varValue)
+ {
+ varValue = defaultValue;
+ }
+
+ return varValue;
+ }
+
+ #endregion
+
+ #region Client id and connection
+
+ protected string clientId;
+ /// <summary>
+ /// Client id.
+ /// </summary>
+ public string ClientId
+ {
+ get { return this.clientId; }
+ }
+
+ /// <summary>
+ /// Gets a new client id.
+ /// </summary>
+ /// <returns>Client id</returns>
+ public virtual string GetTestClientId()
+ {
+ System.Text.StringBuilder id = new System.Text.StringBuilder();
+
+ id.Append("ID:");
+ id.Append(this.GetType().Name);
+ id.Append(":");
+ id.Append(this.testRun);
+ id.Append(":");
+ id.Append(++idCounter);
+
+ return id.ToString();
+ }
+
+ protected string userName;
+ /// <summary>
+ /// User name.
+ /// </summary>
+ public string UserName
+ {
+ get { return this.userName; }
+ }
+
+ protected string passWord;
+ /// <summary>
+ /// User pass word.
+ /// </summary>
+ public string PassWord
+ {
+ get { return this.passWord; }
+ }
+
+ /// <summary>
+ /// Create a new connection to the broker.
+ /// </summary>
+ /// <returns>New connection</returns>
+ public virtual IConnection CreateConnection()
+ {
+ return CreateConnection(null);
+ }
+
+ /// <summary>
+ /// Create a new connection to the broker.
+ /// </summary>
+ /// <param name="newClientId">Client ID of the new connection.</param>
+ /// <returns>New connection</returns>
+ public virtual IConnection CreateConnection(string newClientId)
+ {
+ IConnection newConnection;
+
+ if(this.userName == null)
+ {
+ newConnection = Factory.CreateConnection();
+ }
+ else
+ {
+ newConnection = Factory.CreateConnection(userName, passWord);
+ }
+
+ Assert.IsNotNull(newConnection, "Connection not created");
+
+ if(newClientId != null)
+ {
+ newConnection.ClientId = newClientId;
+ }
+
+ return newConnection;
+ }
+
+ /// <summary>
+ /// Create a new connection to the broker, and start it.
+ /// </summary>
+ /// <returns>Started connection</returns>
+ public virtual IConnection CreateConnectionAndStart()
+ {
+ return CreateConnectionAndStart(null);
+ }
+
+ /// <summary>
+ /// Create a new connection to the broker, and start it.
+ /// </summary>
+ /// <param name="newClientId">Client ID of the new connection.</param>
+ /// <returns>Started connection</returns>
+ public virtual IConnection CreateConnectionAndStart(string newClientId)
+ {
+ IConnection newConnection = CreateConnection(newClientId);
+ newConnection.Start();
+ return newConnection;
+ }
+
+ #endregion
+
+ #region Destination
+
+ /// <summary>
+ /// Gets a clear destination.
+ /// </summary>
+ /// <param name="session">Session</param>
+ /// <param name="type">Destination type</param>
+ /// <param name="destinationRef">Configuration node name for the
+ /// destination URI</param>
+ /// <returns>Destination</returns>
+ public virtual IDestination GetClearDestination(ISession session,
+ DestinationType type, string destinationRef)
+ {
+ string uri = GetDestinationURI(type, destinationRef);
+
+ return GetClearDestination(session, uri);
+ }
+
+ /// <summary>
+ /// Gets a clear destination. This will try to delete an existing
+ /// destination and re-create it.
+ /// </summary>
+ /// <param name="session">Session</param>
+ /// <param name="destinationURI">Destination URI</param>
+ /// <returns>Clear destination</returns>
+ public virtual IDestination GetClearDestination(ISession session,
+ string destinationURI)
+ {
+ IDestination destination;
+
+ try
+ {
+ DeleteDestination(session, destinationURI);
+ destination = CreateDestination(session, destinationURI);
+ }
+ catch(Exception)
+ {
+ // Can't delete it, so lets try and purge it.
+ destination = SessionUtil.GetDestination(session, destinationURI);
+
+ using(IMessageConsumer consumer = session.CreateConsumer(destination))
+ {
+ while(consumer.Receive(TimeSpan.FromMilliseconds(750)) != null)
+ {
+ }
+ }
+ }
+
+ return destination;
+ }
+
+ /// <summary>
+ /// Deletes a destination.
+ /// </summary>
+ /// <param name="session">Session</param>
+ /// <param name="destinationURI">Destination URI</param>
+ protected virtual void DeleteDestination(ISession session,
+ string destinationURI)
+ {
+ // Only delete the destination if it can be recreated
+ // SessionUtil.DeleteDestination(session, destinationURI, DestinationType.Queue)
+ throw new NotSupportedException();
+ }
+
+ /// <summary>
+ /// Creates a destination.
+ /// </summary>
+ /// <param name="session">Session</param>
+ /// <param name="destinationURI">Destination URI</param>
+ protected virtual IDestination CreateDestination(ISession session,
+ string destinationURI)
+ {
+ throw new NotSupportedException();
+ }
+
+ /// <summary>
+ /// Gets an existing destination. Don't clear its contents.
+ /// </summary>
+ /// <param name="session">Session</param>
+ /// <param name="type">Destination type</param>
+ /// <param name="destinationRef">Configuration node name for the
+ /// destination URI</param>
+ /// <returns>Destination</returns>
+ public virtual IDestination GetDestination(ISession session,
+ DestinationType type, string destinationRef)
+ {
+ string uri = GetDestinationURI(type, destinationRef);
+
+ IDestination destination = SessionUtil.GetDestination(session, uri);
+
+ return destination;
+ }
+
+ /// <summary>
+ /// Gets a destination URI.
+ /// </summary>
+ /// <param name="type">Destination type</param>
+ /// <param name="destinationRef">Configuration node name for the
+ /// destination URI</param>
+ /// <returns>Destination URI</returns>
+ public virtual string GetDestinationURI(
+ DestinationType type, string destinationRef)
+ {
+ string uri = null;
+
+ if(!string.IsNullOrEmpty(destinationRef))
+ {
+ XmlElement uriNode = GetURINode();
+
+ if(uriNode != null)
+ {
+ uri = GetNodeValueAttribute(uriNode, destinationRef, null);
+ }
+ }
+
+ if(string.IsNullOrEmpty(uri))
+ {
+ uri = NewDestinationURI(type);
+ }
+
+ return uri;
+ }
+
+ /// <summary>
+ /// Gets a new destination URI.
+ /// </summary>
+ /// <param name="type">Destination type</param>
+ /// <returns>Destination URI</returns>
+ public virtual string NewDestinationURI(DestinationType type)
+ {
+ string name = "TEST." + this.TestClassType.Name
+ + "." + Guid.NewGuid().ToString();
+ string scheme;
+ switch(type)
+ {
+ case DestinationType.Queue:
+ scheme = "queue://";
+ break;
+
+ case DestinationType.Topic:
+ scheme = "topic://";
+ break;
+
+ case DestinationType.TemporaryQueue:
+ scheme = "temp-queue://";
+ break;
+
+ case DestinationType.TemporaryTopic:
+ scheme = "temp-topic://";
+ break;
+
+ default:
+ throw new ArgumentException("type: " + type);
+ }
+
+ return scheme + name;
+ }
+
+ #endregion
+ }
+}
diff --git a/src/test/csharp/NMSTracer.cs b/src/test/csharp/NMSTracer.cs
new file mode 100644
index 0000000..1e254bd
--- /dev/null
+++ b/src/test/csharp/NMSTracer.cs
@@ -0,0 +1,87 @@
+/*
+ * 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.
+ */
+
+#define TRACE // Force tracing to be enabled for this class
+
+namespace Apache.NMS.Test
+{
+ public class NMSTracer : Apache.NMS.ITrace
+ {
+ #region ITrace Members
+ public void Debug(string message)
+ {
+#if !NETCF
+ System.Diagnostics.Trace.WriteLine(string.Format("DEBUG: {0}", message));
+#endif
+ }
+
+ public void Error(string message)
+ {
+#if !NETCF
+ System.Diagnostics.Trace.WriteLine(string.Format("ERROR: {0}", message));
+#endif
+ }
+
+ public void Fatal(string message)
+ {
+#if !NETCF
+ System.Diagnostics.Trace.WriteLine(string.Format("FATAL: {0}", message));
+#endif
+ }
+
+ public void Info(string message)
+ {
+#if !NETCF
+ System.Diagnostics.Trace.WriteLine(string.Format("INFO: {0}", message));
+#endif
+ }
+
+ public void Warn(string message)
+ {
+#if !NETCF
+ System.Diagnostics.Trace.WriteLine(string.Format("WARN: {0}", message));
+#endif
+ }
+
+ public bool IsDebugEnabled
+ {
+ get { return true; }
+ }
+
+ public bool IsErrorEnabled
+ {
+ get { return true; }
+ }
+
+ public bool IsFatalEnabled
+ {
+ get { return true; }
+ }
+
+ public bool IsInfoEnabled
+ {
+ get { return true; }
+ }
+
+ public bool IsWarnEnabled
+ {
+ get { return true; }
+ }
+
+ #endregion
+ }
+}
diff --git a/src/test/csharp/PrimitiveMapTest.cs b/src/test/csharp/PrimitiveMapTest.cs
new file mode 100644
index 0000000..f98322a
--- /dev/null
+++ b/src/test/csharp/PrimitiveMapTest.cs
@@ -0,0 +1,170 @@
+/*
+ * 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.
+ */
+
+using System;
+using System.Collections;
+using Apache.NMS.Util;
+using NUnit.Framework;
+
+namespace Apache.NMS.Test
+{
+ [TestFixture]
+ public class PrimitiveMapTest
+ {
+
+ bool a = true;
+ byte b = 123;
+ char c = 'c';
+ short d = 0x1234;
+ int e = 0x12345678;
+ long f = 0x1234567812345678;
+ string g = "Hello World!";
+ bool h = false;
+ byte i = 0xFF;
+ short j = -0x1234;
+ int k = -0x12345678;
+ long l = -0x1234567812345678;
+ IList m = CreateList();
+ IDictionary n = CreateDictionary();
+
+ [Test]
+ public void TestNotMarshalled()
+ {
+ PrimitiveMap map = CreatePrimitiveMap();
+ AssertPrimitiveMap(map);
+ }
+
+ [Test]
+ public void TestMarshalled()
+ {
+ PrimitiveMap map = CreatePrimitiveMap();
+ byte[] data = map.Marshal();
+ map = PrimitiveMap.Unmarshal(data);
+ AssertPrimitiveMap(map);
+ }
+
+ [Test]
+ public void TestMarshalledWithBigString()
+ {
+ PrimitiveMap map = CreatePrimitiveMap();
+ String test = new String('a', 65538);
+ map.SetString("BIG_STRING", test);
+ byte[] data = map.Marshal();
+ map = PrimitiveMap.Unmarshal(data);
+ AssertPrimitiveMap(map);
+ Assert.AreEqual(test, map.GetString("BIG_STRING"));
+ }
+
+ protected PrimitiveMap CreatePrimitiveMap()
+ {
+ PrimitiveMap map = new PrimitiveMap();
+
+ map["a"] = a;
+ map["b"] = b;
+ map["c"] = c;
+ map["d"] = d;
+ map["e"] = e;
+ map["f"] = f;
+ map["g"] = g;
+ map["h"] = h;
+ map["i"] = i;
+ map["j"] = j;
+ map["k"] = k;
+ map["l"] = l;
+ map["m"] = m;
+ map["n"] = n;
+
+ return map;
+ }
+
+ protected void AssertPrimitiveMap(PrimitiveMap map)
+ {
+ // use generic API to access entries
+ Assert.AreEqual(a, map["a"], "generic map entry: a");
+ Assert.AreEqual(b, map["b"], "generic map entry: b");
+ Assert.AreEqual(c, map["c"], "generic map entry: c");
+ Assert.AreEqual(d, map["d"], "generic map entry: d");
+ Assert.AreEqual(e, map["e"], "generic map entry: e");
+ Assert.AreEqual(f, map["f"], "generic map entry: f");
+ Assert.AreEqual(g, map["g"], "generic map entry: g");
+ Assert.AreEqual(h, map["h"], "generic map entry: h");
+ Assert.AreEqual(i, map["i"], "generic map entry: i");
+ Assert.AreEqual(j, map["j"], "generic map entry: j");
+ Assert.AreEqual(k, map["k"], "generic map entry: k");
+ Assert.AreEqual(l, map["l"], "generic map entry: l");
+ //Assert.AreEqual(m, map["m"], "generic map entry: m");
+ //Assert.AreEqual(n, map["n"], "generic map entry: n");
+
+ // use type safe APIs
+ Assert.AreEqual(a, map.GetBool("a"), "map entry: a");
+ Assert.AreEqual(b, map.GetByte("b"), "map entry: b");
+ Assert.AreEqual(c, map.GetChar("c"), "map entry: c");
+ Assert.AreEqual(d, map.GetShort("d"), "map entry: d");
+ Assert.AreEqual(e, map.GetInt("e"), "map entry: e");
+ Assert.AreEqual(f, map.GetLong("f"), "map entry: f");
+ Assert.AreEqual(g, map.GetString("g"), "map entry: g");
+ Assert.AreEqual(h, map.GetBool("h"), "map entry: h");
+ Assert.AreEqual(i, map.GetByte("i"), "map entry: i");
+ Assert.AreEqual(j, map.GetShort("j"), "map entry: j");
+ Assert.AreEqual(k, map.GetInt("k"), "map entry: k");
+ Assert.AreEqual(l, map.GetLong("l"), "map entry: l");
+ //Assert.AreEqual(m, map.GetList("m"), "map entry: m");
+ //Assert.AreEqual(n, map.GetDictionary("n"), "map entry: n");
+
+ IList list = map.GetList("m");
+ Assert.AreEqual(2, list.Count, "list size");
+ Assert.IsTrue(list.Contains("Item1"));
+ Assert.IsTrue(list.Contains("Item2"));
+
+ IDictionary dictionary = map.GetDictionary("n");
+ Assert.AreEqual(5, dictionary.Count, "dictionary size");
+
+ IDictionary childMap = (IDictionary) dictionary["childMap"];
+ Assert.IsNotNull(childMap);
+ Assert.AreEqual("childMap", childMap["name"], "childMap[name]");
+
+ IList childList = (IList) dictionary["childList"];
+ Assert.IsNotNull(childList);
+ Assert.IsTrue(childList.Contains("childListElement1"));
+ }
+
+ protected static IList CreateList()
+ {
+ ArrayList answer = new ArrayList();
+ answer.Add("Item1");
+ answer.Add("Item2");
+ return answer;
+ }
+
+ protected static IDictionary CreateDictionary()
+ {
+ Hashtable answer = new Hashtable();
+ answer.Add("Name", "James");
+ answer.Add("Location", "London");
+ answer.Add("Company", "LogicBlaze");
+
+ Hashtable childMap = new Hashtable();
+ childMap.Add("name", "childMap");
+ answer.Add("childMap", childMap);
+
+ ArrayList childList = new ArrayList();
+ childList.Add("childListElement1");
+ answer.Add("childList", childList);
+ return answer;
+ }
+ }
+}
diff --git a/src/test/csharp/ProducerTest.cs b/src/test/csharp/ProducerTest.cs
new file mode 100644
index 0000000..4cb30ac
--- /dev/null
+++ b/src/test/csharp/ProducerTest.cs
@@ -0,0 +1,113 @@
+/*
+ * 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.
+ */
+using System;
+using NUnit.Framework;
+
+namespace Apache.NMS.Test
+{
+ //[TestFixture]
+ public class ProducerTest : NMSTest
+ {
+ protected ProducerTest(NMSTestSupport testSupport)
+ : base(testSupport)
+ {
+ }
+
+ //[Test]
+ public virtual void TestProducerSendToNullDestinationWithoutDefault()
+ {
+ using(IConnection connection = CreateConnection(GetTestClientId()))
+ {
+ connection.Start();
+ using(ISession session = connection.CreateSession())
+ {
+ IMessageProducer producer = session.CreateProducer(null);
+
+ try
+ {
+ producer.Send(null, session.CreateTextMessage("Message"));
+ Assert.Fail("Producer should have thrown an NotSupportedException");
+ }
+ catch(NotSupportedException)
+ {
+ }
+ catch(Exception ex)
+ {
+ Assert.Fail("Wrong Exception Type Thrown: " + ex.GetType().Name);
+ }
+ }
+ }
+ }
+
+ //[Test]
+ public virtual void TestProducerSendToNullDestinationWithDefault()
+ {
+ using(IConnection connection = CreateConnection(GetTestClientId()))
+ {
+ connection.Start();
+ using(ISession session = connection.CreateSession())
+ {
+ IDestination unusedDest = session.CreateTemporaryQueue();
+
+ IMessageProducer producer = session.CreateProducer(unusedDest);
+
+ try
+ {
+ producer.Send(null, session.CreateTextMessage("Message"));
+ Assert.Fail("Producer should have thrown an InvalidDestinationException");
+ }
+ catch(InvalidDestinationException)
+ {
+ }
+ catch(Exception ex)
+ {
+ Assert.Fail("Wrong Exception Type Thrown: " + ex.GetType().Name);
+ }
+ }
+ }
+ }
+
+ //[Test]
+ public virtual void TestProducerSendToNonDefaultDestination()
+ {
+ using(IConnection connection = CreateConnection(GetTestClientId()))
+ {
+ connection.Start();
+ using(ISession session = connection.CreateSession())
+ {
+ IDestination unusedDest = session.CreateTemporaryQueue();
+ IDestination usedDest = session.CreateTemporaryQueue();
+
+ IMessageProducer producer = session.CreateProducer(unusedDest);
+
+ try
+ {
+ producer.Send(usedDest, session.CreateTextMessage("Message"));
+ Assert.Fail("Producer should have thrown an NotSupportedException");
+ }
+ catch(NotSupportedException)
+ {
+ }
+ catch(Exception ex)
+ {
+ Assert.Fail("Wrong Exception Type Thrown: " + ex.GetType().Name);
+ }
+ }
+ }
+ }
+ }
+}
diff --git a/src/test/csharp/RedeliveryPolicyTest.cs b/src/test/csharp/RedeliveryPolicyTest.cs
new file mode 100644
index 0000000..d11a6fb
--- /dev/null
+++ b/src/test/csharp/RedeliveryPolicyTest.cs
@@ -0,0 +1,135 @@
+/*
+ * 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.
+ */
+using Apache.NMS.Policies;
+using NUnit.Framework;
+
+namespace Apache.NMS.Test
+{
+ [TestFixture]
+ public class RedeliveryPolicyTest
+ {
+ [Test]
+ public void Executes_redelivery_policy_with_backoff_enabled_correctly()
+ {
+ RedeliveryPolicy policy = new RedeliveryPolicy();
+
+ policy.BackOffMultiplier = 2;
+ policy.InitialRedeliveryDelay = 5;
+ policy.UseExponentialBackOff = true;
+
+ // simulate a retry of 10 times
+ Assert.IsTrue(policy.RedeliveryDelay(0) == 0, "redelivery delay not 5 is " + policy.RedeliveryDelay(0));
+ Assert.IsTrue(policy.RedeliveryDelay(1) == 5, "redelivery delay not 10 is " + policy.RedeliveryDelay(1));
+ Assert.IsTrue(policy.RedeliveryDelay(2) == 10, "redelivery delay not 20 is " + policy.RedeliveryDelay(2));
+ Assert.IsTrue(policy.RedeliveryDelay(3) == 20, "redelivery delay not 40 is " + policy.RedeliveryDelay(3));
+ Assert.IsTrue(policy.RedeliveryDelay(4) == 40, "redelivery delay not 80 is " + policy.RedeliveryDelay(4));
+ Assert.IsTrue(policy.RedeliveryDelay(5) == 80, "redelivery delay not 160 is " + policy.RedeliveryDelay(5));
+ Assert.IsTrue(policy.RedeliveryDelay(6) == 160, "redelivery delay not 320 is " + policy.RedeliveryDelay(6));
+ Assert.IsTrue(policy.RedeliveryDelay(7) == 320, "redelivery delay not 640 is " + policy.RedeliveryDelay(7));
+ Assert.IsTrue(policy.RedeliveryDelay(8) == 640, "redelivery delay not 1280 is " + policy.RedeliveryDelay(8));
+ Assert.IsTrue(policy.RedeliveryDelay(9) == 1280, "redelivery delay not 2560 is " + policy.RedeliveryDelay(9));
+ }
+
+ [Test]
+ public void Executes_redelivery_policy_with_backoff_of_3_enabled_correctly()
+ {
+ RedeliveryPolicy policy = new RedeliveryPolicy();
+
+ policy.BackOffMultiplier = 3;
+ policy.InitialRedeliveryDelay = 3;
+ policy.UseExponentialBackOff = true;
+
+ // simulate a retry of 10 times
+ Assert.IsTrue(policy.RedeliveryDelay(0) == 0, "redelivery delay not 5 is " + policy.RedeliveryDelay(0));
+ Assert.IsTrue(policy.RedeliveryDelay(1) == 3, "redelivery delay not 10 is " + policy.RedeliveryDelay(1));
+ Assert.IsTrue(policy.RedeliveryDelay(2) == 9, "redelivery delay not 20 is " + policy.RedeliveryDelay(2));
+ Assert.IsTrue(policy.RedeliveryDelay(3) == 27, "redelivery delay not 40 is " + policy.RedeliveryDelay(3));
+ Assert.IsTrue(policy.RedeliveryDelay(4) == 81, "redelivery delay not 80 is " + policy.RedeliveryDelay(4));
+ Assert.IsTrue(policy.RedeliveryDelay(5) == 243, "redelivery delay not 160 is " + policy.RedeliveryDelay(5));
+ Assert.IsTrue(policy.RedeliveryDelay(6) == 729, "redelivery delay not 320 is " + policy.RedeliveryDelay(6));
+ Assert.IsTrue(policy.RedeliveryDelay(7) == 2187, "redelivery delay not 640 is " + policy.RedeliveryDelay(7));
+ Assert.IsTrue(policy.RedeliveryDelay(8) == 6561, "redelivery delay not 1280 is " + policy.RedeliveryDelay(8));
+ Assert.IsTrue(policy.RedeliveryDelay(9) == 19683, "redelivery delay not 2560 is " + policy.RedeliveryDelay(9));
+ }
+
+ [Test]
+ public void Executes_redelivery_policy_without_backoff_enabled_correctly()
+ {
+ RedeliveryPolicy policy = new RedeliveryPolicy();
+
+ policy.InitialRedeliveryDelay = 5;
+
+ // simulate a retry of 10 times
+ Assert.IsTrue(policy.RedeliveryDelay(0) == 0, "redelivery delay not 0 is " + policy.RedeliveryDelay(0));
+ Assert.IsTrue(policy.RedeliveryDelay(1) == 5, "redelivery delay not 5 is " + policy.RedeliveryDelay(1));
+ Assert.IsTrue(policy.RedeliveryDelay(2) == 5, "redelivery delay not 5 is " + policy.RedeliveryDelay(2));
+ Assert.IsTrue(policy.RedeliveryDelay(3) == 5, "redelivery delay not 5 is " + policy.RedeliveryDelay(3));
+ Assert.IsTrue(policy.RedeliveryDelay(4) == 5, "redelivery delay not 5 is " + policy.RedeliveryDelay(4));
+ Assert.IsTrue(policy.RedeliveryDelay(5) == 5, "redelivery delay not 5 is " + policy.RedeliveryDelay(5));
+ Assert.IsTrue(policy.RedeliveryDelay(6) == 5, "redelivery delay not 5 is " + policy.RedeliveryDelay(6));
+ Assert.IsTrue(policy.RedeliveryDelay(7) == 5, "redelivery delay not 5 is " + policy.RedeliveryDelay(7));
+ Assert.IsTrue(policy.RedeliveryDelay(8) == 5, "redelivery delay not 5 is " + policy.RedeliveryDelay(8));
+ Assert.IsTrue(policy.RedeliveryDelay(9) == 5, "redelivery delay not 5 is " + policy.RedeliveryDelay(9));
+ }
+
+ [Test]
+ public void Should_get_collision_percent_correctly()
+ {
+ RedeliveryPolicy policy = new RedeliveryPolicy();
+
+ policy.CollisionAvoidancePercent = 45;
+
+ Assert.IsTrue(policy.CollisionAvoidancePercent == 45);
+ }
+
+ [Test]
+ public void Executes_redelivery_policy_with_collision_enabled_correctly()
+ {
+ RedeliveryPolicy policy = new RedeliveryPolicy();
+
+ policy.BackOffMultiplier = 2;
+ policy.InitialRedeliveryDelay = 5;
+ policy.UseExponentialBackOff = true;
+ policy.UseCollisionAvoidance = true;
+ policy.CollisionAvoidancePercent = 10;
+
+ // simulate a retry of 10 times
+ int delay = policy.RedeliveryDelay(0);
+ Assert.IsTrue(delay == 0, "not zero is " + policy.RedeliveryDelay(0));
+ delay = policy.RedeliveryDelay(1);
+ Assert.IsTrue(delay >= 4.5 && delay <= 5.5, "not delay >= 4.5 && delay <= 5.5 is " + policy.RedeliveryDelay(1));
+ delay = policy.RedeliveryDelay(2);
+ Assert.IsTrue(delay >= 9 && delay <= 11, "not delay >= 9 && delay <= 11 is " + policy.RedeliveryDelay(2));
+ delay = policy.RedeliveryDelay(3);
+ Assert.IsTrue(delay >= 18 && delay <= 22, "not delay >= 18 && delay <= 22 is " + policy.RedeliveryDelay(3));
+ delay = policy.RedeliveryDelay(4);
+ Assert.IsTrue(delay >= 36 && delay <= 44, "not delay >= 36 && delay <= 44 is " + policy.RedeliveryDelay(4));
+ delay = policy.RedeliveryDelay(5);
+ Assert.IsTrue(delay >= 72 && delay <= 88, "not delay >= 72 && delay <= 88 is " + policy.RedeliveryDelay(5));
+ delay = policy.RedeliveryDelay(6);
+ Assert.IsTrue(delay >= 144 && delay <= 176, "not delay >= 144 && delay <= 176 is " + policy.RedeliveryDelay(6));
+ delay = policy.RedeliveryDelay(7);
+ Assert.IsTrue(delay >= 288 && delay <= 352, "not delay >= 288 && delay <= 352 is " + policy.RedeliveryDelay(7));
+ delay = policy.RedeliveryDelay(8);
+ Assert.IsTrue(delay >= 576 && delay <= 704, "not delay >= 576 && delay <= 704 is " + policy.RedeliveryDelay(8));
+ delay = policy.RedeliveryDelay(9);
+ Assert.IsTrue(delay >= 1152 && delay <= 1408, "not delay >= 1152 && delay <= 1408 is " + policy.RedeliveryDelay(9));
+ delay = policy.RedeliveryDelay(10);
+ Assert.IsTrue(delay >= 2304 && delay <= 2816, "not delay >= 2304 && delay <= 2816 is " + policy.RedeliveryDelay(10));
+ }
+ }
+}
diff --git a/src/test/csharp/RequestResponseTest.cs b/src/test/csharp/RequestResponseTest.cs
new file mode 100644
index 0000000..1c1ca41
--- /dev/null
+++ b/src/test/csharp/RequestResponseTest.cs
@@ -0,0 +1,74 @@
+/*
+ * 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.
+ */
+using System;
+using Apache.NMS.Util;
+using NUnit.Framework;
+
+namespace Apache.NMS.Test
+{
+ //[TestFixture]
+ public class RequestResponseTest : NMSTest
+ {
+ protected RequestResponseTest(NMSTestSupport testSupport)
+ : base(testSupport)
+ {
+ }
+
+ //[Test]
+ //[Category("RequestResponse")]
+ public virtual void TestRequestResponseMessaging(string testQueueRef)
+ {
+ using(IConnection connection = CreateConnection())
+ {
+ connection.Start();
+ using(ISession session = connection.CreateSession(AcknowledgementMode.AutoAcknowledge))
+ {
+ IDestination destination = GetClearDestination(session, DestinationType.Queue, testQueueRef);
+ ITemporaryQueue replyTo = session.CreateTemporaryQueue();
+
+ using(IMessageConsumer consumer = session.CreateConsumer(destination))
+ using(IMessageProducer producer = session.CreateProducer(destination))
+ {
+ IMessage request = session.CreateMessage();
+
+ request.NMSReplyTo = replyTo;
+
+ producer.Send(request);
+
+ request = consumer.Receive(TimeSpan.FromMilliseconds(3000));
+ Assert.IsNotNull(request);
+ Assert.IsNotNull(request.NMSReplyTo);
+
+ using(IMessageProducer responder = session.CreateProducer(request.NMSReplyTo))
+ {
+ IMessage response = session.CreateTextMessage("RESPONSE");
+ responder.Send(response);
+ }
+ }
+
+ using(IMessageConsumer consumer = session.CreateConsumer(replyTo))
+ {
+ ITextMessage response = consumer.Receive(TimeSpan.FromMilliseconds(3000)) as ITextMessage;
+ Assert.IsNotNull(response);
+ Assert.AreEqual("RESPONSE", response.Text);
+ }
+ }
+ }
+ }
+ }
+}
+
diff --git a/src/test/csharp/StreamMessageTest.cs b/src/test/csharp/StreamMessageTest.cs
new file mode 100644
index 0000000..d2c6d87
--- /dev/null
+++ b/src/test/csharp/StreamMessageTest.cs
@@ -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.
+ */
+using Apache.NMS.Util;
+using NUnit.Framework;
+
+namespace Apache.NMS.Test
+{
+ //[TestFixture]
+ public class StreamMessageTest : NMSTest
+ {
+ protected bool a = true;
+ protected byte b = 123;
+ protected char c = 'c';
+ protected short d = 0x1234;
+ protected int e = 0x12345678;
+ protected long f = 0x1234567812345678;
+ protected string g = "Hello World!";
+ protected bool h = false;
+ protected byte i = 0xFF;
+ protected short j = -0x1234;
+ protected int k = -0x12345678;
+ protected long l = -0x1234567812345678;
+ protected float m = 2.1F;
+ protected double n = 2.3;
+
+ protected StreamMessageTest(NMSTestSupport testSupport)
+ : base(testSupport)
+ {
+ }
+
+ //[Test]
+ public virtual void TestSendReceiveStreamMessage(
+ //[Values(MsgDeliveryMode.Persistent, MsgDeliveryMode.NonPersistent)]
+ MsgDeliveryMode deliveryMode, string testQueueRef)
+ {
+ using(IConnection connection = CreateConnection(GetTestClientId()))
+ {
+ connection.Start();
+ using(ISession session = connection.CreateSession(AcknowledgementMode.AutoAcknowledge))
+ {
+ IDestination destination = GetClearDestination(session, DestinationType.Queue, testQueueRef);
+ using(IMessageConsumer consumer = session.CreateConsumer(destination))
+ using(IMessageProducer producer = session.CreateProducer(destination))
+ {
+ producer.DeliveryMode = deliveryMode;
+ IStreamMessage request;
+
+ try
+ {
+ request = session.CreateStreamMessage();
+ }
+ catch(System.NotSupportedException)
+ {
+ return;
+ }
+
+ request.WriteBoolean(a);
+ request.WriteByte(b);
+ request.WriteChar(c);
+ request.WriteInt16(d);
+ request.WriteInt32(e);
+ request.WriteInt64(f);
+ request.WriteString(g);
+ request.WriteBoolean(h);
+ request.WriteByte(i);
+ request.WriteInt16(j);
+ request.WriteInt32(k);
+ request.WriteInt64(l);
+ request.WriteSingle(m);
+ request.WriteDouble(n);
+ producer.Send(request);
+
+ IStreamMessage message = consumer.Receive(receiveTimeout) as IStreamMessage;
+ Assert.IsNotNull(message, "No message returned!");
+ Assert.AreEqual(deliveryMode, message.NMSDeliveryMode, "NMSDeliveryMode does not match");
+
+ // use generic API to access entries
+ Assert.AreEqual(a, message.ReadBoolean(), "Stream Boolean Value: a");
+ Assert.AreEqual(b, message.ReadByte(), "Stream Byte Value: b");
+ Assert.AreEqual(c, message.ReadChar(), "Stream Char Value: c");
+ Assert.AreEqual(d, message.ReadInt16(), "Stream Int16 Value: d");
+ Assert.AreEqual(e, message.ReadInt32(), "Stream Int32 Value: e");
+ Assert.AreEqual(f, message.ReadInt64(), "Stream Int64 Value: f");
+ Assert.AreEqual(g, message.ReadString(), "Stream String Value: g");
+ Assert.AreEqual(h, message.ReadBoolean(), "Stream Boolean Value: h");
+ Assert.AreEqual(i, message.ReadByte(), "Stream Byte Value: i");
+ Assert.AreEqual(j, message.ReadInt16(), "Stream Int16 Value: j");
+ Assert.AreEqual(k, message.ReadInt32(), "Stream Int32 Value: k");
+ Assert.AreEqual(l, message.ReadInt64(), "Stream Int64 Value: l");
+ Assert.AreEqual(m, message.ReadSingle(), "Stream Single Value: m");
+ Assert.AreEqual(n, message.ReadDouble(), "Stream Double Value: n");
+ }
+ }
+ }
+ }
+ }
+}
diff --git a/src/test/csharp/TempDestinationDeletionTest.cs b/src/test/csharp/TempDestinationDeletionTest.cs
new file mode 100644
index 0000000..6c96d74
--- /dev/null
+++ b/src/test/csharp/TempDestinationDeletionTest.cs
@@ -0,0 +1,80 @@
+/*
+ * 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.
+ */
+using System;
+using Apache.NMS.Util;
+using NUnit.Framework;
+
+namespace Apache.NMS.Test
+{
+ //[TestFixture]
+ public class TempDestinationDeletionTest : NMSTest
+ {
+ protected TempDestinationDeletionTest(NMSTestSupport testSupport)
+ : base(testSupport)
+ {
+ }
+
+ //[Test]
+ public virtual void TestTempDestinationDeletion(
+ //[Values(MsgDeliveryMode.Persistent, MsgDeliveryMode.NonPersistent)]
+ MsgDeliveryMode deliveryMode,
+ //[Values(QUEUE_DESTINATION_NAME, TOPIC_DESTINATION_NAME, TEMP_QUEUE_DESTINATION_NAME, TEMP_TOPIC_DESTINATION_NAME)]
+ string testDestinationURI)
+ {
+ using(IConnection connection1 = CreateConnection(GetTestClientId()))
+ {
+ connection1.Start();
+ using(ISession session = connection1.CreateSession(AcknowledgementMode.AutoAcknowledge))
+ {
+ const int MaxNumDestinations = 100;
+
+ for(int index = 1; index <= MaxNumDestinations; index++)
+ {
+ IDestination destination = GetClearDestination(session, testDestinationURI);
+
+ using(IMessageProducer producer = session.CreateProducer(destination))
+ using(IMessageConsumer consumer = session.CreateConsumer(destination))
+ {
+ producer.DeliveryMode = deliveryMode;
+
+ IMessage request = session.CreateTextMessage("Hello World, Just Passing Through!");
+
+ request.NMSType = "TEMP_MSG";
+ producer.Send(request);
+ IMessage receivedMsg = consumer.Receive(TimeSpan.FromMilliseconds(5000));
+ Assert.IsNotNull(receivedMsg);
+ Assert.AreEqual(receivedMsg.NMSType, "TEMP_MSG");
+
+ // Ensures that Consumer closes out its subscription
+ consumer.Close();
+ }
+
+ try
+ {
+ session.DeleteDestination(destination);
+ }
+ catch(NotSupportedException)
+ {
+ // Might as well not try this again.
+ break;
+ }
+ }
+ }
+ }
+ }
+ }
+}
diff --git a/src/test/csharp/TempDestinationTest.cs b/src/test/csharp/TempDestinationTest.cs
new file mode 100644
index 0000000..f773698
--- /dev/null
+++ b/src/test/csharp/TempDestinationTest.cs
@@ -0,0 +1,175 @@
+/*
+ * 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.
+ */
+using System;
+using System.Collections;
+using NUnit.Framework;
+
+namespace Apache.NMS.Test
+{
+ //[TestFixture]
+ public class TempDestinationTest : NMSTest
+ {
+ private IConnection connection;
+ private IList connections = ArrayList.Synchronized(new ArrayList());
+
+ protected TempDestinationTest(NMSTestSupport testSupport)
+ : base(testSupport)
+ {
+ }
+
+ //[SetUp]
+ public override void SetUp()
+ {
+ base.SetUp();
+
+ this.connection = CreateConnection();
+ this.connections.Add(connection);
+ }
+
+ //[TearDown]
+ public override void TearDown()
+ {
+ foreach(IConnection conn in this.connections)
+ {
+ try
+ {
+ conn.Close();
+ }
+ catch
+ {
+ }
+ }
+
+ connections.Clear();
+
+ base.TearDown();
+ }
+
+ //[Test]
+ public virtual void TestTempDestOnlyConsumedByLocalConn()
+ {
+ connection.Start();
+
+ ISession tempSession = connection.CreateSession(AcknowledgementMode.AutoAcknowledge);
+ ITemporaryQueue queue = tempSession.CreateTemporaryQueue();
+ IMessageProducer producer = tempSession.CreateProducer(queue);
+ producer.DeliveryMode = (MsgDeliveryMode.NonPersistent);
+ ITextMessage message = tempSession.CreateTextMessage("First");
+ producer.Send(message);
+
+ // temp destination should not be consume when using another connection
+ IConnection otherConnection = CreateConnection();
+ connections.Add(otherConnection);
+ ISession otherSession = otherConnection.CreateSession(AcknowledgementMode.AutoAcknowledge);
+ ITemporaryQueue otherQueue = otherSession.CreateTemporaryQueue();
+ IMessageConsumer consumer = otherSession.CreateConsumer(otherQueue);
+ IMessage msg = consumer.Receive(TimeSpan.FromMilliseconds(3000));
+ Assert.IsNull(msg);
+
+ // should be able to consume temp destination from the same connection
+ consumer = tempSession.CreateConsumer(queue);
+ msg = consumer.Receive(TimeSpan.FromMilliseconds(3000));
+ Assert.IsNotNull(msg);
+ }
+
+ //[Test]
+ public virtual void TestTempQueueHoldsMessagesWithConsumers()
+ {
+ ISession session = connection.CreateSession(AcknowledgementMode.AutoAcknowledge);
+ ITemporaryQueue queue = session.CreateTemporaryQueue();
+ IMessageConsumer consumer = session.CreateConsumer(queue);
+ connection.Start();
+
+ IMessageProducer producer = session.CreateProducer(queue);
+ producer.DeliveryMode = (MsgDeliveryMode.NonPersistent);
+ ITextMessage message = session.CreateTextMessage("Hello");
+ producer.Send(message);
+
+ IMessage message2 = consumer.Receive(TimeSpan.FromMilliseconds(1000));
+ Assert.IsNotNull(message2);
+ Assert.IsTrue(message2 is ITextMessage, "Expected message to be a ITextMessage");
+ Assert.IsTrue(((ITextMessage)message2).Text == message.Text, "Expected message to be a '" + message.Text + "'");
+ }
+
+ //[Test]
+ public virtual void TestTempQueueHoldsMessagesWithoutConsumers()
+ {
+ ISession session = connection.CreateSession(AcknowledgementMode.AutoAcknowledge);
+ ITemporaryQueue queue = session.CreateTemporaryQueue();
+ IMessageProducer producer = session.CreateProducer(queue);
+ producer.DeliveryMode = MsgDeliveryMode.NonPersistent;
+ ITextMessage message = session.CreateTextMessage("Hello");
+ producer.Send(message);
+
+ connection.Start();
+ IMessageConsumer consumer = session.CreateConsumer(queue);
+ IMessage message2 = consumer.Receive(TimeSpan.FromMilliseconds(3000));
+ Assert.IsNotNull(message2);
+ Assert.IsTrue(message2 is ITextMessage, "Expected message to be a ITextMessage");
+ Assert.IsTrue(((ITextMessage)message2).Text == message.Text, "Expected message to be a '" + message.Text + "'");
+ }
+
+ //[Test]
+ public virtual void TestTmpQueueWorksUnderLoad()
+ {
+ int count = 500;
+ int dataSize = 1024;
+
+ ArrayList list = new ArrayList(count);
+ ISession session = connection.CreateSession(AcknowledgementMode.AutoAcknowledge);
+ ITemporaryQueue queue = session.CreateTemporaryQueue();
+ IBytesMessage message;
+ IBytesMessage message2;
+ IMessageProducer producer = session.CreateProducer(queue);
+ producer.DeliveryMode = MsgDeliveryMode.NonPersistent;
+
+ byte[] srcdata = new byte[dataSize];
+ srcdata[0] = (byte) 'B';
+ srcdata[1] = (byte) 'A';
+ srcdata[2] = (byte) 'D';
+ srcdata[3] = (byte) 'W';
+ srcdata[4] = (byte) 'O';
+ srcdata[5] = (byte) 'L';
+ srcdata[6] = (byte) 'F';
+ for(int i = 0; i < count; i++)
+ {
+ message = session.CreateBytesMessage();
+ message.WriteBytes(srcdata);
+ message.Properties.SetInt("c", i);
+ producer.Send(message);
+ list.Add(message);
+ }
+
+ connection.Start();
+ byte[] data = new byte[dataSize];
+ byte[] data2 = new byte[dataSize];
+ IMessageConsumer consumer = session.CreateConsumer(queue);
+ for(int i = 0; i < count; i++)
+ {
+ message2 = consumer.Receive(TimeSpan.FromMilliseconds(2000)) as IBytesMessage;
+ Assert.IsNotNull(message2);
+ Assert.AreEqual(i, message2.Properties.GetInt("c"));
+ message = list[i] as IBytesMessage;
+ Assert.IsNotNull(message);
+ message.Reset();
+ message.ReadBytes(data);
+ message2.ReadBytes(data2);
+ Assert.AreEqual(data, data2);
+ }
+ }
+ }
+}
diff --git a/src/test/csharp/TextMessageTest.cs b/src/test/csharp/TextMessageTest.cs
new file mode 100644
index 0000000..8db26aa
--- /dev/null
+++ b/src/test/csharp/TextMessageTest.cs
@@ -0,0 +1,71 @@
+/*
+ * 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.
+ */
+using System;
+using Apache.NMS.Util;
+using NUnit.Framework;
+
+namespace Apache.NMS.Test
+{
+ //[TestFixture]
+ public class TextMessageTest : NMSTest
+ {
+ protected TextMessageTest(NMSTestSupport testSupport)
+ : base(testSupport)
+ {
+ }
+
+ //[Test]
+ public virtual void TestSendReceiveTextMessage(
+ //[Values(MsgDeliveryMode.Persistent, MsgDeliveryMode.NonPersistent)]
+ MsgDeliveryMode deliveryMode, string testQueueRef)
+ {
+ using(IConnection connection = CreateConnection(GetTestClientId()))
+ {
+ connection.Start();
+ using(ISession session = connection.CreateSession(AcknowledgementMode.AutoAcknowledge))
+ {
+ IDestination destination = GetClearDestination(session, DestinationType.Queue, testQueueRef);
+ using(IMessageConsumer consumer = session.CreateConsumer(destination))
+ using(IMessageProducer producer = session.CreateProducer(destination))
+ {
+ producer.DeliveryMode = deliveryMode;
+ IMessage request = session.CreateTextMessage("Hello World!");
+ producer.Send(request);
+
+ IMessage message = consumer.Receive(receiveTimeout);
+ AssertTextMessageEqual(request, message);
+ Assert.AreEqual(deliveryMode, message.NMSDeliveryMode, "NMSDeliveryMode does not match");
+ }
+ }
+ }
+ }
+
+ /// <summary>
+ /// Assert that two messages are ITextMessages and their text bodies are equal.
+ /// </summary>
+ /// <param name="expected"></param>
+ /// <param name="actual"></param>
+ protected void AssertTextMessageEqual(IMessage expected, IMessage actual)
+ {
+ ITextMessage expectedTextMsg = expected as ITextMessage;
+ Assert.IsNotNull(expectedTextMsg, "'expected' message not a text message");
+ ITextMessage actualTextMsg = actual as ITextMessage;
+ Assert.IsNotNull(actualTextMsg, "'actual' message not a text message");
+ Assert.AreEqual(expectedTextMsg.Text, actualTextMsg.Text, "Text message does not match.");
+ }
+ }
+}
diff --git a/src/test/csharp/TransactionTest.cs b/src/test/csharp/TransactionTest.cs
new file mode 100644
index 0000000..7c13827
--- /dev/null
+++ b/src/test/csharp/TransactionTest.cs
@@ -0,0 +1,439 @@
+/*
+ * 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.
+ */
+using System;
+using Apache.NMS.Util;
+using NUnit.Framework;
+
+namespace Apache.NMS.Test
+{
+ //[TestFixture]
+ public class TransactionTest : NMSTest
+ {
+ protected TransactionTest(NMSTestSupport testSupport)
+ : base(testSupport)
+ {
+ }
+
+ //[Test]
+ public virtual void TestSendRollback(
+ //[Values(MsgDeliveryMode.Persistent, MsgDeliveryMode.NonPersistent)]
+ MsgDeliveryMode deliveryMode, string testQueueRef)
+ {
+ using(IConnection connection = CreateConnection(GetTestClientId()))
+ {
+ connection.Start();
+ using(ISession session = connection.CreateSession(AcknowledgementMode.Transactional))
+ {
+ IDestination destination = GetClearDestination(session, DestinationType.Queue, testQueueRef);
+ using(IMessageConsumer consumer = session.CreateConsumer(destination))
+ using(IMessageProducer producer = session.CreateProducer(destination))
+ {
+ producer.DeliveryMode = deliveryMode;
+ ITextMessage firstMsgSend = session.CreateTextMessage("First Message");
+ producer.Send(firstMsgSend);
+ session.Commit();
+
+ ITextMessage rollbackMsg = session.CreateTextMessage("I'm going to get rolled back.");
+ producer.Send(rollbackMsg);
+ session.Rollback();
+
+ ITextMessage secondMsgSend = session.CreateTextMessage("Second Message");
+ producer.Send(secondMsgSend);
+ session.Commit();
+
+ // Receive the messages
+
+ IMessage message = consumer.Receive(receiveTimeout);
+ AssertTextMessageEqual(firstMsgSend, message, "First message does not match.");
+
+ message = consumer.Receive(receiveTimeout);
+ AssertTextMessageEqual(secondMsgSend, message, "Second message does not match.");
+
+ // validates that the rollback was not consumed
+ session.Commit();
+ }
+ }
+ }
+ }
+
+ //[Test]
+ public virtual void TestSendSessionClose(
+ //[Values(MsgDeliveryMode.Persistent, MsgDeliveryMode.NonPersistent)]
+ MsgDeliveryMode deliveryMode, string testQueueRef)
+ {
+ ITextMessage firstMsgSend;
+ ITextMessage secondMsgSend;
+
+ using(IConnection connection1 = CreateConnection(GetTestClientId()))
+ {
+ connection1.Start();
+ using(ISession session1 = connection1.CreateSession(AcknowledgementMode.Transactional))
+ {
+ IDestination destination1 = GetClearDestination(session1, DestinationType.Queue, testQueueRef);
+ using(IMessageConsumer consumer = session1.CreateConsumer(destination1))
+ {
+ // First connection session that sends one message, and the
+ // second message is implicitly rolled back as the session is
+ // disposed before Commit() can be called.
+ using(IConnection connection2 = CreateConnection(GetTestClientId()))
+ {
+ connection2.Start();
+ using(ISession session2 = connection2.CreateSession(AcknowledgementMode.Transactional))
+ {
+ IDestination destination2 = GetClearDestination(session2, DestinationType.Queue, testQueueRef);
+ using(IMessageProducer producer = session2.CreateProducer(destination2))
+ {
+ producer.DeliveryMode = deliveryMode;
+ firstMsgSend = session2.CreateTextMessage("First Message");
+ producer.Send(firstMsgSend);
+ session2.Commit();
+
+ ITextMessage rollbackMsg = session2.CreateTextMessage("I'm going to get rolled back.");
+ producer.Send(rollbackMsg);
+ }
+ }
+ }
+
+ // Second connection session that will send one message.
+ using(IConnection connection2 = CreateConnection(GetTestClientId()))
+ {
+ connection2.Start();
+ using(ISession session2 = connection2.CreateSession(AcknowledgementMode.Transactional))
+ {
+ IDestination destination2 = GetClearDestination(session2, DestinationType.Queue, testQueueRef);
+ using(IMessageProducer producer = session2.CreateProducer(destination2))
+ {
+ producer.DeliveryMode = deliveryMode;
+ secondMsgSend = session2.CreateTextMessage("Second Message");
+ producer.Send(secondMsgSend);
+ session2.Commit();
+ }
+ }
+ }
+
+ // Check the consumer to verify which messages were actually received.
+ IMessage message = consumer.Receive(receiveTimeout);
+ AssertTextMessageEqual(firstMsgSend, message, "First message does not match.");
+
+ message = consumer.Receive(receiveTimeout);
+ AssertTextMessageEqual(secondMsgSend, message, "Second message does not match.");
+
+ // validates that the rollback was not consumed
+ session1.Commit();
+ }
+ }
+ }
+ }
+
+ //[Test]
+ public virtual void TestReceiveRollback(
+ //[Values(MsgDeliveryMode.Persistent, MsgDeliveryMode.NonPersistent)]
+ MsgDeliveryMode deliveryMode, string testQueueRef)
+ {
+ using(IConnection connection = CreateConnection(GetTestClientId()))
+ {
+ connection.Start();
+ using(ISession session = connection.CreateSession(AcknowledgementMode.Transactional))
+ {
+ IDestination destination = GetClearDestination(session, DestinationType.Queue, testQueueRef);
+ using(IMessageConsumer consumer = session.CreateConsumer(destination))
+ using(IMessageProducer producer = session.CreateProducer(destination))
+ {
+ producer.DeliveryMode = deliveryMode;
+ // Send both messages
+ ITextMessage firstMsgSend = session.CreateTextMessage("First Message");
+ producer.Send(firstMsgSend);
+ ITextMessage secondMsgSend = session.CreateTextMessage("Second Message");
+ producer.Send(secondMsgSend);
+ session.Commit();
+
+ // Receive the messages
+
+ IMessage message = consumer.Receive(receiveTimeout);
+ AssertTextMessageEqual(firstMsgSend, message, "First message does not match.");
+ session.Commit();
+
+ message = consumer.Receive(receiveTimeout);
+ AssertTextMessageEqual(secondMsgSend, message, "Second message does not match.");
+
+ // Rollback so we can get that last message again.
+ session.Rollback();
+ IMessage rollbackMsg = consumer.Receive(receiveTimeout);
+ AssertTextMessageEqual(secondMsgSend, rollbackMsg, "Rollback message does not match.");
+ session.Commit();
+ }
+ }
+ }
+ }
+
+
+ //[Test]
+ public virtual void TestReceiveTwoThenRollback(
+ //[Values(MsgDeliveryMode.Persistent, MsgDeliveryMode.NonPersistent)]
+ MsgDeliveryMode deliveryMode, string testQueueRef)
+ {
+ using(IConnection connection = CreateConnection(GetTestClientId()))
+ {
+ connection.Start();
+ using(ISession session = connection.CreateSession(AcknowledgementMode.Transactional))
+ {
+ IDestination destination = GetClearDestination(session, DestinationType.Queue, testQueueRef);
+ using(IMessageConsumer consumer = session.CreateConsumer(destination))
+ using(IMessageProducer producer = session.CreateProducer(destination))
+ {
+ producer.DeliveryMode = deliveryMode;
+ // Send both messages
+ ITextMessage firstMsgSend = session.CreateTextMessage("First Message");
+ producer.Send(firstMsgSend);
+ ITextMessage secondMsgSend = session.CreateTextMessage("Second Message");
+ producer.Send(secondMsgSend);
+ session.Commit();
+
+ // Receive the messages
+
+ IMessage message = consumer.Receive(receiveTimeout);
+ AssertTextMessageEqual(firstMsgSend, message, "First message does not match.");
+ message = consumer.Receive(receiveTimeout);
+ AssertTextMessageEqual(secondMsgSend, message, "Second message does not match.");
+
+ // Rollback so we can get that last two messages again.
+ session.Rollback();
+ IMessage rollbackMsg = consumer.Receive(receiveTimeout);
+ AssertTextMessageEqual(firstMsgSend, rollbackMsg, "First rollback message does not match.");
+ rollbackMsg = consumer.Receive(receiveTimeout);
+ AssertTextMessageEqual(secondMsgSend, rollbackMsg, "Second rollback message does not match.");
+
+ Assert.IsNull(consumer.ReceiveNoWait());
+ session.Commit();
+ }
+ }
+ }
+ }
+
+ //[Test]
+ public virtual void TestSendCommitNonTransaction(
+ //[Values(AcknowledgementMode.AutoAcknowledge, AcknowledgementMode.ClientAcknowledge)]
+ AcknowledgementMode ackMode,
+ //[Values(MsgDeliveryMode.Persistent, MsgDeliveryMode.NonPersistent)]
+ MsgDeliveryMode deliveryMode, string testQueueRef)
+ {
+ using(IConnection connection = CreateConnection(GetTestClientId()))
+ {
+ connection.Start();
+ using(ISession session = connection.CreateSession(ackMode))
+ {
+ IDestination destination = GetClearDestination(session, DestinationType.Queue, testQueueRef);
+ using(IMessageConsumer consumer = session.CreateConsumer(destination))
+ using(IMessageProducer producer = session.CreateProducer(destination))
+ {
+ producer.DeliveryMode = deliveryMode;
+ ITextMessage firstMsgSend = session.CreateTextMessage("SendCommitNonTransaction Message");
+ producer.Send(firstMsgSend);
+ try
+ {
+ session.Commit();
+ Assert.Fail("Should have thrown an InvalidOperationException.");
+ }
+ catch(InvalidOperationException)
+ {
+ }
+ }
+ }
+ }
+ }
+
+ //[Test]
+ public virtual void TestReceiveCommitNonTransaction(
+ //[Values(AcknowledgementMode.AutoAcknowledge, AcknowledgementMode.ClientAcknowledge)]
+ AcknowledgementMode ackMode,
+ //[Values(MsgDeliveryMode.Persistent, MsgDeliveryMode.NonPersistent)]
+ MsgDeliveryMode deliveryMode, string testQueueRef)
+ {
+ using(IConnection connection = CreateConnection(GetTestClientId()))
+ {
+ connection.Start();
+ using(ISession session = connection.CreateSession(ackMode))
+ {
+ IDestination destination = GetClearDestination(session, DestinationType.Queue, testQueueRef);
+ using(IMessageConsumer consumer = session.CreateConsumer(destination))
+ using(IMessageProducer producer = session.CreateProducer(destination))
+ {
+ producer.DeliveryMode = deliveryMode;
+ ITextMessage firstMsgSend = session.CreateTextMessage("ReceiveCommitNonTransaction Message");
+ producer.Send(firstMsgSend);
+
+ // Receive the messages
+
+ IMessage message = consumer.Receive(receiveTimeout);
+ AssertTextMessageEqual(firstMsgSend, message, "First message does not match.");
+ if(AcknowledgementMode.ClientAcknowledge == ackMode)
+ {
+ message.Acknowledge();
+ }
+
+ try
+ {
+ session.Commit();
+ Assert.Fail("Should have thrown an InvalidOperationException.");
+ }
+ catch(InvalidOperationException)
+ {
+ }
+ }
+ }
+ }
+ }
+
+ //[Test]
+ public virtual void TestReceiveRollbackNonTransaction(
+ //[Values(AcknowledgementMode.AutoAcknowledge, AcknowledgementMode.ClientAcknowledge)]
+ AcknowledgementMode ackMode,
+ //[Values(MsgDeliveryMode.Persistent, MsgDeliveryMode.NonPersistent)]
+ MsgDeliveryMode deliveryMode, string testQueueRef)
+ {
+ using(IConnection connection = CreateConnection(GetTestClientId()))
+ {
+ connection.Start();
+ using(ISession session = connection.CreateSession(ackMode))
+ {
+ IDestination destination = GetClearDestination(session, DestinationType.Queue, testQueueRef);
+ using(IMessageConsumer consumer = session.CreateConsumer(destination))
+ using(IMessageProducer producer = session.CreateProducer(destination))
+ {
+ producer.DeliveryMode = deliveryMode;
+ ITextMessage firstMsgSend = session.CreateTextMessage("ReceiveCommitNonTransaction Message");
+ producer.Send(firstMsgSend);
+
+ // Receive the messages
+
+ IMessage message = consumer.Receive(receiveTimeout);
+ AssertTextMessageEqual(firstMsgSend, message, "First message does not match.");
+ if(AcknowledgementMode.ClientAcknowledge == ackMode)
+ {
+ message.Acknowledge();
+ }
+
+ try
+ {
+ session.Rollback();
+ Assert.Fail("Should have thrown an InvalidOperationException.");
+ }
+ catch(InvalidOperationException)
+ {
+ }
+ }
+ }
+ }
+ }
+
+ /// <summary>
+ /// Assert that two messages are ITextMessages and their text bodies are equal.
+ /// </summary>
+ /// <param name="expected"></param>
+ /// <param name="actual"></param>
+ /// <param name="message"></param>
+ protected void AssertTextMessageEqual(IMessage expected, IMessage actual, String message)
+ {
+ ITextMessage expectedTextMsg = expected as ITextMessage;
+ Assert.IsNotNull(expectedTextMsg, "'expected' message not a text message");
+ ITextMessage actualTextMsg = actual as ITextMessage;
+ Assert.IsNotNull(actualTextMsg, "'actual' message not a text message");
+ Assert.AreEqual(expectedTextMsg.Text, actualTextMsg.Text, message);
+ }
+
+ //[Test]
+ public virtual void TestRedispatchOfRolledbackTx(
+ //[Values(MsgDeliveryMode.Persistent, MsgDeliveryMode.NonPersistent)]
+ MsgDeliveryMode deliveryMode, string testQueueRef)
+ {
+ using(IConnection connection = CreateConnection(GetTestClientId()))
+ {
+ connection.Start();
+ ISession session = connection.CreateSession(AcknowledgementMode.Transactional);
+ IDestination destination = GetClearDestination(session, DestinationType.Queue, testQueueRef);
+
+ SendMessages(connection, destination, deliveryMode, 2);
+
+ IMessageConsumer consumer = session.CreateConsumer(destination);
+ Assert.IsNotNull(consumer.Receive(TimeSpan.FromMilliseconds(1500)));
+ Assert.IsNotNull(consumer.Receive(TimeSpan.FromMilliseconds(1500)));
+
+ // install another consumer while message dispatch is unacked/uncommitted
+ ISession redispatchSession = connection.CreateSession(AcknowledgementMode.Transactional);
+ IMessageConsumer redispatchConsumer = redispatchSession.CreateConsumer(destination);
+
+ session.Rollback();
+ session.Close();
+
+ IMessage msg = redispatchConsumer.Receive(TimeSpan.FromMilliseconds(1500));
+ Assert.IsNotNull(msg);
+ Assert.IsTrue(msg.NMSRedelivered);
+ Assert.AreEqual(2, msg.Properties.GetLong("NMSXDeliveryCount"));
+ msg = redispatchConsumer.Receive(TimeSpan.FromMilliseconds(1500));
+ Assert.IsNotNull(msg);
+ Assert.IsTrue(msg.NMSRedelivered);
+ Assert.AreEqual(2, msg.Properties.GetLong("NMSXDeliveryCount"));
+ redispatchSession.Commit();
+
+ Assert.IsNull(redispatchConsumer.Receive(TimeSpan.FromMilliseconds(500)));
+ redispatchSession.Close();
+ }
+ }
+
+ //[Test]
+ public virtual void TestRedispatchOfUncommittedTx(
+ //[Values(MsgDeliveryMode.Persistent, MsgDeliveryMode.NonPersistent)]
+ MsgDeliveryMode deliveryMode, string testQueueRef)
+ {
+ using(IConnection connection = CreateConnection(GetTestClientId()))
+ {
+ connection.Start();
+ ISession session = connection.CreateSession(AcknowledgementMode.Transactional);
+ IDestination destination = GetClearDestination(session, DestinationType.Queue, testQueueRef);
+
+ SendMessages(connection, destination, deliveryMode, 2);
+
+ IMessageConsumer consumer = session.CreateConsumer(destination);
+ Assert.IsNotNull(consumer.Receive(TimeSpan.FromMilliseconds(2000)));
+ Assert.IsNotNull(consumer.Receive(TimeSpan.FromMilliseconds(2000)));
+
+ // install another consumer while message dispatch is unacked/uncommitted
+ ISession redispatchSession = connection.CreateSession(AcknowledgementMode.Transactional);
+ IMessageConsumer redispatchConsumer = redispatchSession.CreateConsumer(destination);
+
+ // no commit so will auto rollback and get re-dispatched to redisptachConsumer
+ session.Close();
+
+ IMessage msg = redispatchConsumer.Receive(TimeSpan.FromMilliseconds(2000));
+ Assert.IsNotNull(msg);
+ Assert.IsTrue(msg.NMSRedelivered);
+ Assert.AreEqual(2, msg.Properties.GetLong("NMSXDeliveryCount"));
+
+ msg = redispatchConsumer.Receive(TimeSpan.FromMilliseconds(2000));
+ Assert.IsNotNull(msg);
+ Assert.IsTrue(msg.NMSRedelivered);
+ Assert.AreEqual(2, msg.Properties.GetLong("NMSXDeliveryCount"));
+ redispatchSession.Commit();
+
+ Assert.IsNull(redispatchConsumer.Receive(TimeSpan.FromMilliseconds(500)));
+ redispatchSession.Close();
+ }
+ }
+ }
+}
+
+
diff --git a/src/test/csharp/XMSAsyncConsumeTest.cs b/src/test/csharp/XMSAsyncConsumeTest.cs
new file mode 100644
index 0000000..7ef2954
--- /dev/null
+++ b/src/test/csharp/XMSAsyncConsumeTest.cs
@@ -0,0 +1,106 @@
+/*
+ * 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.
+ */
+using System.Threading;
+using Apache.NMS.Test;
+using NUnit.Framework;
+
+namespace Apache.NMS.XMS.Test
+{
+ [TestFixture]
+ public class XMSAsyncConsumeTest : AsyncConsumeTest
+ {
+ protected static string DEFAULT_TEST_QUEUE = "defaultTestQueue";
+
+ public XMSAsyncConsumeTest() :
+ base(new XMSTestSupport())
+ {
+ }
+
+ [SetUp]
+ public override void SetUp()
+ {
+ base.SetUp();
+ }
+
+ [TearDown]
+ public override void TearDown()
+ {
+ base.TearDown();
+ }
+
+ [Test]
+ public void TestAsynchronousConsume(
+ [Values(MsgDeliveryMode.Persistent, MsgDeliveryMode.NonPersistent)]
+ MsgDeliveryMode deliveryMode)
+ {
+ base.TestAsynchronousConsume(deliveryMode, DEFAULT_TEST_QUEUE);
+ }
+
+ [Test]
+ public void TestCreateConsumerAfterSend(
+ [Values(MsgDeliveryMode.Persistent, MsgDeliveryMode.NonPersistent)]
+ MsgDeliveryMode deliveryMode)
+ {
+ base.TestCreateConsumerAfterSend(deliveryMode, DEFAULT_TEST_QUEUE);
+ }
+
+ [Test]
+ public void TestCreateConsumerBeforeSendAddListenerAfterSend(
+ [Values(MsgDeliveryMode.Persistent, MsgDeliveryMode.NonPersistent)]
+ MsgDeliveryMode deliveryMode)
+ {
+ base.TestCreateConsumerBeforeSendAddListenerAfterSend(deliveryMode, DEFAULT_TEST_QUEUE);
+ }
+
+ [Test]
+ public void TestAsynchronousTextMessageConsume(
+ [Values(MsgDeliveryMode.Persistent, MsgDeliveryMode.NonPersistent)]
+ MsgDeliveryMode deliveryMode)
+ {
+ base.TestAsynchronousTextMessageConsume(deliveryMode, DEFAULT_TEST_QUEUE);
+ }
+
+ [Test]
+ public void TestTemporaryQueueAsynchronousConsume(
+ [Values(MsgDeliveryMode.Persistent, MsgDeliveryMode.NonPersistent)]
+ MsgDeliveryMode deliveryMode)
+ {
+ using(IConnection connection = CreateConnectionAndStart(GetTestClientId()))
+ using(ISession syncSession = connection.CreateSession(AcknowledgementMode.AutoAcknowledge))
+ using(ISession asyncSession = connection.CreateSession(AcknowledgementMode.AutoAcknowledge))
+ using(IDestination destination = GetClearDestination(syncSession, DestinationType.Queue, DEFAULT_TEST_QUEUE))
+ using(ITemporaryQueue tempReplyDestination = syncSession.CreateTemporaryQueue())
+ using(IMessageConsumer consumer = asyncSession.CreateConsumer(destination))
+ using(IMessageConsumer tempConsumer = asyncSession.CreateConsumer(tempReplyDestination))
+ using(IMessageProducer producer = syncSession.CreateProducer(destination))
+ {
+ producer.DeliveryMode = deliveryMode;
+ tempConsumer.Listener += new MessageListener(OnMessage);
+ consumer.Listener += new MessageListener(OnQueueMessage);
+
+ IMessage request = syncSession.CreateMessage();
+ request.NMSCorrelationID = "TemqQueueAsyncConsume";
+ request.NMSType = "Test";
+ request.NMSReplyTo = tempReplyDestination;
+ producer.Send(request);
+
+ WaitForMessageToArrive();
+ Assert.AreEqual("TempQueueAsyncResponse", receivedMsg.NMSCorrelationID, "Invalid correlation ID.");
+ }
+ }
+ }
+}
diff --git a/src/test/csharp/XMSBadConsumeTest.cs b/src/test/csharp/XMSBadConsumeTest.cs
new file mode 100644
index 0000000..4c6b0b8
--- /dev/null
+++ b/src/test/csharp/XMSBadConsumeTest.cs
@@ -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.
+ */
+using System;
+using NUnit.Framework;
+using Apache.NMS.Test;
+
+namespace Apache.NMS.XMS.Test
+{
+ [TestFixture]
+ public class XMSBadConsumeTest : BadConsumeTest
+ {
+ public XMSBadConsumeTest()
+ : base(new NMSTestSupport())
+ {
+ }
+
+ [SetUp]
+ public override void SetUp()
+ {
+ base.SetUp();
+ }
+
+ [TearDown]
+ public override void TearDown()
+ {
+ base.TearDown();
+ }
+
+ [Test]
+ [ExpectedException(Handler="ExceptionValidationCheck")]
+ public override void TestBadConsumerException()
+ {
+ base.TestBadConsumerException();
+ }
+ }
+}
diff --git a/src/test/csharp/XMSBytesMessageTest.cs b/src/test/csharp/XMSBytesMessageTest.cs
new file mode 100644
index 0000000..25a3382
--- /dev/null
+++ b/src/test/csharp/XMSBytesMessageTest.cs
@@ -0,0 +1,51 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using Apache.NMS.Util;
+using Apache.NMS.Test;
+using NUnit.Framework;
+
+namespace Apache.NMS.XMS.Test
+{
+ [TestFixture]
+ public class XMSBytesMessageTest : BytesMessageTest
+ {
+ protected static string DEFAULT_TEST_QUEUE = "defaultTestQueue";
+
+ public XMSBytesMessageTest()
+ : base(new XMSTestSupport())
+ {
+ }
+
+ [Test]
+ public void SendReceiveBytesMessage(
+ [Values(MsgDeliveryMode.Persistent, MsgDeliveryMode.NonPersistent)]
+ MsgDeliveryMode deliveryMode)
+ {
+ base.SendReceiveBytesMessage(deliveryMode, DEFAULT_TEST_QUEUE);
+ }
+
+ [Test]
+ public void SendReceiveBytesMessageContent(
+ [Values(MsgDeliveryMode.Persistent, MsgDeliveryMode.NonPersistent)]
+ MsgDeliveryMode deliveryMode)
+ {
+ base.SendReceiveBytesMessageContent(deliveryMode, DEFAULT_TEST_QUEUE);
+ }
+ }
+}
diff --git a/src/test/csharp/XMSConnectionTest.cs b/src/test/csharp/XMSConnectionTest.cs
new file mode 100644
index 0000000..10b778b
--- /dev/null
+++ b/src/test/csharp/XMSConnectionTest.cs
@@ -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.
+ */
+using System;
+using Apache.NMS.Test;
+using NUnit.Framework;
+
+namespace Apache.NMS.XMS.Test
+{
+ [TestFixture]
+ public class XMSConnectionTest : ConnectionTest
+ {
+ protected static string DEFAULT_TEST_QUEUE = "defaultTestQueue";
+ protected static string DEFAULT_TEST_TOPIC = "defaultTestTopic";
+
+ public XMSConnectionTest()
+ : base(new XMSTestSupport())
+ {
+ }
+
+ [SetUp]
+ public override void SetUp()
+ {
+ base.SetUp();
+ }
+
+ [TearDown]
+ public override void TearDown()
+ {
+ base.TearDown();
+ }
+
+ /// <summary>
+ /// Verify that it is possible to create multiple connections to the broker.
+ /// There was a bug in the connection factory which set the clientId member which made
+ /// it impossible to create an additional connection.
+ /// </summary>
+ [Test]
+ public override void TestTwoConnections()
+ {
+ base.TestTwoConnections();
+ }
+
+ [Test]
+ public void TestCreateAndDisposeWithConsumer(
+ [Values(true, false)]
+ bool disposeConsumer)
+ {
+ base.TestCreateAndDisposeWithConsumer(disposeConsumer, DEFAULT_TEST_QUEUE);
+ }
+
+ [Test]
+ public void TestCreateAndDisposeWithProducer(
+ [Values(true, false)]
+ bool disposeProducer)
+ {
+ base.TestCreateAndDisposeWithProducer(disposeProducer, DEFAULT_TEST_QUEUE);
+ }
+
+ [Test]
+ public void TestStartAfterSend(
+ [Values(MsgDeliveryMode.Persistent, MsgDeliveryMode.NonPersistent)]
+ MsgDeliveryMode deliveryMode,
+ [Values(DestinationType.Queue, DestinationType.Topic)]
+ DestinationType destinationType)
+ {
+ base.TestStartAfterSend(deliveryMode, destinationType,
+ destinationType == DestinationType.Queue ? DEFAULT_TEST_QUEUE : DEFAULT_TEST_TOPIC);
+ }
+
+ /// <summary>
+ /// Tests if the consumer receives the messages that were sent before the
+ /// connection was started.
+ /// </summary>
+ [Test]
+ public void TestStoppedConsumerHoldsMessagesTillStarted()
+ {
+ base.TestStoppedConsumerHoldsMessagesTillStarted(DEFAULT_TEST_TOPIC);
+ }
+
+ /// <summary>
+ /// Tests if the consumer is able to receive messages eveb when the
+ /// connecction restarts multiple times.
+ /// </summary>
+ [Test]
+ public void TestMultipleConnectionStops()
+ {
+ base.TestMultipleConnectionStops(DEFAULT_TEST_TOPIC);
+ }
+ }
+}
diff --git a/src/test/csharp/XMSConsumerTest.cs b/src/test/csharp/XMSConsumerTest.cs
new file mode 100644
index 0000000..522dfe2
--- /dev/null
+++ b/src/test/csharp/XMSConsumerTest.cs
@@ -0,0 +1,153 @@
+/*
+ * 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.
+ */
+using System;
+using System.Threading;
+using Apache.NMS.Test;
+using NUnit.Framework;
+
+namespace Apache.NMS.XMS.Test
+{
+ [TestFixture]
+ public class XMSConsumerTest : ConsumerTest
+ {
+ protected static string DEFAULT_TEST_QUEUE = "defaultTestQueue";
+ protected static string DEFAULT_TEST_TOPIC = "defaultTestTopic";
+
+ public XMSConsumerTest()
+ : base(new XMSTestSupport())
+ {
+ }
+
+// The .NET CF does not have the ability to interrupt threads, so this test is impossible.
+#if !NETCF
+ [Test]
+ public override void TestNoTimeoutConsumer(
+ [Values(AcknowledgementMode.AutoAcknowledge, AcknowledgementMode.ClientAcknowledge,
+ AcknowledgementMode.DupsOkAcknowledge, AcknowledgementMode.Transactional)]
+ AcknowledgementMode ackMode)
+ {
+ base.TestNoTimeoutConsumer(ackMode);
+ }
+
+ [Test]
+ public override void TestSyncReceiveConsumerClose(
+ [Values(AcknowledgementMode.AutoAcknowledge, AcknowledgementMode.ClientAcknowledge,
+ AcknowledgementMode.DupsOkAcknowledge, AcknowledgementMode.Transactional)]
+ AcknowledgementMode ackMode)
+ {
+ base.TestSyncReceiveConsumerClose(ackMode);
+ }
+
+ [Test]
+ public override void TestDoChangeSentMessage(
+ [Values(AcknowledgementMode.AutoAcknowledge, AcknowledgementMode.ClientAcknowledge,
+ AcknowledgementMode.DupsOkAcknowledge, AcknowledgementMode.Transactional)]
+ AcknowledgementMode ackMode,
+ [Values(true, false)] bool doClear)
+ {
+ base.TestDoChangeSentMessage(ackMode, doClear);
+ }
+
+ [Test]
+ public override void TestConsumerReceiveBeforeMessageDispatched(
+ [Values(AcknowledgementMode.AutoAcknowledge, AcknowledgementMode.ClientAcknowledge,
+ AcknowledgementMode.DupsOkAcknowledge, AcknowledgementMode.Transactional)]
+ AcknowledgementMode ackMode)
+ {
+ base.TestConsumerReceiveBeforeMessageDispatched(ackMode);
+ }
+
+ [Test]
+ public void TestDontStart(
+ [Values(MsgDeliveryMode.NonPersistent)]
+ MsgDeliveryMode deliveryMode,
+ [Values(DestinationType.Queue, DestinationType.Topic)]
+ DestinationType destinationType)
+ {
+ base.TestDontStart(deliveryMode, destinationType,
+ destinationType == DestinationType.Queue ? DEFAULT_TEST_QUEUE : DEFAULT_TEST_TOPIC);
+ }
+
+ [Test]
+ public void TestSendReceiveTransacted(
+ [Values(MsgDeliveryMode.NonPersistent, MsgDeliveryMode.Persistent)]
+ MsgDeliveryMode deliveryMode,
+ [Values(DestinationType.Queue, DestinationType.Topic, DestinationType.TemporaryQueue, DestinationType.TemporaryTopic)]
+ DestinationType destinationType)
+ {
+ string testDestinationRef;
+ switch(destinationType)
+ {
+ case DestinationType.Queue: testDestinationRef = DEFAULT_TEST_QUEUE; break;
+ case DestinationType.Topic: testDestinationRef = DEFAULT_TEST_TOPIC; break;
+ default: testDestinationRef = ""; break;
+ }
+
+ base.TestSendReceiveTransacted(deliveryMode, destinationType, testDestinationRef);
+ }
+
+ [Test]
+ public void TestAckedMessageAreConsumed()
+ {
+ base.TestAckedMessageAreConsumed(DEFAULT_TEST_QUEUE);
+ }
+
+ [Test]
+ public void TestLastMessageAcked()
+ {
+ base.TestLastMessageAcked(DEFAULT_TEST_QUEUE);
+ }
+
+ [Test]
+ public void TestUnAckedMessageAreNotConsumedOnSessionClose()
+ {
+ base.TestUnAckedMessageAreNotConsumedOnSessionClose(DEFAULT_TEST_QUEUE);
+ }
+
+ [Test]
+ public void TestAsyncAckedMessageAreConsumed()
+ {
+ base.TestAsyncAckedMessageAreConsumed(DEFAULT_TEST_QUEUE);
+ }
+
+ [Test]
+ public void TestAsyncUnAckedMessageAreNotConsumedOnSessionClose()
+ {
+ base.TestAsyncUnAckedMessageAreNotConsumedOnSessionClose(DEFAULT_TEST_QUEUE);
+ }
+
+ [Test]
+ public override void TestAddRemoveAsnycMessageListener()
+ {
+ base.TestAddRemoveAsnycMessageListener();
+ }
+
+ [Test]
+ public override void TestReceiveNoWait(
+ [Values(AcknowledgementMode.AutoAcknowledge, AcknowledgementMode.ClientAcknowledge,
+ AcknowledgementMode.DupsOkAcknowledge, AcknowledgementMode.Transactional)]
+ AcknowledgementMode ackMode,
+ [Values(MsgDeliveryMode.NonPersistent, MsgDeliveryMode.Persistent)]
+ MsgDeliveryMode deliveryMode)
+ {
+ base.TestReceiveNoWait(ackMode, deliveryMode);
+ }
+
+#endif
+
+ }
+}
diff --git a/src/test/csharp/XMSDurableTest.cs b/src/test/csharp/XMSDurableTest.cs
new file mode 100644
index 0000000..994ecf8
--- /dev/null
+++ b/src/test/csharp/XMSDurableTest.cs
@@ -0,0 +1,71 @@
+/*
+ * 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.
+ */
+using System;
+using Apache.NMS.Util;
+using Apache.NMS.Test;
+using NUnit.Framework;
+
+namespace Apache.NMS.XMS.Test
+{
+ [TestFixture]
+ public class XMSDurableTest : DurableTest
+ {
+ protected static string DEFAULT_TEST_QUEUE = "defaultTestQueue";
+ protected static string DEFAULT_TEST_TOPIC = "defaultTestTopic";
+ protected static string DURABLE_TEST_TOPIC = "durableConsumerTestTopic";
+
+ public XMSDurableTest()
+ : base(new XMSTestSupport())
+ {
+ }
+
+ [SetUp]
+ public override void SetUp()
+ {
+ base.SetUp();
+ }
+
+ [Test]
+ public void TestSendWhileClosed(
+ [Values(AcknowledgementMode.AutoAcknowledge, AcknowledgementMode.ClientAcknowledge,
+ AcknowledgementMode.DupsOkAcknowledge, AcknowledgementMode.Transactional)]
+ AcknowledgementMode ackMode)
+ {
+ base.TestSendWhileClosed(ackMode, DEFAULT_TEST_TOPIC);
+ }
+
+ [Test]
+ public void TestDurableConsumerSelectorChange(
+ [Values(AcknowledgementMode.AutoAcknowledge, AcknowledgementMode.ClientAcknowledge,
+ AcknowledgementMode.DupsOkAcknowledge, AcknowledgementMode.Transactional)]
+ AcknowledgementMode ackMode)
+ {
+ base.TestDurableConsumerSelectorChange(ackMode, DEFAULT_TEST_TOPIC);
+ }
+
+ [Test]
+ public void TestDurableConsumer(
+ [Values(AcknowledgementMode.AutoAcknowledge, AcknowledgementMode.ClientAcknowledge,
+ AcknowledgementMode.DupsOkAcknowledge, AcknowledgementMode.Transactional)]
+ AcknowledgementMode ackMode)
+ {
+ string testDurableTopicURI = GetDestinationURI(DestinationType.Topic, DURABLE_TEST_TOPIC);
+
+ base.TestDurableConsumer(ackMode, testDurableTopicURI);
+ }
+ }
+}
diff --git a/src/test/csharp/XMSForeignMessageTransformationTest.cs b/src/test/csharp/XMSForeignMessageTransformationTest.cs
new file mode 100644
index 0000000..0b6d144
--- /dev/null
+++ b/src/test/csharp/XMSForeignMessageTransformationTest.cs
@@ -0,0 +1,75 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+using System;
+using Apache.NMS.Util;
+using Apache.NMS.Test;
+using NUnit.Framework;
+
+namespace Apache.NMS.XMS.Test
+{
+ [TestFixture]
+ public class XMSForeignMessageTransformationTest : ForeignMessageTransformationTest
+ {
+ protected static string DEFAULT_TEST_TOPIC = "defaultTestTopic";
+
+ public XMSForeignMessageTransformationTest()
+ : base(new XMSTestSupport())
+ {
+ }
+
+ [Test]
+ public void TestSendReceiveForeignMessage(
+ [Values(MsgDeliveryMode.Persistent, MsgDeliveryMode.NonPersistent)]
+ MsgDeliveryMode deliveryMode)
+ {
+ base.TestSendReceiveForeignMessage(deliveryMode, DEFAULT_TEST_TOPIC);
+ }
+
+ [Test]
+ public void TestSendReceiveForeignTextMessage(
+ [Values(MsgDeliveryMode.Persistent, MsgDeliveryMode.NonPersistent)]
+ MsgDeliveryMode deliveryMode)
+ {
+ base.TestSendReceiveForeignTextMessage(deliveryMode, DEFAULT_TEST_TOPIC);
+ }
+
+ [Test]
+ public void TestSendReceiveForeignBytesMessage(
+ [Values(MsgDeliveryMode.Persistent, MsgDeliveryMode.NonPersistent)]
+ MsgDeliveryMode deliveryMode)
+ {
+ base.TestSendReceiveForeignBytesMessage(deliveryMode, DEFAULT_TEST_TOPIC);
+ }
+
+ [Test]
+ public void TestSendReceiveForeignMapMessage(
+ [Values(MsgDeliveryMode.Persistent, MsgDeliveryMode.NonPersistent)]
+ MsgDeliveryMode deliveryMode)
+ {
+ base.TestSendReceiveForeignMapMessage(deliveryMode, DEFAULT_TEST_TOPIC);
+ }
+
+ [Test]
+ public void TestSendReceiveForeignStreamMessage(
+ [Values(MsgDeliveryMode.Persistent, MsgDeliveryMode.NonPersistent)]
+ MsgDeliveryMode deliveryMode)
+ {
+ base.TestSendReceiveForeignStreamMessage(deliveryMode, DEFAULT_TEST_TOPIC);
+ }
+ }
+}
+
diff --git a/src/test/csharp/XMSMapMessageTest.cs b/src/test/csharp/XMSMapMessageTest.cs
new file mode 100644
index 0000000..c92cd89
--- /dev/null
+++ b/src/test/csharp/XMSMapMessageTest.cs
@@ -0,0 +1,49 @@
+/*
+ * 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.
+ */
+using System;
+using Apache.NMS.Test;
+using NUnit.Framework;
+
+namespace Apache.NMS.XMS.Test
+{
+ [TestFixture]
+ public class XMSMapMessageTest : MapMessageTest
+ {
+ protected static string DEFAULT_TEST_QUEUE = "defaultTestQueue";
+
+ public XMSMapMessageTest()
+ : base(new XMSTestSupport())
+ {
+ }
+
+ [Test]
+ public void TestSendReceiveMapMessage(
+ [Values(MsgDeliveryMode.Persistent, MsgDeliveryMode.NonPersistent)]
+ MsgDeliveryMode deliveryMode)
+ {
+ base.TestSendReceiveMapMessage(deliveryMode, DEFAULT_TEST_QUEUE);
+ }
+
+ [Test]
+ public void TestSendReceiveNestedMapMessage(
+ [Values(MsgDeliveryMode.Persistent, MsgDeliveryMode.NonPersistent)]
+ MsgDeliveryMode deliveryMode)
+ {
+ base.TestSendReceiveNestedMapMessage(deliveryMode, DEFAULT_TEST_QUEUE);
+ }
+ }
+}
diff --git a/src/test/csharp/XMSMessageSelectorTest.cs b/src/test/csharp/XMSMessageSelectorTest.cs
new file mode 100644
index 0000000..179bbf9
--- /dev/null
+++ b/src/test/csharp/XMSMessageSelectorTest.cs
@@ -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.
+ */
+using System;
+using Apache.NMS.Util;
+using Apache.NMS.Test;
+using NUnit.Framework;
+
+namespace Apache.NMS.XMS.Test
+{
+ [TestFixture]
+ [Category("LongRunning")]
+ public class XMSMessageSelectorTest : MessageSelectorTest
+ {
+ protected const string SELECTOR_TEST_QUEUE = "messageSelectorTestQueue";
+ protected const string SELECTOR_TEST_TOPIC = "messageSelectorTestTopic";
+
+ public XMSMessageSelectorTest()
+ : base(new XMSTestSupport())
+ {
+ }
+
+ [Test]
+ public override void TestFilterIgnoredMessages(
+ [Values(SELECTOR_TEST_QUEUE, SELECTOR_TEST_TOPIC)]
+ string testDestinationRef)
+ {
+ string testDestinationURI = GetDestinationURI(
+ testDestinationRef == SELECTOR_TEST_QUEUE ? DestinationType.Queue : DestinationType.Topic,
+ testDestinationRef);
+
+ base.TestFilterIgnoredMessages(testDestinationURI);
+ }
+
+ [Test]
+ public override void TestFilterIgnoredMessagesSlowConsumer(
+ [Values(SELECTOR_TEST_QUEUE, SELECTOR_TEST_TOPIC)]
+ string testDestinationRef)
+ {
+ string testDestinationURI = GetDestinationURI(
+ testDestinationRef == SELECTOR_TEST_QUEUE ? DestinationType.Queue : DestinationType.Topic,
+ testDestinationRef);
+
+ base.TestFilterIgnoredMessagesSlowConsumer(testDestinationURI);
+ }
+ }
+}
diff --git a/src/test/csharp/XMSMessageTest.cs b/src/test/csharp/XMSMessageTest.cs
new file mode 100644
index 0000000..9e2f367
--- /dev/null
+++ b/src/test/csharp/XMSMessageTest.cs
@@ -0,0 +1,42 @@
+/*
+ * 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.
+ */
+using System;
+using Apache.NMS.Test;
+using NUnit.Framework;
+
+namespace Apache.NMS.XMS.Test
+{
+ [TestFixture]
+ public class XMSMessageTest : MessageTest
+ {
+ protected static string DEFAULT_TEST_QUEUE = "defaultTestQueue";
+
+ public XMSMessageTest()
+ : base(new XMSTestSupport())
+ {
+ }
+
+ [Test]
+ public void TestSendReceiveMessageProperties(
+ [Values(MsgDeliveryMode.Persistent, MsgDeliveryMode.NonPersistent)]
+ MsgDeliveryMode deliveryMode)
+ {
+ base.TestSendReceiveMessageProperties(deliveryMode, DEFAULT_TEST_QUEUE);
+ }
+ }
+}
+
diff --git a/src/test/csharp/XMSMessageTransformerTest.cs b/src/test/csharp/XMSMessageTransformerTest.cs
new file mode 100644
index 0000000..58e8b54
--- /dev/null
+++ b/src/test/csharp/XMSMessageTransformerTest.cs
@@ -0,0 +1,48 @@
+/*
+ * 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.
+ */
+using System;
+using Apache.NMS.Test;
+using NUnit.Framework;
+
+namespace Apache.NMS.XMS.Test
+{
+ [TestFixture]
+ public class XMSMessageTransformerTest : MessageTransformerTest
+ {
+ public XMSMessageTransformerTest()
+ : base(new XMSTestSupport())
+ {
+ }
+
+ [Test]
+ public override void TestProducerTransformer(
+ [Values(MsgDeliveryMode.Persistent, MsgDeliveryMode.NonPersistent)]
+ MsgDeliveryMode deliveryMode)
+ {
+ base.TestProducerTransformer(deliveryMode);
+ }
+
+ [Test]
+ public override void TestConsumerTransformer(
+ [Values(MsgDeliveryMode.Persistent, MsgDeliveryMode.NonPersistent)]
+ MsgDeliveryMode deliveryMode)
+ {
+ base.TestConsumerTransformer(deliveryMode);
+ }
+ }
+}
+
diff --git a/src/test/csharp/XMSNMSPropertyTest.cs b/src/test/csharp/XMSNMSPropertyTest.cs
new file mode 100644
index 0000000..eed608a
--- /dev/null
+++ b/src/test/csharp/XMSNMSPropertyTest.cs
@@ -0,0 +1,41 @@
+/*
+ * 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.
+ */
+using System;
+using Apache.NMS.Test;
+using NUnit.Framework;
+
+namespace Apache.NMS.XMS.Test
+{
+ [TestFixture]
+ public class XMSNMSPropertyTest : NMSPropertyTest
+ {
+ protected static string DEFAULT_TEST_QUEUE = "defaultTestQueue";
+
+ public XMSNMSPropertyTest()
+ : base(new XMSTestSupport())
+ {
+ }
+
+ [Test]
+ public void TestSendReceiveNMSProperties(
+ [Values(MsgDeliveryMode.Persistent, MsgDeliveryMode.NonPersistent)]
+ MsgDeliveryMode deliveryMode)
+ {
+ base.TestSendReceiveNMSProperties(deliveryMode, DEFAULT_TEST_QUEUE);
+ }
+ }
+}
diff --git a/src/test/csharp/XMSProducerTest.cs b/src/test/csharp/XMSProducerTest.cs
new file mode 100644
index 0000000..58ce283
--- /dev/null
+++ b/src/test/csharp/XMSProducerTest.cs
@@ -0,0 +1,49 @@
+/*
+ * 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.
+ */
+using System;
+using Apache.NMS.Test;
+using NUnit.Framework;
+
+namespace Apache.NMS.XMS.Test
+{
+ [TestFixture]
+ public class XMSProducerTest : ProducerTest
+ {
+ public XMSProducerTest()
+ : base(new NMSTestSupport())
+ {
+ }
+
+ [Test]
+ public override void TestProducerSendToNullDestinationWithoutDefault()
+ {
+ base.TestProducerSendToNullDestinationWithoutDefault();
+ }
+
+ [Test]
+ public override void TestProducerSendToNullDestinationWithDefault()
+ {
+ base.TestProducerSendToNullDestinationWithDefault();
+ }
+
+ [Test]
+ public override void TestProducerSendToNonDefaultDestination()
+ {
+ base.TestProducerSendToNonDefaultDestination();
+ }
+ }
+}
diff --git a/src/test/csharp/XMSRequestResponseTest.cs b/src/test/csharp/XMSRequestResponseTest.cs
new file mode 100644
index 0000000..0d96e29
--- /dev/null
+++ b/src/test/csharp/XMSRequestResponseTest.cs
@@ -0,0 +1,41 @@
+/*
+ * 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.
+ */
+using System;
+using Apache.NMS.Test;
+using NUnit.Framework;
+
+namespace Apache.NMS.XMS.Test
+{
+ [TestFixture]
+ public class XMSRequestResponseTest : RequestResponseTest
+ {
+ protected static string DEFAULT_TEST_QUEUE = "defaultTestQueue";
+
+ public XMSRequestResponseTest()
+ : base(new XMSTestSupport())
+ {
+ }
+
+ [Test]
+ [Category("RequestResponse")]
+ public void TestRequestResponseMessaging()
+ {
+ base.TestRequestResponseMessaging(DEFAULT_TEST_QUEUE);
+ }
+ }
+}
+
diff --git a/src/test/csharp/XMSStreamMessageTest.cs b/src/test/csharp/XMSStreamMessageTest.cs
new file mode 100644
index 0000000..8331c2e
--- /dev/null
+++ b/src/test/csharp/XMSStreamMessageTest.cs
@@ -0,0 +1,41 @@
+/*
+ * 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.
+ */
+using System;
+using Apache.NMS.Test;
+using NUnit.Framework;
+
+namespace Apache.NMS.XMS.Test
+{
+ [TestFixture]
+ public class XMSStreamMessageTest : StreamMessageTest
+ {
+ protected static string DEFAULT_TEST_QUEUE = "defaultTestQueue";
+
+ public XMSStreamMessageTest()
+ : base(new XMSTestSupport())
+ {
+ }
+
+ [Test]
+ public void TestSendReceiveStreamMessage(
+ [Values(MsgDeliveryMode.Persistent, MsgDeliveryMode.NonPersistent)]
+ MsgDeliveryMode deliveryMode)
+ {
+ base.TestSendReceiveStreamMessage(deliveryMode, DEFAULT_TEST_QUEUE);
+ }
+ }
+}
diff --git a/src/test/csharp/XMSTempDestinationDeletionTest.cs b/src/test/csharp/XMSTempDestinationDeletionTest.cs
new file mode 100644
index 0000000..e9d5f45
--- /dev/null
+++ b/src/test/csharp/XMSTempDestinationDeletionTest.cs
@@ -0,0 +1,55 @@
+/*
+ * 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.
+ */
+using System;
+using Apache.NMS.Util;
+using Apache.NMS.Test;
+using NUnit.Framework;
+
+namespace Apache.NMS.XMS.Test
+{
+ [TestFixture]
+ public class XMSTempDestinationDeletionTest : TempDestinationDeletionTest
+ {
+ protected const string DELETION_TEST_QUEUE = "deletionTestQueue";
+ protected const string DELETION_TEST_TOPIC = "deletionTestTopic";
+ protected const string DELETION_TEST_TEMP_QUEUE = "deletionTestTempQueue";
+ protected const string DELETION_TEST_TEMP_TOPIC = "deletionTestTempTopic";
+
+ public XMSTempDestinationDeletionTest()
+ : base(new XMSTestSupport())
+ {
+ }
+
+ [Test]
+ public override void TestTempDestinationDeletion(
+ [Values(MsgDeliveryMode.Persistent, MsgDeliveryMode.NonPersistent)]
+ MsgDeliveryMode deliveryMode,
+ [Values(DELETION_TEST_QUEUE, DELETION_TEST_TOPIC, DELETION_TEST_TEMP_QUEUE, DELETION_TEST_TEMP_TOPIC)]
+ string testDestinationRef)
+ {
+ DestinationType type;
+ if (testDestinationRef == DELETION_TEST_QUEUE) type = DestinationType.Queue;
+ else if(testDestinationRef == DELETION_TEST_TOPIC) type = DestinationType.Topic;
+ else if(testDestinationRef == DELETION_TEST_TEMP_QUEUE) type = DestinationType.TemporaryQueue;
+ else type = DestinationType.TemporaryTopic;
+
+ string testDestinationURI = GetDestinationURI(type, testDestinationRef);
+
+ base.TestTempDestinationDeletion(deliveryMode, testDestinationURI);
+ }
+ }
+}
diff --git a/src/test/csharp/XMSTempDestinationTest.cs b/src/test/csharp/XMSTempDestinationTest.cs
new file mode 100644
index 0000000..25d09bb
--- /dev/null
+++ b/src/test/csharp/XMSTempDestinationTest.cs
@@ -0,0 +1,67 @@
+/*
+ * 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.
+ */
+using System;
+using Apache.NMS.Test;
+using NUnit.Framework;
+
+namespace Apache.NMS.XMS.Test
+{
+ [TestFixture]
+ public class XMSTempDestinationTest : TempDestinationTest
+ {
+ public XMSTempDestinationTest()
+ : base(new XMSTestSupport())
+ {
+ }
+
+ [SetUp]
+ public override void SetUp()
+ {
+ base.SetUp();
+ }
+
+ [TearDown]
+ public override void TearDown()
+ {
+ base.TearDown();
+ }
+
+ [Test]
+ public override void TestTempDestOnlyConsumedByLocalConn()
+ {
+ base.TestTempDestOnlyConsumedByLocalConn();
+ }
+
+ [Test]
+ public override void TestTempQueueHoldsMessagesWithConsumers()
+ {
+ base.TestTempQueueHoldsMessagesWithConsumers();
+ }
+
+ [Test]
+ public override void TestTempQueueHoldsMessagesWithoutConsumers()
+ {
+ base.TestTempQueueHoldsMessagesWithoutConsumers();
+ }
+
+ [Test]
+ public override void TestTmpQueueWorksUnderLoad()
+ {
+ base.TestTmpQueueWorksUnderLoad();
+ }
+ }
+}
diff --git a/src/test/csharp/XMSTestSupport.cs b/src/test/csharp/XMSTestSupport.cs
new file mode 100644
index 0000000..556012e
--- /dev/null
+++ b/src/test/csharp/XMSTestSupport.cs
@@ -0,0 +1,132 @@
+/*
+ * 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.
+ */
+using System;
+using System.Xml;
+using Apache.NMS.Test;
+using Apache.NMS.Util;
+using NUnit.Framework;
+
+using Apache.NMS.XMS;
+
+namespace Apache.NMS.XMS.Test
+{
+ /// <summary>
+ /// Useful class for test cases support.
+ /// </summary>
+ public class XMSTestSupport : NMSTestSupport
+ {
+ /// <summary>
+ /// Gets the environment variable name for the configuration file path.
+ /// </summary>
+ /// <returns>Environment variable name</returns>
+ public override string GetConfigEnvVarName()
+ {
+ return "XMSTESTCONFIGPATH";
+ }
+
+ /// <summary>
+ /// Gets the default name for the configuration filename.
+ /// </summary>
+ /// <returns>Default name of the configuration filename</returns>
+ public override string GetDefaultConfigFileName()
+ {
+ return "xmsprovider-test.config";
+ }
+
+ /// <summary>
+ /// Gets a new client id.
+ /// </summary>
+ /// <returns>Client id</returns>
+ public override string GetTestClientId()
+ {
+ return base.GetTestClientId();
+ //return null;
+ }
+
+ /// <summary>
+ /// Create a new connection to the broker.
+ /// </summary>
+ /// <param name="newClientId">Client ID of the new connection.</param>
+ /// <returns>New connection</returns>
+ public override IConnection CreateConnection(string newClientId)
+ {
+ IConnection newConnection;
+
+ // IBM.XMS throws an exception if attempting to set the ClientId
+ // on the Connection after it was created.
+ // In a multithreaded environment, it would probably be best to
+ // create as many factories as client ids, rather than change the
+ // client id on the factory before creating a connection. Plus it
+ // wouldn't be a good idea to protect the code section through a
+ // semaphore, since connections creation takes a long time to be
+ // performed.
+ if(newClientId != null)
+ {
+ ((Apache.NMS.XMS.ConnectionFactory)Factory).ClientId = newClientId;
+ }
+
+ if(this.userName == null)
+ {
+ newConnection = Factory.CreateConnection();
+ }
+ else
+ {
+ newConnection = Factory.CreateConnection(userName, passWord);
+ }
+
+ Assert.IsNotNull(newConnection, "Connection not created");
+
+ return newConnection;
+ }
+
+ ISession cleanupSession = null;
+ /// <summary>
+ /// Gets a clear destination. This will try to delete an existing
+ /// destination and re-create it.
+ /// </summary>
+ /// <param name="session">Session</param>
+ /// <param name="destinationURI">Destination URI</param>
+ /// <returns>Clear destination</returns>
+ public override IDestination GetClearDestination(ISession session,
+ string destinationURI)
+ {
+ IDestination destination = SessionUtil.GetDestination(session, destinationURI);
+
+ // Destination exists. Can't use the given session to clean up:
+ // once used synchronously, IBM XMS doesn't allow the session to be
+ // used asynchronously. Therefore, we create a specific synchronous
+ // session to perform cleanups.
+ if(cleanupSession == null)
+ {
+ IConnection cleanupConnection = CreateConnection("Cleanup");
+ cleanupSession = cleanupConnection.CreateSession();
+ }
+
+ IDestination cleanupDestination = SessionUtil.GetDestination(cleanupSession, destinationURI);
+
+ using(IMessageConsumer consumer = cleanupSession.CreateConsumer(destination))
+ {
+ while(consumer.Receive(TimeSpan.FromMilliseconds(750)) != null)
+ {
+ }
+ }
+
+ return destination;
+ }
+
+ }
+}
diff --git a/src/test/csharp/XMSTextMessageTest.cs b/src/test/csharp/XMSTextMessageTest.cs
new file mode 100644
index 0000000..bfbfd77
--- /dev/null
+++ b/src/test/csharp/XMSTextMessageTest.cs
@@ -0,0 +1,41 @@
+/*
+ * 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.
+ */
+using System;
+using Apache.NMS.Test;
+using NUnit.Framework;
+
+namespace Apache.NMS.XMS.Test
+{
+ [TestFixture]
+ public class XMSTextMessageTest : TextMessageTest
+ {
+ protected static string DEFAULT_TEST_QUEUE = "defaultTestQueue";
+
+ public XMSTextMessageTest()
+ : base(new XMSTestSupport())
+ {
+ }
+
+ [Test]
+ public void TestSendReceiveTextMessage(
+ [Values(MsgDeliveryMode.Persistent, MsgDeliveryMode.NonPersistent)]
+ MsgDeliveryMode deliveryMode)
+ {
+ base.TestSendReceiveTextMessage(deliveryMode, DEFAULT_TEST_QUEUE);
+ }
+ }
+}
diff --git a/src/test/csharp/XMSTransactionTest.cs b/src/test/csharp/XMSTransactionTest.cs
new file mode 100644
index 0000000..f369c4f
--- /dev/null
+++ b/src/test/csharp/XMSTransactionTest.cs
@@ -0,0 +1,115 @@
+/*
+ * 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.
+ */
+
+using System;
+using Apache.NMS.Test;
+using NUnit.Framework;
+
+namespace Apache.NMS.XMS.Test
+{
+ [TestFixture]
+ public class XMSTransactionTest : TransactionTest
+ {
+ protected static string TRANSACTION_TEST_QUEUE = "transactionTestQueue";
+
+ public XMSTransactionTest()
+ : base(new XMSTestSupport())
+ {
+ }
+
+ [Test]
+ public void TestSendRollback(
+ [Values(MsgDeliveryMode.Persistent, MsgDeliveryMode.NonPersistent)]
+ MsgDeliveryMode deliveryMode)
+ {
+ base.TestSendRollback(deliveryMode, TRANSACTION_TEST_QUEUE);
+ }
+
+ [Test]
+ public void TestSendSessionClose(
+ [Values(MsgDeliveryMode.Persistent, MsgDeliveryMode.NonPersistent)]
+ MsgDeliveryMode deliveryMode)
+ {
+ base.TestSendSessionClose(deliveryMode, TRANSACTION_TEST_QUEUE);
+ }
+
+ [Test]
+ public void TestReceiveRollback(
+ [Values(MsgDeliveryMode.Persistent, MsgDeliveryMode.NonPersistent)]
+ MsgDeliveryMode deliveryMode)
+ {
+ base.TestReceiveRollback(deliveryMode, TRANSACTION_TEST_QUEUE);
+ }
+
+
+ [Test]
+ public void TestReceiveTwoThenRollback(
+ [Values(MsgDeliveryMode.Persistent, MsgDeliveryMode.NonPersistent)]
+ MsgDeliveryMode deliveryMode)
+ {
+ base.TestReceiveTwoThenRollback(deliveryMode, TRANSACTION_TEST_QUEUE);
+ }
+
+ [Test]
+ public void TestSendCommitNonTransaction(
+ [Values(AcknowledgementMode.AutoAcknowledge, AcknowledgementMode.ClientAcknowledge)]
+ AcknowledgementMode ackMode,
+ [Values(MsgDeliveryMode.Persistent, MsgDeliveryMode.NonPersistent)]
+ MsgDeliveryMode deliveryMode)
+ {
+ base.TestSendCommitNonTransaction(ackMode, deliveryMode, TRANSACTION_TEST_QUEUE);
+ }
+
+ [Test]
+ public void TestReceiveCommitNonTransaction(
+ [Values(AcknowledgementMode.AutoAcknowledge, AcknowledgementMode.ClientAcknowledge)]
+ AcknowledgementMode ackMode,
+ [Values(MsgDeliveryMode.Persistent, MsgDeliveryMode.NonPersistent)]
+ MsgDeliveryMode deliveryMode)
+ {
+ base.TestReceiveCommitNonTransaction(ackMode, deliveryMode, TRANSACTION_TEST_QUEUE);
+ }
+
+ [Test]
+ public void TestReceiveRollbackNonTransaction(
+ [Values(AcknowledgementMode.AutoAcknowledge, AcknowledgementMode.ClientAcknowledge)]
+ AcknowledgementMode ackMode,
+ [Values(MsgDeliveryMode.Persistent, MsgDeliveryMode.NonPersistent)]
+ MsgDeliveryMode deliveryMode)
+ {
+ base.TestReceiveRollbackNonTransaction(ackMode, deliveryMode, TRANSACTION_TEST_QUEUE);
+ }
+
+ [Test]
+ public void TestRedispatchOfRolledbackTx(
+ [Values(MsgDeliveryMode.Persistent, MsgDeliveryMode.NonPersistent)]
+ MsgDeliveryMode deliveryMode)
+ {
+ base.TestRedispatchOfRolledbackTx(deliveryMode, TRANSACTION_TEST_QUEUE);
+ }
+
+ [Test]
+ public void TestRedispatchOfUncommittedTx(
+ [Values(MsgDeliveryMode.Persistent, MsgDeliveryMode.NonPersistent)]
+ MsgDeliveryMode deliveryMode)
+ {
+ base.TestRedispatchOfUncommittedTx(deliveryMode, TRANSACTION_TEST_QUEUE);
+ }
+ }
+}
+
+
diff --git a/src/test/csharp/XMSXmlMessageTest.cs b/src/test/csharp/XMSXmlMessageTest.cs
new file mode 100644
index 0000000..db0c80a
--- /dev/null
+++ b/src/test/csharp/XMSXmlMessageTest.cs
@@ -0,0 +1,52 @@
+/*
+ * 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.
+ */
+using System;
+using Apache.NMS.Test;
+using NUnit.Framework;
+
+namespace Apache.NMS.XMS.Test
+{
+ [TestFixture]
+ public class XMSXmlMessageTest : XmlMessageTest
+ {
+ protected static string DEFAULT_TEST_QUEUE = "defaultTestQueue";
+
+ public XMSXmlMessageTest()
+ : base(new XMSTestSupport())
+ {
+ }
+
+#if NET_3_5 || MONO
+
+ [Test]
+ public void TestSendReceiveXmlMessage_Net35()
+ {
+ base.TestSendReceiveXmlMessage_Net35(DEFAULT_TEST_QUEUE);
+ }
+
+#else
+
+ // Test the obsolete API versions until they are completely removed.
+ [Test]
+ public void SendReceiveXmlMessage()
+ {
+ base.TestSendReceiveXmlMessage(DEFAULT_TEST_QUEUE);
+ }
+
+#endif
+ }
+}
diff --git a/src/test/csharp/XmlMessageTest.cs b/src/test/csharp/XmlMessageTest.cs
new file mode 100644
index 0000000..ebbb202
--- /dev/null
+++ b/src/test/csharp/XmlMessageTest.cs
@@ -0,0 +1,186 @@
+/*
+ * 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.
+ */
+using System;
+using Apache.NMS.Util;
+using NUnit.Framework;
+
+namespace Apache.NMS.Test
+{
+ // For ease of cross-platform exchange of information, you might generate objects from
+ // an XSD file using XSDObjectGen. However, C# has built-in support for serializing.
+ // All of the XML attributes that are commented out are optional, but give you fine-grained
+ // control over the serialized format if you need it.
+
+ // [Serializable]
+ public enum CheckType
+ {
+ // [XmlEnum(Name = "message")]
+ message,
+ // [XmlEnum(Name = "command")]
+ command,
+ // [XmlEnum(Name = "response")]
+ response
+ }
+
+ // [XmlRoot(ElementName = "NMSTestXmlType1", IsNullable = false), Serializable]
+ public class NMSTestXmlType1
+ {
+ // [XmlElement(ElementName = "crcCheck", IsNullable = false, DataType = "int")]
+ public int crcCheck;
+
+ // [XmlElement(Type = typeof(CheckType), ElementName = "checkType", IsNullable = false)]
+ public CheckType checkType;
+
+ public NMSTestXmlType1()
+ {
+ crcCheck = 0;
+ checkType = CheckType.message;
+ }
+ }
+
+ // [XmlRoot(ElementName = "NMSTestXmlType2", IsNullable = false), Serializable]
+ public class NMSTestXmlType2
+ {
+ // [XmlElement(ElementName = "stringCheck", IsNullable = false, DataType = "string")]
+ public string stringCheck;
+
+ public NMSTestXmlType2()
+ {
+ stringCheck = String.Empty;
+ }
+ }
+
+ //[TestFixture]
+ public class XmlMessageTest : NMSTest
+ {
+ public XmlMessageTest(NMSTestSupport testSupport)
+ : base(testSupport)
+ {
+ }
+
+#if NET_3_5 || MONO
+
+ //[Test]
+ public virtual void TestSendReceiveXmlMessage_Net35(string testQueueRef)
+ {
+ using(IConnection connection = CreateConnection(GetTestClientId()))
+ {
+ connection.Start();
+ using(ISession session = connection.CreateSession(AcknowledgementMode.AutoAcknowledge))
+ {
+ IDestination destination = GetClearDestination(session, DestinationType.Queue, testQueueRef);
+ using(IMessageConsumer consumer = session.CreateConsumer(destination))
+ using(IMessageProducer producer = session.CreateProducer(destination))
+ {
+ NMSTestXmlType1 srcIntObject = new NMSTestXmlType1();
+ srcIntObject.crcCheck = 0xbadf00d;
+ srcIntObject.checkType = CheckType.command;
+ producer.Send(srcIntObject);
+
+ NMSTestXmlType2 srcStringObject = new NMSTestXmlType2();
+ srcStringObject.stringCheck = "BadFood";
+ producer.Send(srcStringObject);
+
+ // Demonstrate the ability to generically handle multiple object types
+ // sent to the same consumer. If only one object type is ever sent to
+ // the destination, then a simple inline cast is all that is necessary
+ // when calling the NMSConvert.FromXmlMessage() function.
+
+ for(int index = 0; index < 2; index++)
+ {
+ object receivedObject = consumer.Receive(receiveTimeout).ToObject();
+ Assert.IsNotNull(receivedObject, "Failed to retrieve XML message object.");
+
+ if(receivedObject is NMSTestXmlType1)
+ {
+ NMSTestXmlType1 destObject = (NMSTestXmlType1) receivedObject;
+ Assert.AreEqual(srcIntObject.crcCheck, destObject.crcCheck, "CRC integer mis-match.");
+ Assert.AreEqual(srcIntObject.checkType, destObject.checkType, "Check type mis-match.");
+ }
+ else if(receivedObject is NMSTestXmlType2)
+ {
+ NMSTestXmlType2 destObject = (NMSTestXmlType2) receivedObject;
+ Assert.AreEqual(srcStringObject.stringCheck, destObject.stringCheck, "CRC string mis-match.");
+ }
+ else
+ {
+ Assert.Fail("Invalid object type.");
+ }
+ }
+ }
+ }
+ }
+ }
+
+#else
+
+ // Test the obsolete API versions until they are completely removed.
+ //[Test]
+ public virtual void TestSendReceiveXmlMessage(string testQueueRef)
+ {
+ using(IConnection connection = CreateConnection(GetTestClientId()))
+ {
+ connection.Start();
+ using(ISession session = connection.CreateSession(AcknowledgementMode.AutoAcknowledge))
+ {
+ IDestination destination = GetClearDestination(session, DestinationType.Queue, testQueueRef);
+ using(IMessageConsumer consumer = session.CreateConsumer(destination))
+ using(IMessageProducer producer = session.CreateProducer(destination))
+ {
+ NMSTestXmlType1 srcIntObject = new NMSTestXmlType1();
+ srcIntObject.crcCheck = 0xbadf00d;
+ srcIntObject.checkType = CheckType.command;
+ producer.Send(NMSConvert.ToXmlMessage(session, srcIntObject));
+
+ NMSTestXmlType2 srcStringObject = new NMSTestXmlType2();
+ srcStringObject.stringCheck = "BadFood";
+ producer.Send(NMSConvert.ToXmlMessage(session, srcStringObject));
+
+ // Demonstrate the ability to generically handle multiple object types
+ // sent to the same consumer. If only one object type is ever sent to
+ // the destination, then a simple inline cast is all that is necessary
+ // when calling the NMSConvert.FromXmlMessage() function.
+
+ for(int index = 0; index < 2; index++)
+ {
+ object receivedObject = NMSConvert.FromXmlMessage(consumer.Receive(receiveTimeout));
+ Assert.IsNotNull(receivedObject, "Failed to retrieve XML message object.");
+
+ if(receivedObject is NMSTestXmlType1)
+ {
+ NMSTestXmlType1 destObject = (NMSTestXmlType1) receivedObject;
+ Assert.AreEqual(srcIntObject.crcCheck, destObject.crcCheck, "CRC integer mis-match.");
+ Assert.AreEqual(srcIntObject.checkType, destObject.checkType, "Check type mis-match.");
+ }
+ else if(receivedObject is NMSTestXmlType2)
+ {
+ NMSTestXmlType2 destObject = (NMSTestXmlType2) receivedObject;
+ Assert.AreEqual(srcStringObject.stringCheck, destObject.stringCheck, "CRC string mis-match.");
+ }
+ else
+ {
+ Assert.Fail("Invalid object type.");
+ }
+ }
+ }
+ }
+ }
+ }
+
+#endif
+ }
+}
diff --git a/vs2013-xms-test.csproj b/vs2013-xms-test.csproj
new file mode 100644
index 0000000..ccdcca0
--- /dev/null
+++ b/vs2013-xms-test.csproj
@@ -0,0 +1,196 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="12.0">
+ <PropertyGroup>
+ <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+ <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+ <ProductVersion>9.0.30729</ProductVersion>
+ <SchemaVersion>2.0</SchemaVersion>
+ <ProjectGuid>{EB943C69-2C9B-45E7-B95B-FB916E7057ED}</ProjectGuid>
+ <OutputType>Library</OutputType>
+ <RootNamespace>Apache.NMS.XMS.Test</RootNamespace>
+ <AssemblyName>Apache.NMS.XMS.Test</AssemblyName>
+ <WarningLevel>4</WarningLevel>
+ <StartupObject>
+ </StartupObject>
+ <FileUpgradeFlags>
+ </FileUpgradeFlags>
+ <OldToolsVersion>3.5</OldToolsVersion>
+ <UpgradeBackupLocation>
+ </UpgradeBackupLocation>
+ <IsWebBootstrapper>false</IsWebBootstrapper>
+ <SignAssembly>true</SignAssembly>
+ <AssemblyOriginatorKeyFile>keyfile\NMSKey.snk</AssemblyOriginatorKeyFile>
+ <SccProjectName>Svn</SccProjectName>
+ <SccLocalPath>Svn</SccLocalPath>
+ <SccAuxPath>Svn</SccAuxPath>
+ <SccProvider>SubversionScc</SccProvider>
+ <RunPostBuildEvent>OnOutputUpdated</RunPostBuildEvent>
+ <TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
+ <PublishUrl>publish\</PublishUrl>
+ <Install>true</Install>
+ <InstallFrom>Disk</InstallFrom>
+ <UpdateEnabled>false</UpdateEnabled>
+ <UpdateMode>Foreground</UpdateMode>
+ <UpdateInterval>7</UpdateInterval>
+ <UpdateIntervalUnits>Days</UpdateIntervalUnits>
+ <UpdatePeriodically>false</UpdatePeriodically>
+ <UpdateRequired>false</UpdateRequired>
+ <MapFileExtensions>true</MapFileExtensions>
+ <ApplicationRevision>0</ApplicationRevision>
+ <ApplicationVersion>1.0.0.%2a</ApplicationVersion>
+ <UseApplicationTrust>false</UseApplicationTrust>
+ <BootstrapperEnabled>true</BootstrapperEnabled>
+ <TargetFrameworkProfile />
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+ <DebugSymbols>true</DebugSymbols>
+ <DebugType>full</DebugType>
+ <Optimize>false</Optimize>
+ <OutputPath>build\net-4.0\debug\</OutputPath>
+ <DefineConstants>TRACE;DEBUG;NET,NET_4_0</DefineConstants>
+ <AllowUnsafeBlocks>false</AllowUnsafeBlocks>
+ <NoWarn>3016</NoWarn>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+ <DebugSymbols>true</DebugSymbols>
+ <Optimize>true</Optimize>
+ <OutputPath>build\net-4.0\release\</OutputPath>
+ <DefineConstants>TRACE;NET,NET_4_0</DefineConstants>
+ <AllowUnsafeBlocks>false</AllowUnsafeBlocks>
+ <DebugType>full</DebugType>
+ <NoWarn>3016</NoWarn>
+ </PropertyGroup>
+ <ItemGroup>
+ <Reference Include="Apache.NMS">
+ <SpecificVersion>False</SpecificVersion>
+ <HintPath>lib\Apache.NMS\net-4.0\Apache.NMS.dll</HintPath>
+ </Reference>
+ <Reference Include="Apache.NMS.Test">
+ <SpecificVersion>False</SpecificVersion>
+ <HintPath>lib\Apache.NMS\net-4.0\Apache.NMS.Test.dll</HintPath>
+ </Reference>
+ <Reference Include="nunit.framework">
+ <SpecificVersion>False</SpecificVersion>
+ <HintPath>lib\NUnit\net-4.0\nunit.framework.dll</HintPath>
+ </Reference>
+ <Reference Include="System" />
+ <Reference Include="System.Xml" />
+ </ItemGroup>
+ <ItemGroup>
+ <Compile Include="src\test\csharp\CommonAssemblyInfo.cs" />
+ <Compile Include="src\test\csharp\AsyncConsumeTest.cs" />
+ <Compile Include="src\test\csharp\BadConsumeTest.cs" />
+ <Compile Include="src\test\csharp\BytesMessageTest.cs" />
+ <Compile Include="src\test\csharp\CommonAssemblyInfo.cs" />
+ <Compile Include="src\test\csharp\ConnectionTest.cs" />
+ <Compile Include="src\test\csharp\ConsumerTest.cs" />
+ <Compile Include="src\test\csharp\DurableTest.cs" />
+ <Compile Include="src\test\csharp\EndianBinaryReaderTest.cs" />
+ <Compile Include="src\test\csharp\EndianBinaryWriterTest.cs" />
+ <Compile Include="src\test\csharp\EndianTest.cs" />
+ <Compile Include="src\test\csharp\ForeignMessageTransformationTest.cs" />
+ <Compile Include="src\test\csharp\MapMessageTest.cs" />
+ <Compile Include="src\test\csharp\MessageSelectorTest.cs" />
+ <Compile Include="src\test\csharp\MessageTest.cs" />
+ <Compile Include="src\test\csharp\MessageTransformerTest.cs" />
+ <Compile Include="src\test\csharp\NMSPropertyTest.cs" />
+ <Compile Include="src\test\csharp\NMSTest.cs" />
+ <Compile Include="src\test\csharp\NMSTestSupport.cs" />
+ <Compile Include="src\test\csharp\NMSTracer.cs" />
+ <Compile Include="src\test\csharp\PrimitiveMapTest.cs" />
+ <Compile Include="src\test\csharp\ProducerTest.cs" />
+ <Compile Include="src\test\csharp\RedeliveryPolicyTest.cs" />
+ <Compile Include="src\test\csharp\RequestResponseTest.cs" />
+ <Compile Include="src\test\csharp\StreamMessageTest.cs" />
+ <Compile Include="src\test\csharp\TempDestinationDeletionTest.cs" />
+ <Compile Include="src\test\csharp\TempDestinationTest.cs" />
+ <Compile Include="src\test\csharp\TextMessageTest.cs" />
+ <Compile Include="src\test\csharp\TransactionTest.cs" />
+ <Compile Include="src\test\csharp\XmlMessageTest.cs" />
+ <Compile Include="src\test\csharp\XMSAsyncConsumeTest.cs" />
+ <Compile Include="src\test\csharp\XMSBadConsumeTest.cs" />
+ <Compile Include="src\test\csharp\XMSBytesMessageTest.cs" />
+ <Compile Include="src\test\csharp\XMSConnectionTest.cs" />
+ <Compile Include="src\test\csharp\XMSConsumerTest.cs" />
+ <Compile Include="src\test\csharp\XMSDurableTest.cs" />
+ <Compile Include="src\test\csharp\XMSForeignMessageTransformationTest.cs" />
+ <Compile Include="src\test\csharp\XMSMapMessageTest.cs" />
+ <Compile Include="src\test\csharp\XMSMessageSelectorTest.cs" />
+ <Compile Include="src\test\csharp\XMSMessageTest.cs" />
+ <Compile Include="src\test\csharp\XMSMessageTransformerTest.cs" />
+ <Compile Include="src\test\csharp\XMSNMSPropertyTest.cs" />
+ <Compile Include="src\test\csharp\XMSProducerTest.cs" />
+ <Compile Include="src\test\csharp\XMSRequestResponseTest.cs" />
+ <Compile Include="src\test\csharp\XMSStreamMessageTest.cs" />
+ <Compile Include="src\test\csharp\XMSTempDestinationDeletionTest.cs" />
+ <Compile Include="src\test\csharp\XMSTempDestinationTest.cs" />
+ <Compile Include="src\test\csharp\XMSTestSupport.cs" />
+ <Compile Include="src\test\csharp\XMSTextMessageTest.cs" />
+ <Compile Include="src\test\csharp\XMSTransactionTest.cs" />
+ <Compile Include="src\test\csharp\XMSXmlMessageTest.cs" />
+ <Compile Include="src\test\csharp\Commands\BytesMessage.cs" />
+ <Compile Include="src\test\csharp\Commands\Destination.cs" />
+ <Compile Include="src\test\csharp\Commands\MapMessage.cs" />
+ <Compile Include="src\test\csharp\Commands\Message.cs" />
+ <Compile Include="src\test\csharp\Commands\ObjectMessage.cs" />
+ <Compile Include="src\test\csharp\Commands\Queue.cs" />
+ <Compile Include="src\test\csharp\Commands\StreamMessage.cs" />
+ <Compile Include="src\test\csharp\Commands\TempDestination.cs" />
+ <Compile Include="src\test\csharp\Commands\TempQueue.cs" />
+ <Compile Include="src\test\csharp\Commands\TempTopic.cs" />
+ <Compile Include="src\test\csharp\Commands\TextMessage.cs" />
+ <Compile Include="src\test\csharp\Commands\Topic.cs" />
+ </ItemGroup>
+ <ItemGroup>
+ <BootstrapperPackage Include="Microsoft.Net.Client.3.5">
+ <Visible>False</Visible>
+ <ProductName>.NET Framework 3.5 SP1 Client Profile</ProductName>
+ <Install>false</Install>
+ </BootstrapperPackage>
+ <BootstrapperPackage Include="Microsoft.Net.Framework.2.0">
+ <Visible>False</Visible>
+ <ProductName>.NET Framework 2.0 %28x86%29</ProductName>
+ <Install>true</Install>
+ </BootstrapperPackage>
+ <BootstrapperPackage Include="Microsoft.Net.Framework.3.0">
+ <Visible>False</Visible>
+ <ProductName>.NET Framework 3.0 %28x86%29</ProductName>
+ <Install>false</Install>
+ </BootstrapperPackage>
+ <BootstrapperPackage Include="Microsoft.Net.Framework.3.5">
+ <Visible>False</Visible>
+ <ProductName>.NET Framework 3.5</ProductName>
+ <Install>false</Install>
+ </BootstrapperPackage>
+ <BootstrapperPackage Include="Microsoft.Net.Framework.3.5.SP1">
+ <Visible>False</Visible>
+ <ProductName>.NET Framework 3.5 SP1</ProductName>
+ <Install>false</Install>
+ </BootstrapperPackage>
+ </ItemGroup>
+ <ItemGroup>
+ <None Include="Apache.NMS.XMS.Test.nunit">
+ <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
+ <SubType>Designer</SubType>
+ </None>
+ <None Include="keyfile\XMSKey.snk" />
+ <Content Include="xmsprovider-test.config">
+ <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
+ <SubType>Designer</SubType>
+ </Content>
+ </ItemGroup>
+ <ItemGroup>
+ <Service Include="{82A7F48D-3B50-4B1E-B82E-3ADA8210C358}" />
+ </ItemGroup>
+ <ItemGroup>
+ <ProjectReference Include="vs2013-xms.csproj">
+ <Project>{2af5ebb5-9873-4b35-a8fc-8b6e74242767}</Project>
+ <Name>vs2013-xms</Name>
+ </ProjectReference>
+ </ItemGroup>
+ <Import Project="$(MSBuildBinPath)\Microsoft.CSHARP.Targets" />
+ <PropertyGroup>
+ <PostBuildEvent>cd $(ProjectDir)
+nant -nologo -q install-all -D:compile.skip=true</PostBuildEvent>
+ </PropertyGroup>
+</Project>
\ No newline at end of file
diff --git a/vs2013-xms.csproj b/vs2013-xms.csproj
new file mode 100644
index 0000000..86fbfc9
--- /dev/null
+++ b/vs2013-xms.csproj
@@ -0,0 +1,146 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="12.0">
+ <PropertyGroup>
+ <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+ <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+ <ProductVersion>9.0.30729</ProductVersion>
+ <SchemaVersion>2.0</SchemaVersion>
+ <ProjectGuid>{2AF5EBB5-9873-4B35-A8FC-8B6E74242767}</ProjectGuid>
+ <OutputType>Library</OutputType>
+ <RootNamespace>Apache.NMS.XMS</RootNamespace>
+ <AssemblyName>Apache.NMS.XMS</AssemblyName>
+ <FileUpgradeFlags>
+ </FileUpgradeFlags>
+ <OldToolsVersion>3.5</OldToolsVersion>
+ <UpgradeBackupLocation>
+ </UpgradeBackupLocation>
+ <IsWebBootstrapper>false</IsWebBootstrapper>
+ <SignAssembly>true</SignAssembly>
+ <AssemblyOriginatorKeyFile>keyfile\NMSKey.snk</AssemblyOriginatorKeyFile>
+ <SccProjectName>Svn</SccProjectName>
+ <SccLocalPath>Svn</SccLocalPath>
+ <SccAuxPath>Svn</SccAuxPath>
+ <SccProvider>SubversionScc</SccProvider>
+ <RunPostBuildEvent>OnOutputUpdated</RunPostBuildEvent>
+ <TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
+ <PublishUrl>publish\</PublishUrl>
+ <Install>true</Install>
+ <InstallFrom>Disk</InstallFrom>
+ <UpdateEnabled>false</UpdateEnabled>
+ <UpdateMode>Foreground</UpdateMode>
+ <UpdateInterval>7</UpdateInterval>
+ <UpdateIntervalUnits>Days</UpdateIntervalUnits>
+ <UpdatePeriodically>false</UpdatePeriodically>
+ <UpdateRequired>false</UpdateRequired>
+ <MapFileExtensions>true</MapFileExtensions>
+ <ApplicationRevision>0</ApplicationRevision>
+ <ApplicationVersion>1.0.0.%2a</ApplicationVersion>
+ <UseApplicationTrust>false</UseApplicationTrust>
+ <BootstrapperEnabled>true</BootstrapperEnabled>
+ <TargetFrameworkProfile />
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+ <DebugSymbols>true</DebugSymbols>
+ <DebugType>full</DebugType>
+ <Optimize>false</Optimize>
+ <OutputPath>build\net-4.0\debug\</OutputPath>
+ <DefineConstants>TRACE;DEBUG;NET,NET_4_0</DefineConstants>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+ <DebugType>full</DebugType>
+ <Optimize>true</Optimize>
+ <OutputPath>build\net-4.0\release\</OutputPath>
+ <DefineConstants>TRACE;NET,NET_4_0</DefineConstants>
+ <ErrorReport>none</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ <DebugSymbols>true</DebugSymbols>
+ </PropertyGroup>
+ <ItemGroup>
+ <Reference Include="Apache.NMS">
+ <SpecificVersion>False</SpecificVersion>
+ <HintPath>lib\Apache.NMS\net-4.0\Apache.NMS.dll</HintPath>
+ </Reference>
+ <Reference Include="System" />
+ <Reference Include="System.Data" />
+ <Reference Include="System.Xml" />
+ <Reference Include="IBM.XMS">
+ <SpecificVersion>False</SpecificVersion>
+ <HintPath>lib\IBM.XMS\net-4.0\IBM.XMS.dll</HintPath>
+ </Reference>
+ </ItemGroup>
+ <ItemGroup>
+ <Compile Include="src\main\csharp\BytesMessage.cs" />
+ <Compile Include="src\main\csharp\CommonAssemblyInfo.cs" />
+ <Compile Include="src\main\csharp\Connection.cs" />
+ <Compile Include="src\main\csharp\ConnectionFactory.cs" />
+ <Compile Include="src\main\csharp\ConnectionMetaData.cs" />
+ <Compile Include="src\main\csharp\Destination.cs" />
+ <Compile Include="src\main\csharp\InitialContext.cs" />
+ <Compile Include="src\main\csharp\MapMessage.cs" />
+ <Compile Include="src\main\csharp\Message.cs" />
+ <Compile Include="src\main\csharp\MessageConsumer.cs" />
+ <Compile Include="src\main\csharp\MessageProducer.cs" />
+ <Compile Include="src\main\csharp\MessageProperties.cs" />
+ <Compile Include="src\main\csharp\ObjectMessage.cs" />
+ <Compile Include="src\main\csharp\Queue.cs" />
+ <Compile Include="src\main\csharp\QueueBrowser.cs" />
+ <Compile Include="src\main\csharp\Session.cs" />
+ <Compile Include="src\main\csharp\StreamMessage.cs" />
+ <Compile Include="src\main\csharp\TemporaryQueue.cs" />
+ <Compile Include="src\main\csharp\TemporaryTopic.cs" />
+ <Compile Include="src\main\csharp\TextMessage.cs" />
+ <Compile Include="src\main\csharp\Topic.cs" />
+ <Compile Include="src\main\csharp\Util\Dispatcher.cs" />
+ <Compile Include="src\main\csharp\Util\ExceptionUtil.cs" />
+ <Compile Include="src\main\csharp\Util\IntrospectionSupport.cs" />
+ <Compile Include="src\main\csharp\Util\UriAttributeAttribute.cs" />
+ <Compile Include="src\main\csharp\Util\XMSConvert.cs" />
+ <Compile Include="src\main\csharp\Util\XMSEnum.cs" />
+ </ItemGroup>
+ <ItemGroup>
+ <None Include="keyfile\XMSKey.snk" />
+ </ItemGroup>
+ <ItemGroup>
+ <BootstrapperPackage Include="Microsoft.Net.Client.3.5">
+ <Visible>False</Visible>
+ <ProductName>.NET Framework 3.5 SP1 Client Profile</ProductName>
+ <Install>false</Install>
+ </BootstrapperPackage>
+ <BootstrapperPackage Include="Microsoft.Net.Framework.2.0">
+ <Visible>False</Visible>
+ <ProductName>.NET Framework 2.0 %28x86%29</ProductName>
+ <Install>true</Install>
+ </BootstrapperPackage>
+ <BootstrapperPackage Include="Microsoft.Net.Framework.3.0">
+ <Visible>False</Visible>
+ <ProductName>.NET Framework 3.0 %28x86%29</ProductName>
+ <Install>false</Install>
+ </BootstrapperPackage>
+ <BootstrapperPackage Include="Microsoft.Net.Framework.3.5">
+ <Visible>False</Visible>
+ <ProductName>.NET Framework 3.5</ProductName>
+ <Install>false</Install>
+ </BootstrapperPackage>
+ <BootstrapperPackage Include="Microsoft.Net.Framework.3.5.SP1">
+ <Visible>False</Visible>
+ <ProductName>.NET Framework 3.5 SP1</ProductName>
+ <Install>false</Install>
+ </BootstrapperPackage>
+ </ItemGroup>
+ <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
+ <!-- To modify your build process, add your task inside one of the targets below and uncomment it.
+ Other similar extension points exist, see Microsoft.Common.targets.
+ <Target Name="BeforeBuild">
+ </Target>
+ <Target Name="AfterBuild">
+ </Target>
+ -->
+ <PropertyGroup>
+ <PreBuildEvent>cd $(ProjectDir)
+nant -nologo download-vendor -D:vendor.build.config=$(ConfigurationName) -D:vendor.build.framework=net-4.0</PreBuildEvent>
+ <PostBuildEvent>cd $(ProjectDir)
+nant -nologo -q install-all -D:compile.skip=true</PostBuildEvent>
+ </PropertyGroup>
+</Project>
\ No newline at end of file
diff --git a/vs2013-xms.sln b/vs2013-xms.sln
new file mode 100644
index 0000000..64bfb8e
--- /dev/null
+++ b/vs2013-xms.sln
@@ -0,0 +1,32 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio 2013
+VisualStudioVersion = 12.0.40629.0
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "vs2013-xms", "vs2013-xms.csproj", "{2AF5EBB5-9873-4B35-A8FC-8B6E74242767}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "vs2013-xms-test", "vs2013-xms-test.csproj", "{EB943C69-2C9B-45E7-B95B-FB916E7057ED}"
+EndProject
+Global
+ GlobalSection(SubversionScc) = preSolution
+ Svn-Managed = True
+ Manager = AnkhSVN - Subversion Support for Visual Studio
+ EndGlobalSection
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Any CPU = Debug|Any CPU
+ Release|Any CPU = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {2AF5EBB5-9873-4B35-A8FC-8B6E74242767}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {2AF5EBB5-9873-4B35-A8FC-8B6E74242767}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {2AF5EBB5-9873-4B35-A8FC-8B6E74242767}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {2AF5EBB5-9873-4B35-A8FC-8B6E74242767}.Release|Any CPU.Build.0 = Release|Any CPU
+ {EB943C69-2C9B-45E7-B95B-FB916E7057ED}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {EB943C69-2C9B-45E7-B95B-FB916E7057ED}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {EB943C69-2C9B-45E7-B95B-FB916E7057ED}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {EB943C69-2C9B-45E7-B95B-FB916E7057ED}.Release|Any CPU.Build.0 = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+EndGlobal
diff --git a/xmsprovider-test.config b/xmsprovider-test.config
new file mode 100644
index 0000000..496545f
--- /dev/null
+++ b/xmsprovider-test.config
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<!--
+* 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.
+-->
+<configuration>
+ <testURI value="xms:wmq://localhost:1414">
+ <userName value="guest"/>
+ <passWord value="guest"/>
+ <defaultTestQueue value="queue://TEST.QUEUE"/>
+ <defaultTestTopic value="topic://TEST.TOPIC"/>
+ <durableConsumerTestTopic value="topic://TEST.DURABLE.CONSUMER.TOPIC"/>
+ <messageSelectorTestQueue value="queue://TEST.SELECTOR.MESSAGE.QUEUE"/>
+ <messageSelectorTestTopic value="topic://TEST.SELECTOR.MESSAGE.TOPIC"/>
+ <deletionTestQueue value="queue://TEST.DELETION.QUEUE"/>
+ <deletionTestTopic value="topic://TEST.DELETION.TOPIC"/>
+ <deletionTestTempQueue value="temp-queue://TEST.DELETION.TEMP.QUEUE"/>
+ <deletionTestTempTopic value="temp-topic://TEST.DELETION.TEMP.TOPIC"/>
+ <transactionTestQueue value="queue://TEST.TRANSACTION.QUEUE"/>
+ </testURI>
+</configuration>